2 Unix SMB/Netbios implementation.
4 SMB transaction2 handling
5 Copyright (C) Jeremy Allison 1994-2001
7 Extensively modified by Andrew Tridgell, 1995
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
27 extern BOOL case_sensitive;
28 extern int smb_read_error;
29 extern fstring local_machine;
30 extern int global_oplock_break;
31 extern uint32 global_client_caps;
32 extern pstring global_myname;
34 /****************************************************************************
35 Send the required number of replies back.
36 We assume all fields other than the data fields are
37 set correctly for the type of call.
38 HACK ! Always assumes smb_setup field is zero.
39 ****************************************************************************/
41 static int send_trans2_replies(char *outbuf, int bufsize, char *params,
42 int paramsize, char *pdata, int datasize)
44 /* As we are using a protocol > LANMAN1 then the max_send
45 variable must have been set in the sessetupX call.
46 This takes precedence over the max_xmit field in the
47 global struct. These different max_xmit variables should
48 be merged as this is now too confusing */
51 int data_to_send = datasize;
52 int params_to_send = paramsize;
56 int params_sent_thistime, data_sent_thistime, total_sent_thistime;
57 int alignment_offset = 1; /* JRA. This used to be 3. Set to 1 to make netmon parse ok. */
58 int data_alignment_offset = 0;
60 /* Initially set the wcnt area to be 10 - this is true for all
62 set_message(outbuf,10,0,True);
64 /* If there genuinely are no parameters or data to send just send
66 if(params_to_send == 0 && data_to_send == 0)
68 if (!send_smb(smbd_server_fd(),outbuf))
69 exit_server("send_trans2_replies: send_smb failed.");
73 /* When sending params and data ensure that both are nicely aligned */
74 /* Only do this alignment when there is also data to send - else
75 can cause NT redirector problems. */
76 if (((params_to_send % 4) != 0) && (data_to_send != 0))
77 data_alignment_offset = 4 - (params_to_send % 4);
79 /* Space is bufsize minus Netbios over TCP header minus SMB header */
80 /* The alignment_offset is to align the param bytes on an even byte
81 boundary. NT 4.0 Beta needs this to work correctly. */
82 useable_space = bufsize - ((smb_buf(outbuf)+
83 alignment_offset+data_alignment_offset) -
86 /* useable_space can never be more than max_send minus the
88 useable_space = MIN(useable_space,
89 max_send - (alignment_offset+data_alignment_offset));
92 while (params_to_send || data_to_send)
94 /* Calculate whether we will totally or partially fill this packet */
95 total_sent_thistime = params_to_send + data_to_send +
96 alignment_offset + data_alignment_offset;
97 /* We can never send more than useable_space */
99 * Note that 'useable_space' does not include the alignment offsets,
100 * but we must include the alignment offsets in the calculation of
101 * the length of the data we send over the wire, as the alignment offsets
102 * are sent here. Fix from Marc_Jacobsen@hp.com.
104 total_sent_thistime = MIN(total_sent_thistime, useable_space+
105 alignment_offset + data_alignment_offset);
107 set_message(outbuf, 10, total_sent_thistime, True);
109 /* Set total params and data to be sent */
110 SSVAL(outbuf,smb_tprcnt,paramsize);
111 SSVAL(outbuf,smb_tdrcnt,datasize);
113 /* Calculate how many parameters and data we can fit into
114 this packet. Parameters get precedence */
116 params_sent_thistime = MIN(params_to_send,useable_space);
117 data_sent_thistime = useable_space - params_sent_thistime;
118 data_sent_thistime = MIN(data_sent_thistime,data_to_send);
120 SSVAL(outbuf,smb_prcnt, params_sent_thistime);
122 /* smb_proff is the offset from the start of the SMB header to the
123 parameter bytes, however the first 4 bytes of outbuf are
124 the Netbios over TCP header. Thus use smb_base() to subtract
125 them from the calculation */
127 SSVAL(outbuf,smb_proff,((smb_buf(outbuf)+alignment_offset) - smb_base(outbuf)));
129 if(params_sent_thistime == 0)
130 SSVAL(outbuf,smb_prdisp,0);
132 /* Absolute displacement of param bytes sent in this packet */
133 SSVAL(outbuf,smb_prdisp,pp - params);
135 SSVAL(outbuf,smb_drcnt, data_sent_thistime);
136 if(data_sent_thistime == 0)
138 SSVAL(outbuf,smb_droff,0);
139 SSVAL(outbuf,smb_drdisp, 0);
143 /* The offset of the data bytes is the offset of the
144 parameter bytes plus the number of parameters being sent this time */
145 SSVAL(outbuf,smb_droff,((smb_buf(outbuf)+alignment_offset) -
146 smb_base(outbuf)) + params_sent_thistime + data_alignment_offset);
147 SSVAL(outbuf,smb_drdisp, pd - pdata);
150 /* Copy the param bytes into the packet */
151 if(params_sent_thistime)
152 memcpy((smb_buf(outbuf)+alignment_offset),pp,params_sent_thistime);
153 /* Copy in the data bytes */
154 if(data_sent_thistime)
155 memcpy(smb_buf(outbuf)+alignment_offset+params_sent_thistime+
156 data_alignment_offset,pd,data_sent_thistime);
158 DEBUG(9,("t2_rep: params_sent_thistime = %d, data_sent_thistime = %d, useable_space = %d\n",
159 params_sent_thistime, data_sent_thistime, useable_space));
160 DEBUG(9,("t2_rep: params_to_send = %d, data_to_send = %d, paramsize = %d, datasize = %d\n",
161 params_to_send, data_to_send, paramsize, datasize));
163 /* Send the packet */
164 if (!send_smb(smbd_server_fd(),outbuf))
165 exit_server("send_trans2_replies: send_smb failed.");
167 pp += params_sent_thistime;
168 pd += data_sent_thistime;
170 params_to_send -= params_sent_thistime;
171 data_to_send -= data_sent_thistime;
174 if(params_to_send < 0 || data_to_send < 0)
176 DEBUG(0,("send_trans2_replies failed sanity check pts = %d, dts = %d\n!!!",
177 params_to_send, data_to_send));
185 /****************************************************************************
186 Reply to a TRANSACT2_OPEN.
187 ****************************************************************************/
189 static int call_trans2open(connection_struct *conn, char *inbuf, char *outbuf,
191 char **pparams, char **ppdata)
193 char *params = *pparams;
194 int16 open_mode = SVAL(params, 2);
195 int16 open_attr = SVAL(params,6);
196 BOOL oplock_request = (((SVAL(params,0)|(1<<1))>>1) | ((SVAL(params,0)|(1<<2))>>1));
198 BOOL return_additional_info = BITSETW(params,0);
199 int16 open_sattr = SVAL(params, 4);
200 time_t open_time = make_unix_date3(params+8);
202 int16 open_ofun = SVAL(params,12);
203 int32 open_size = IVAL(params,14);
204 char *pname = ¶ms[28];
208 int fmode=0,mtime=0,rmode;
210 SMB_STRUCT_STAT sbuf;
212 BOOL bad_path = False;
215 srvstr_pull(inbuf, fname, pname, sizeof(fname), -1, STR_TERMINATE);
217 DEBUG(3,("trans2open %s mode=%d attr=%d ofun=%d size=%d\n",
218 fname,open_mode, open_attr, open_ofun, open_size));
221 return(ERROR_DOS(ERRSRV,ERRaccess));
224 /* XXXX we need to handle passed times, sattr and flags */
226 unix_convert(fname,conn,0,&bad_path,&sbuf);
228 if (!check_name(fname,conn))
230 if((errno == ENOENT) && bad_path)
232 unix_ERR_class = ERRDOS;
233 unix_ERR_code = ERRbadpath;
235 return(UNIXERROR(ERRDOS,ERRnoaccess));
238 unixmode = unix_mode(conn,open_attr | aARCH, fname);
240 fsp = open_file_shared(conn,fname,&sbuf,open_mode,open_ofun,unixmode,
241 oplock_request, &rmode,&smb_action);
245 if((errno == ENOENT) && bad_path)
247 unix_ERR_class = ERRDOS;
248 unix_ERR_code = ERRbadpath;
250 return(UNIXERROR(ERRDOS,ERRnoaccess));
254 fmode = dos_mode(conn,fname,&sbuf);
255 mtime = sbuf.st_mtime;
258 close_file(fsp,False);
259 return(ERROR_DOS(ERRDOS,ERRnoaccess));
262 /* Realloc the size of parameters and data we will return */
263 params = Realloc(*pparams, 28);
264 if( params == NULL ) {
265 return(ERROR_DOS(ERRDOS,ERRnomem));
269 memset((char *)params,'\0',28);
270 SSVAL(params,0,fsp->fnum);
271 SSVAL(params,2,fmode);
272 put_dos_date2(params,4, mtime);
273 SIVAL(params,8, (uint32)size);
274 SSVAL(params,12,rmode);
276 if (oplock_request && lp_fake_oplocks(SNUM(conn))) {
277 smb_action |= EXTENDED_OPLOCK_GRANTED;
280 SSVAL(params,18,smb_action);
282 * WARNING - this may need to be changed if SMB_INO_T <> 4 bytes.
284 SIVAL(params,20,inode);
286 /* Send the required number of replies */
287 send_trans2_replies(outbuf, bufsize, params, 28, *ppdata, 0);
292 /*********************************************************
293 Routine to check if a given string matches exactly.
294 as a special case a mask of "." does NOT match. That
295 is required for correct wildcard semantics
296 Case can be significant or not.
297 **********************************************************/
299 static BOOL exact_match(char *str,char *mask, BOOL case_sig)
301 if (mask[0] == '.' && mask[1] == 0)
304 return strcmp(str,mask)==0;
305 return strcasecmp(str,mask) == 0;
310 Not finished yet - jra.
312 /****************************************************************************
313 Return the filetype for UNIX extensions.
314 ****************************************************************************/
316 static uint32 unix_filetype(mode_t mode)
319 return UNIX_TYPE_FILE;
320 else if(S_ISDIR(mode))
321 return UNIX_TYPE_DIR;
323 else if(S_ISLNK(mode))
324 return UNIX_TYPE_SYMLINK;
327 else if(S_ISCHR(mode))
328 return UNIX_TYPE_CHARDEV;
331 else if(S_ISBLK(mode))
332 return UNIX_TYPE_BLKDEV;
335 else if(S_ISFIFO(mode))
336 return UNIX_TYPE_FIFO;
339 else if(S_ISSOCK(mode))
340 return UNIX_TYPE_SOCKET;
343 DEBUG(0,("unix_filetype: unknown filetype %u", (unsigned)mode));
344 return UNIX_TYPE_UNKNOWN;
347 /****************************************************************************
348 Return the major devicenumber for UNIX extensions.
349 ****************************************************************************/
351 static uint32 unix_dev_major(SMB_DEV_T dev)
353 #if defined(HAVE_DEVICE_MAJOR_FN)
354 return (uint32)major(dev);
356 return (uint32)(dev >> 8);
360 /****************************************************************************
361 Return the minor devicenumber for UNIX extensions.
362 ****************************************************************************/
364 static uint32 unix_dev_minor(SMB_DEV_T dev)
366 #if defined(HAVE_DEVICE_MINOR_FN)
367 return (uint32)minor(dev);
369 return (uint32)(dev & 0xff);
373 /****************************************************************************
374 Map standard UNIX permissions onto wire representations.
375 ****************************************************************************/
377 static uint32 unix_perms_to_wire(mode_t perms)
381 ret |= ((perms & S_IXOTH) ? UNIX_X_OTH : 0);
382 ret |= ((perms & S_IWOTH) ? UNIX_W_OTH : 0);
383 ret |= ((perms & S_IROTH) ? UNIX_R_OTH : 0);
384 ret |= ((perms & S_IXGRP) ? UNIX_X_GRP : 0);
385 ret |= ((perms & S_IWGRP) ? UNIX_W_GRP : 0);
386 ret |= ((perms & S_IRGRP) ? UNIX_R_GRP : 0);
387 ret |= ((perms & S_IXUSR) ? UNIX_X_USR : 0);
388 ret |= ((perms & S_IWUSR) ? UNIX_W_USR : 0);
389 ret |= ((perms & S_IRUSR) ? UNIX_R_USR : 0);
391 ret |= ((perms & S_ISVTX) ? UNIX_STICKY : 0);
394 ret |= ((perms & S_ISGID) ? UNIX_SET_GID : 0);
397 ret |= ((perms & S_ISVTX) ? UNIX_SET_UID : 0);
404 /****************************************************************************
405 Get a level dependent lanman2 dir entry.
406 ****************************************************************************/
408 static BOOL get_lanman2_dir_entry(connection_struct *conn,
409 void *inbuf, void *outbuf,
410 char *path_mask,int dirtype,int info_level,
411 int requires_resume_key,
412 BOOL dont_descend,char **ppdata,
413 char *base_data, int space_remaining,
414 BOOL *out_of_space, BOOL *got_exact_match,
419 SMB_STRUCT_STAT sbuf;
423 char *p, *q, *pdata = *ppdata;
428 SMB_OFF_T allocation_size = 0;
430 time_t mdate=0, adate=0, cdate=0;
433 int nt_extmode; /* Used for NT connections instead of mode */
434 BOOL needslash = ( conn->dirpath[strlen(conn->dirpath) -1] != '/');
437 *out_of_space = False;
438 *got_exact_match = False;
443 p = strrchr_m(path_mask,'/');
450 pstrcpy(mask, path_mask);
455 /* Needed if we run out of space */
456 prev_dirpos = TellDir(conn->dirptr);
457 dname = ReadDirName(conn->dirptr);
460 * Due to bugs in NT client redirectors we are not using
461 * resume keys any more - set them to zero.
462 * Check out the related comments in findfirst/findnext.
468 DEBUG(8,("get_lanman2_dir_entry:readdir on dirptr 0x%lx now at offset %d\n",
469 (long)conn->dirptr,TellDir(conn->dirptr)));
474 pstrcpy(fname,dname);
476 if(!(got_match = *got_exact_match = exact_match(fname, mask, case_sensitive)))
477 got_match = mask_match(fname, mask, case_sensitive);
479 if(!got_match && !is_8_3(fname, False)) {
482 * It turns out that NT matches wildcards against
483 * both long *and* short names. This may explain some
484 * of the wildcard wierdness from old DOS clients
485 * that some people have been seeing.... JRA.
489 pstrcpy( newname, fname);
490 name_map_mangle( newname, True, False, SNUM(conn));
491 if(!(got_match = *got_exact_match = exact_match(newname, mask, case_sensitive)))
492 got_match = mask_match(newname, mask, case_sensitive);
496 BOOL isdots = (strequal(fname,"..") || strequal(fname,"."));
497 if (dont_descend && !isdots)
500 pstrcpy(pathreal,conn->dirpath);
502 pstrcat(pathreal,"/");
503 pstrcat(pathreal,dname);
505 if (INFO_LEVEL_IS_UNIX(info_level)) {
506 if (vfs_lstat(conn,pathreal,&sbuf) != 0) {
507 DEBUG(5,("get_lanman2_dir_entry:Couldn't lstat [%s] (%s)\n",
508 pathreal,strerror(errno)));
511 } else if (vfs_stat(conn,pathreal,&sbuf) != 0) {
512 /* Needed to show the msdfs symlinks as directories */
513 if(!lp_host_msdfs() || !lp_msdfs_root(SNUM(conn))
514 || !is_msdfs_link(conn, pathreal)) {
515 DEBUG(5,("get_lanman2_dir_entry:Couldn't stat [%s] (%s)\n",
516 pathreal,strerror(errno)));
519 DEBUG(5,("get_lanman2_dir_entry: Masquerading msdfs link %s as a directory\n",
521 sbuf.st_mode = (sbuf.st_mode & 0xFFF) | S_IFDIR;
525 mode = dos_mode(conn,pathreal,&sbuf);
527 if (!dir_check_ftype(conn,mode,&sbuf,dirtype)) {
528 DEBUG(5,("[%s] attribs didn't match %x\n",fname,dirtype));
533 allocation_size = SMB_ROUNDUP_ALLOCATION(sbuf.st_size);
534 mdate = sbuf.st_mtime;
535 adate = sbuf.st_atime;
536 cdate = get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(conn)));
538 if (lp_dos_filetime_resolution(SNUM(conn))) {
547 DEBUG(5,("get_lanman2_dir_entry found %s fname=%s\n",pathreal,fname));
553 name_map_mangle(fname,False,True,SNUM(conn));
558 nt_extmode = mode ? mode : FILE_ATTRIBUTE_NORMAL;
560 switch (info_level) {
562 if(requires_resume_key) {
566 put_dos_date2(p,l1_fdateCreation,cdate);
567 put_dos_date2(p,l1_fdateLastAccess,adate);
568 put_dos_date2(p,l1_fdateLastWrite,mdate);
569 SIVAL(p,l1_cbFile,(uint32)size);
570 SIVAL(p,l1_cbFileAlloc,(uint32)allocation_size);
571 SSVAL(p,l1_attrFile,mode);
574 p += align_string(outbuf, p, 0);
575 len = srvstr_push(outbuf, p, fname, -1, STR_TERMINATE);
576 SCVAL(nameptr, -1, len);
581 if(requires_resume_key) {
585 put_dos_date2(p,l2_fdateCreation,cdate);
586 put_dos_date2(p,l2_fdateLastAccess,adate);
587 put_dos_date2(p,l2_fdateLastWrite,mdate);
588 SIVAL(p,l2_cbFile,(uint32)size);
589 SIVAL(p,l2_cbFileAlloc,(uint32)allocation_size);
590 SSVAL(p,l2_attrFile,mode);
591 SIVAL(p,l2_cbList,0); /* No extended attributes */
594 len = srvstr_push(outbuf, p, fname, -1, STR_NOALIGN);
597 *p++ = 0; /* craig from unisys pointed out we need this */
600 case SMB_FIND_FILE_BOTH_DIRECTORY_INFO:
601 was_8_3 = is_8_3(fname, True);
603 SIVAL(p,0,reskey); p += 4;
604 put_long_date(p,cdate); p += 8;
605 put_long_date(p,adate); p += 8;
606 put_long_date(p,mdate); p += 8;
607 put_long_date(p,mdate); p += 8;
609 SOFF_T(p,8,allocation_size);
611 SIVAL(p,0,nt_extmode); p += 4;
613 SIVAL(p,0,0); p += 4;
615 pstring mangled_name;
616 pstrcpy(mangled_name, fname);
617 name_map_mangle(mangled_name,True,True,SNUM(conn));
618 mangled_name[12] = 0;
619 len = srvstr_push(outbuf, p+2, mangled_name, 24, STR_UPPER);
626 len = srvstr_push(outbuf, p, fname, -1, STR_TERMINATE);
629 len = PTR_DIFF(p, pdata);
630 len = (len + 3) & ~3;
635 case SMB_FIND_FILE_DIRECTORY_INFO:
637 SIVAL(p,0,reskey); p += 4;
638 put_long_date(p,cdate); p += 8;
639 put_long_date(p,adate); p += 8;
640 put_long_date(p,mdate); p += 8;
641 put_long_date(p,mdate); p += 8;
643 SOFF_T(p,8,allocation_size);
645 SIVAL(p,0,nt_extmode); p += 4;
647 len = srvstr_push(outbuf, p, fname, -1, STR_TERMINATE);
650 len = PTR_DIFF(p, pdata);
651 len = (len + 3) & ~3;
656 case SMB_FIND_FILE_FULL_DIRECTORY_INFO:
658 SIVAL(p,0,reskey); p += 4;
659 put_long_date(p,cdate); p += 8;
660 put_long_date(p,adate); p += 8;
661 put_long_date(p,mdate); p += 8;
662 put_long_date(p,mdate); p += 8;
664 SOFF_T(p,8,allocation_size);
666 SIVAL(p,0,nt_extmode); p += 4;
668 SIVAL(p,0,0); p += 4;
670 len = srvstr_push(outbuf, p, fname, -1, STR_TERMINATE);
674 len = PTR_DIFF(p, pdata);
675 len = (len + 3) & ~3;
680 case SMB_FIND_FILE_NAMES_INFO:
682 SIVAL(p,0,reskey); p += 4;
684 len = srvstr_push(outbuf, p, fname, -1, STR_TERMINATE);
687 len = PTR_DIFF(p, pdata);
688 len = (len + 3) & ~3;
693 /* CIFS UNIX Extension. */
695 #if 0 /* JRA - FIXME - NEEDS UNICODE CONVERSION !!! */
696 case SMB_FIND_FILE_UNIX:
698 len = 108+strlen(fname)+1; /* (length of SMB_QUERY_FILE_UNIX_BASIC = 100)+4+4+strlen(fname)*/
699 /* +1 to be sure to transmit the termination of fname */
700 len = (len + 3) & ~3;
702 SIVAL(p,0,len); p+= 4; /* Offset from this structure to the beginning of the next one */
703 SIVAL(p,0,reskey); p+= 4; /* Used for continuing search. */
705 /* Begin of SMB_QUERY_FILE_UNIX_BASIC */
706 SOFF_T(p,0,sbuf.st_size); /* File size 64 Bit */
709 #if defined(HAVE_STAT_ST_BLOCKS) && defined(STAT_ST_BLOCKSIZE)
710 SOFF_T(p,0,sbuf.st_blocks*STAT_ST_BLOCKSIZE); /* Number of bytes used on disk - 64 Bit */
712 /* Can't get the value - fake it using size. */
713 SOFF_T(p,0,sbuf.st_size); /* Number of bytes used on disk - 64 Bit */
717 put_long_date(p,sbuf.st_ctime); /* Creation Time 64 Bit */
718 put_long_date(p+8,sbuf.st_atime); /* Last access time 64 Bit */
719 put_long_date(p+16,sbuf.st_mtime); /* Last modification time 64 Bit */
722 SIVAL(p,0,sbuf.st_uid); /* user id for the owner */
726 SIVAL(p,0,sbuf.st_gid); /* group id of owner */
730 SIVAL(p,0,unix_filetype(sbuf.st_mode));
733 SIVAL(p,0,unix_dev_major(sbuf.st_rdev)); /* Major device number if type is device */
737 SIVAL(p,0,unix_dev_minor(sbuf.st_rdev)); /* Minor device number if type is device */
741 SINO_T(p,0,(SMB_INO_T)sbuf.st_ino); /* inode number */
744 SIVAL(p,0, unix_perms_to_wire(sbuf.st_mode)); /* Standard UNIX file permissions */
748 SIVAL(p,0,sbuf.st_nlink); /* number of hard links */
752 /* End of SMB_QUERY_FILE_UNIX_BASIC */
764 if (PTR_DIFF(p,pdata) > space_remaining) {
765 /* Move the dirptr back to prev_dirpos */
766 SeekDir(conn->dirptr, prev_dirpos);
767 *out_of_space = True;
768 DEBUG(9,("get_lanman2_dir_entry: out of space\n"));
769 return False; /* Not finished - just out of space */
772 /* Setup the last_filename pointer, as an offset from base_data */
773 *last_name_off = PTR_DIFF(nameptr,base_data);
774 /* Advance the data pointer to the next slot */
780 /****************************************************************************
781 Reply to a TRANS2_FINDFIRST.
782 ****************************************************************************/
784 static int call_trans2findfirst(connection_struct *conn,
785 char *inbuf, char *outbuf, int bufsize,
786 char **pparams, char **ppdata)
788 /* We must be careful here that we don't return more than the
789 allowed number of data bytes. If this means returning fewer than
790 maxentries then so be it. We assume that the redirector has
791 enough room for the fixed number of parameter bytes it has
793 uint32 max_data_bytes = SVAL(inbuf, smb_mdrcnt);
794 char *params = *pparams;
795 char *pdata = *ppdata;
796 int dirtype = SVAL(params,0);
797 int maxentries = SVAL(params,2);
798 BOOL close_after_first = BITSETW(params+4,0);
799 BOOL close_if_end = BITSETW(params+4,1);
800 BOOL requires_resume_key = BITSETW(params+4,2);
801 int info_level = SVAL(params,6);
809 BOOL finished = False;
810 BOOL dont_descend = False;
811 BOOL out_of_space = False;
813 BOOL bad_path = False;
814 SMB_STRUCT_STAT sbuf;
816 *directory = *mask = 0;
818 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",
819 dirtype, maxentries, close_after_first, close_if_end, requires_resume_key,
820 info_level, max_data_bytes));
828 case SMB_FIND_FILE_DIRECTORY_INFO:
829 case SMB_FIND_FILE_FULL_DIRECTORY_INFO:
830 case SMB_FIND_FILE_NAMES_INFO:
831 case SMB_FIND_FILE_BOTH_DIRECTORY_INFO:
834 return(ERROR_DOS(ERRDOS,ERRunknownlevel));
837 srvstr_pull(inbuf, directory, params+12, sizeof(directory), -1, STR_TERMINATE);
839 RESOLVE_FINDFIRST_DFSPATH(directory, conn, inbuf, outbuf);
841 unix_convert(directory,conn,0,&bad_path,&sbuf);
842 if(!check_name(directory,conn)) {
843 if((errno == ENOENT) && bad_path)
845 unix_ERR_class = ERRDOS;
846 unix_ERR_code = ERRbadpath;
850 /* Ugly - NT specific hack - maybe not needed ? (JRA) */
851 if((errno == ENOTDIR) && (Protocol >= PROTOCOL_NT1) &&
852 (get_remote_arch() == RA_WINNT))
854 unix_ERR_class = ERRDOS;
855 unix_ERR_code = ERRbaddirectory;
859 return(UNIXERROR(ERRDOS,ERRbadpath));
862 p = strrchr_m(directory,'/');
864 pstrcpy(mask,directory);
865 pstrcpy(directory,"./");
871 DEBUG(5,("dir=%s, mask = %s\n",directory, mask));
873 pdata = Realloc(*ppdata, max_data_bytes + 1024);
874 if( pdata == NULL ) {
875 return(ERROR_DOS(ERRDOS,ERRnomem));
878 memset((char *)pdata,'\0',max_data_bytes + 1024);
880 /* Realloc the params space */
881 params = Realloc(*pparams, 10);
882 if (params == NULL) {
883 return ERROR_DOS(ERRDOS,ERRnomem);
887 dptr_num = dptr_create(conn,directory, False, True ,SVAL(inbuf,smb_pid));
889 return(UNIXERROR(ERRDOS,ERRbadfile));
891 /* Save the wildcard match and attribs we are using on this directory -
892 needed as lanman2 assumes these are being saved between calls */
894 if(!(wcard = strdup(mask))) {
895 dptr_close(&dptr_num);
896 return ERROR_DOS(ERRDOS,ERRnomem);
899 dptr_set_wcard(dptr_num, wcard);
900 dptr_set_attr(dptr_num, dirtype);
902 DEBUG(4,("dptr_num is %d, wcard = %s, attr = %d\n",dptr_num, wcard, dirtype));
904 /* We don't need to check for VOL here as this is returned by
905 a different TRANS2 call. */
907 DEBUG(8,("dirpath=<%s> dontdescend=<%s>\n",
908 conn->dirpath,lp_dontdescend(SNUM(conn))));
909 if (in_list(conn->dirpath,lp_dontdescend(SNUM(conn)),case_sensitive))
913 space_remaining = max_data_bytes;
914 out_of_space = False;
916 for (i=0;(i<maxentries) && !finished && !out_of_space;i++)
918 BOOL got_exact_match = False;
920 /* this is a heuristic to avoid seeking the dirptr except when
921 absolutely necessary. It allows for a filename of about 40 chars */
922 if (space_remaining < DIRLEN_GUESS && numentries > 0)
929 finished = !get_lanman2_dir_entry(conn,
931 mask,dirtype,info_level,
932 requires_resume_key,dont_descend,
933 &p,pdata,space_remaining, &out_of_space, &got_exact_match,
937 if (finished && out_of_space)
940 if (!finished && !out_of_space)
944 * As an optimisation if we know we aren't looking
945 * for a wildcard name (ie. the name matches the wildcard exactly)
946 * then we can finish on any (first) match.
947 * This speeds up large directory searches. JRA.
953 space_remaining = max_data_bytes - PTR_DIFF(p,pdata);
956 /* Check if we can close the dirptr */
957 if(close_after_first || (finished && close_if_end))
959 DEBUG(5,("call_trans2findfirst - (2) closing dptr_num %d\n", dptr_num));
960 dptr_close(&dptr_num);
964 * If there are no matching entries we must return ERRDOS/ERRbadfile -
965 * from observation of NT.
968 if(numentries == 0) {
969 dptr_close(&dptr_num);
970 return ERROR_DOS(ERRDOS,ERRbadfile);
973 /* At this point pdata points to numentries directory entries. */
975 /* Set up the return parameter block */
976 SSVAL(params,0,dptr_num);
977 SSVAL(params,2,numentries);
978 SSVAL(params,4,finished);
979 SSVAL(params,6,0); /* Never an EA error */
980 SSVAL(params,8,last_name_off);
982 send_trans2_replies( outbuf, bufsize, params, 10, pdata, PTR_DIFF(p,pdata));
984 if ((! *directory) && dptr_path(dptr_num))
985 slprintf(directory,sizeof(directory)-1, "(%s)",dptr_path(dptr_num));
987 DEBUG( 4, ( "%s mask=%s directory=%s dirtype=%d numentries=%d\n",
988 smb_fn_name(CVAL(inbuf,smb_com)),
989 mask, directory, dirtype, numentries ) );
992 * Force a name mangle here to ensure that the
993 * mask as an 8.3 name is top of the mangled cache.
994 * The reasons for this are subtle. Don't remove
995 * this code unless you know what you are doing
996 * (see PR#13758). JRA.
999 if(!is_8_3( mask, False))
1000 name_map_mangle(mask, True, True, SNUM(conn));
1005 /****************************************************************************
1006 Reply to a TRANS2_FINDNEXT.
1007 ****************************************************************************/
1009 static int call_trans2findnext(connection_struct *conn,
1010 char *inbuf, char *outbuf,
1011 int length, int bufsize,
1012 char **pparams, char **ppdata)
1014 /* We must be careful here that we don't return more than the
1015 allowed number of data bytes. If this means returning fewer than
1016 maxentries then so be it. We assume that the redirector has
1017 enough room for the fixed number of parameter bytes it has
1019 int max_data_bytes = SVAL(inbuf, smb_mdrcnt);
1020 char *params = *pparams;
1021 char *pdata = *ppdata;
1022 int dptr_num = SVAL(params,0);
1023 int maxentries = SVAL(params,2);
1024 uint16 info_level = SVAL(params,4);
1025 uint32 resume_key = IVAL(params,6);
1026 BOOL close_after_request = BITSETW(params+10,0);
1027 BOOL close_if_end = BITSETW(params+10,1);
1028 BOOL requires_resume_key = BITSETW(params+10,2);
1029 BOOL continue_bit = BITSETW(params+10,3);
1030 pstring resume_name;
1036 int i, last_name_off=0;
1037 BOOL finished = False;
1038 BOOL dont_descend = False;
1039 BOOL out_of_space = False;
1040 int space_remaining;
1042 *mask = *directory = *resume_name = 0;
1044 srvstr_pull(inbuf, resume_name, params+12, sizeof(resume_name), -1, STR_TERMINATE);
1046 DEBUG(3,("call_trans2findnext: dirhandle = %d, max_data_bytes = %d, maxentries = %d, \
1047 close_after_request=%d, close_if_end = %d requires_resume_key = %d \
1048 resume_key = %d resume name = %s continue=%d level = %d\n",
1049 dptr_num, max_data_bytes, maxentries, close_after_request, close_if_end,
1050 requires_resume_key, resume_key, resume_name, continue_bit, info_level));
1058 case SMB_FIND_FILE_DIRECTORY_INFO:
1059 case SMB_FIND_FILE_FULL_DIRECTORY_INFO:
1060 case SMB_FIND_FILE_NAMES_INFO:
1061 case SMB_FIND_FILE_BOTH_DIRECTORY_INFO:
1064 return ERROR_DOS(ERRDOS,ERRunknownlevel);
1067 pdata = Realloc( *ppdata, max_data_bytes + 1024);
1069 return ERROR_DOS(ERRDOS,ERRnomem);
1072 memset((char *)pdata,'\0',max_data_bytes + 1024);
1074 /* Realloc the params space */
1075 params = Realloc(*pparams, 6*SIZEOFWORD);
1076 if( params == NULL ) {
1077 return ERROR_DOS(ERRDOS,ERRnomem);
1081 /* Check that the dptr is valid */
1082 if(!(conn->dirptr = dptr_fetch_lanman2(dptr_num)))
1083 return ERROR_DOS(ERRDOS,ERRnofiles);
1085 string_set(&conn->dirpath,dptr_path(dptr_num));
1087 /* Get the wildcard mask from the dptr */
1088 if((p = dptr_wcard(dptr_num))== NULL) {
1089 DEBUG(2,("dptr_num %d has no wildcard\n", dptr_num));
1090 return ERROR_DOS(ERRDOS,ERRnofiles);
1093 pstrcpy(directory,conn->dirpath);
1095 /* Get the attr mask from the dptr */
1096 dirtype = dptr_attr(dptr_num);
1098 DEBUG(3,("dptr_num is %d, mask = %s, attr = %x, dirptr=(0x%lX,%d)\n",
1099 dptr_num, mask, dirtype,
1101 TellDir(conn->dirptr)));
1103 /* We don't need to check for VOL here as this is returned by
1104 a different TRANS2 call. */
1106 DEBUG(8,("dirpath=<%s> dontdescend=<%s>\n",conn->dirpath,lp_dontdescend(SNUM(conn))));
1107 if (in_list(conn->dirpath,lp_dontdescend(SNUM(conn)),case_sensitive))
1108 dont_descend = True;
1111 space_remaining = max_data_bytes;
1112 out_of_space = False;
1115 * Seek to the correct position. We no longer use the resume key but
1116 * depend on the last file name instead.
1118 if(requires_resume_key && *resume_name && !continue_bit)
1121 * Fix for NT redirector problem triggered by resume key indexes
1122 * changing between directory scans. We now return a resume key of 0
1123 * and instead look for the filename to continue from (also given
1124 * to us by NT/95/smbfs/smbclient). If no other scans have been done between the
1125 * findfirst/findnext (as is usual) then the directory pointer
1126 * should already be at the correct place. Check this by scanning
1127 * backwards looking for an exact (ie. case sensitive) filename match.
1128 * If we get to the beginning of the directory and haven't found it then scan
1129 * forwards again looking for a match. JRA.
1132 int current_pos, start_pos;
1134 void *dirptr = conn->dirptr;
1135 start_pos = TellDir(dirptr);
1136 for(current_pos = start_pos; current_pos >= 0; current_pos--)
1138 DEBUG(7,("call_trans2findnext: seeking to pos %d\n", current_pos));
1140 SeekDir(dirptr, current_pos);
1141 dname = ReadDirName(dirptr);
1144 * Remember, name_map_mangle is called by
1145 * get_lanman2_dir_entry(), so the resume name
1146 * could be mangled. Ensure we do the same
1151 name_map_mangle( dname, False, True, SNUM(conn));
1153 if(dname && strcsequal( resume_name, dname))
1155 SeekDir(dirptr, current_pos+1);
1156 DEBUG(7,("call_trans2findnext: got match at pos %d\n", current_pos+1 ));
1162 * Scan forward from start if not found going backwards.
1167 DEBUG(7,("call_trans2findnext: notfound: seeking to pos %d\n", start_pos));
1168 SeekDir(dirptr, start_pos);
1169 for(current_pos = start_pos; (dname = ReadDirName(dirptr)) != NULL; SeekDir(dirptr,++current_pos))
1172 * Remember, name_map_mangle is called by
1173 * get_lanman2_dir_entry(), so the resume name
1174 * could be mangled. Ensure we do the same
1179 name_map_mangle( dname, False, True, SNUM(conn));
1181 if(dname && strcsequal( resume_name, dname))
1183 SeekDir(dirptr, current_pos+1);
1184 DEBUG(7,("call_trans2findnext: got match at pos %d\n", current_pos+1 ));
1188 } /* end if current_pos */
1189 } /* end if requires_resume_key && !continue_bit */
1191 for (i=0;(i<(int)maxentries) && !finished && !out_of_space ;i++)
1193 BOOL got_exact_match = False;
1195 /* this is a heuristic to avoid seeking the dirptr except when
1196 absolutely necessary. It allows for a filename of about 40 chars */
1197 if (space_remaining < DIRLEN_GUESS && numentries > 0)
1199 out_of_space = True;
1204 finished = !get_lanman2_dir_entry(conn,
1206 mask,dirtype,info_level,
1207 requires_resume_key,dont_descend,
1208 &p,pdata,space_remaining, &out_of_space, &got_exact_match,
1212 if (finished && out_of_space)
1215 if (!finished && !out_of_space)
1219 * As an optimisation if we know we aren't looking
1220 * for a wildcard name (ie. the name matches the wildcard exactly)
1221 * then we can finish on any (first) match.
1222 * This speeds up large directory searches. JRA.
1228 space_remaining = max_data_bytes - PTR_DIFF(p,pdata);
1231 /* Check if we can close the dirptr */
1232 if(close_after_request || (finished && close_if_end))
1234 DEBUG(5,("call_trans2findnext: closing dptr_num = %d\n", dptr_num));
1235 dptr_close(&dptr_num); /* This frees up the saved mask */
1239 /* Set up the return parameter block */
1240 SSVAL(params,0,numentries);
1241 SSVAL(params,2,finished);
1242 SSVAL(params,4,0); /* Never an EA error */
1243 SSVAL(params,6,last_name_off);
1245 send_trans2_replies( outbuf, bufsize, params, 8, pdata, PTR_DIFF(p,pdata));
1247 if ((! *directory) && dptr_path(dptr_num))
1248 slprintf(directory,sizeof(directory)-1, "(%s)",dptr_path(dptr_num));
1250 DEBUG( 3, ( "%s mask=%s directory=%s dirtype=%d numentries=%d\n",
1251 smb_fn_name(CVAL(inbuf,smb_com)),
1252 mask, directory, dirtype, numentries ) );
1257 /****************************************************************************
1258 Reply to a TRANS2_QFSINFO (query filesystem info).
1259 ****************************************************************************/
1261 static int call_trans2qfsinfo(connection_struct *conn,
1262 char *inbuf, char *outbuf,
1263 int length, int bufsize,
1264 char **pparams, char **ppdata)
1266 int max_data_bytes = SVAL(inbuf, smb_mdrcnt);
1267 char *pdata = *ppdata;
1268 char *params = *pparams;
1269 uint16 info_level = SVAL(params,0);
1272 char *vname = volume_label(SNUM(conn));
1273 int snum = SNUM(conn);
1274 char *fstype = lp_fstype(SNUM(conn));
1276 DEBUG(3,("call_trans2qfsinfo: level = %d\n", info_level));
1278 if(vfs_stat(conn,".",&st)!=0) {
1279 DEBUG(2,("call_trans2qfsinfo: stat of . failed (%s)\n", strerror(errno)));
1280 return ERROR_DOS(ERRSRV,ERRinvdevice);
1283 pdata = Realloc(*ppdata, max_data_bytes + 1024);
1284 if ( pdata == NULL ) {
1285 return ERROR_DOS(ERRDOS,ERRnomem);
1288 memset((char *)pdata,'\0',max_data_bytes + 1024);
1294 SMB_BIG_UINT dfree,dsize,bsize;
1296 conn->vfs_ops.disk_free(conn,".",False,&bsize,&dfree,&dsize);
1297 SIVAL(pdata,l1_idFileSystem,st.st_dev);
1298 SIVAL(pdata,l1_cSectorUnit,bsize/512);
1299 SIVAL(pdata,l1_cUnit,dsize);
1300 SIVAL(pdata,l1_cUnitAvail,dfree);
1301 SSVAL(pdata,l1_cbSector,512);
1302 DEBUG(5,("call_trans2qfsinfo : bsize=%u, id=%x, cSectorUnit=%u, cUnit=%u, cUnitAvail=%u, cbSector=%d\n",
1303 (unsigned int)bsize, (unsigned int)st.st_dev, ((unsigned int)bsize)/512, (unsigned int)dsize,
1304 (unsigned int)dfree, 512));
1308 /* Return volume name */
1310 * Add volume serial number - hash of a combination of
1311 * the called hostname and the service name.
1313 SIVAL(pdata,0,str_checksum(lp_servicename(snum)) ^ (str_checksum(local_machine)<<16) );
1314 len = srvstr_push(outbuf, pdata+l2_vol_szVolLabel, vname, -1,
1316 SCVAL(pdata,l2_vol_cch,len);
1317 data_len = l2_vol_szVolLabel + len;
1318 DEBUG(5,("call_trans2qfsinfo : time = %x, namelen = %d, name = %s\n",
1319 (unsigned)st.st_ctime, len, vname));
1322 case SMB_QUERY_FS_ATTRIBUTE_INFO:
1323 SIVAL(pdata,0,FILE_CASE_PRESERVED_NAMES|FILE_CASE_SENSITIVE_SEARCH|
1324 (lp_nt_acl_support(SNUM(conn)) ? FILE_PERSISTENT_ACLS : 0)); /* FS ATTRIBUTES */
1325 SIVAL(pdata,4,255); /* Max filename component length */
1326 /* NOTE! the fstype must *not* be null terminated or win98 won't recognise it
1327 and will think we can't do long filenames */
1328 len = srvstr_push(outbuf, pdata+12, fstype, -1, 0);
1330 data_len = 12 + len;
1333 case SMB_QUERY_FS_LABEL_INFO:
1334 len = srvstr_push(outbuf, pdata+4, vname, -1, STR_TERMINATE);
1338 case SMB_QUERY_FS_VOLUME_INFO:
1340 * Add volume serial number - hash of a combination of
1341 * the called hostname and the service name.
1343 SIVAL(pdata,8,str_checksum(lp_servicename(snum)) ^
1344 (str_checksum(local_machine)<<16));
1346 len = srvstr_push(outbuf, pdata+18, vname, -1, STR_TERMINATE);
1347 SIVAL(pdata,12,len);
1349 DEBUG(5,("call_trans2qfsinfo : SMB_QUERY_FS_VOLUME_INFO namelen = %d, vol=%s serv=%s\n",
1350 (int)strlen(vname),vname, lp_servicename(snum)));
1352 case SMB_QUERY_FS_SIZE_INFO:
1354 SMB_BIG_UINT dfree,dsize,bsize;
1356 conn->vfs_ops.disk_free(conn,".",False,&bsize,&dfree,&dsize);
1357 SBIG_UINT(pdata,0,dsize);
1358 SBIG_UINT(pdata,8,dfree);
1359 SIVAL(pdata,16,bsize/512);
1360 SIVAL(pdata,20,512);
1363 case SMB_QUERY_FS_DEVICE_INFO:
1365 SIVAL(pdata,0,0); /* dev type */
1366 SIVAL(pdata,4,0); /* characteristics */
1368 case SMB_MAC_QUERY_FS_INFO:
1370 * Thursby MAC extension... ONLY on NTFS filesystems
1371 * once we do streams then we don't need this
1373 if (strequal(lp_fstype(SNUM(conn)),"NTFS")) {
1375 SIVAL(pdata,84,0x100); /* Don't support mac... */
1380 return ERROR_DOS(ERRDOS,ERRunknownlevel);
1384 send_trans2_replies( outbuf, bufsize, params, 0, pdata, data_len);
1386 DEBUG( 4, ( "%s info_level = %d\n",
1387 smb_fn_name(CVAL(inbuf,smb_com)), info_level) );
1392 /****************************************************************************
1393 Reply to a TRANS2_SETFSINFO (set filesystem info).
1394 ****************************************************************************/
1396 static int call_trans2setfsinfo(connection_struct *conn,
1397 char *inbuf, char *outbuf, int length,
1399 char **pparams, char **ppdata)
1401 /* Just say yes we did it - there is nothing that
1402 can be set here so it doesn't matter. */
1404 DEBUG(3,("call_trans2setfsinfo\n"));
1406 if (!CAN_WRITE(conn))
1407 return ERROR_DOS(ERRSRV,ERRaccess);
1409 outsize = set_message(outbuf,10,0,True);
1414 /****************************************************************************
1415 Reply to a TRANS2_QFILEPATHINFO or TRANSACT2_QFILEINFO (query file info by
1416 file name or file id).
1417 ****************************************************************************/
1419 static int call_trans2qfilepathinfo(connection_struct *conn,
1420 char *inbuf, char *outbuf, int length,
1422 char **pparams,char **ppdata,
1425 int max_data_bytes = SVAL(inbuf, smb_mdrcnt);
1426 char *params = *pparams;
1427 char *pdata = *ppdata;
1428 uint16 tran_call = SVAL(inbuf, smb_setup0);
1432 SMB_OFF_T allocation_size=0;
1433 unsigned int data_size;
1434 SMB_STRUCT_STAT sbuf;
1439 BOOL bad_path = False;
1440 BOOL delete_pending = False;
1444 if (tran_call == TRANSACT2_QFILEINFO) {
1445 files_struct *fsp = file_fsp(params,0);
1446 info_level = SVAL(params,2);
1448 DEBUG(3,("call_trans2qfilepathinfo: TRANSACT2_QFILEINFO: level = %d\n", info_level));
1450 if(fsp && (fsp->is_directory || fsp->stat_open)) {
1452 * This is actually a QFILEINFO on a directory
1453 * handle (returned from an NT SMB). NT5.0 seems
1454 * to do this call. JRA.
1456 pstrcpy(fname, fsp->fsp_name);
1457 unix_convert(fname,conn,0,&bad_path,&sbuf);
1458 if (!check_name(fname,conn) ||
1459 (!VALID_STAT(sbuf) && vfs_stat(conn,fname,&sbuf))) {
1460 DEBUG(3,("fileinfo of %s failed (%s)\n",fname,strerror(errno)));
1461 if((errno == ENOENT) && bad_path) {
1462 unix_ERR_class = ERRDOS;
1463 unix_ERR_code = ERRbadpath;
1465 return(UNIXERROR(ERRDOS,ERRbadpath));
1468 delete_pending = fsp->directory_delete_on_close;
1471 * Original code - this is an open file.
1473 CHECK_FSP(fsp,conn);
1475 pstrcpy(fname, fsp->fsp_name);
1476 if (vfs_fstat(fsp,fsp->fd,&sbuf) != 0) {
1477 DEBUG(3,("fstat of fnum %d failed (%s)\n", fsp->fnum, strerror(errno)));
1478 return(UNIXERROR(ERRDOS,ERRbadfid));
1480 if((pos = fsp->conn->vfs_ops.lseek(fsp,fsp->fd,0,SEEK_CUR)) == -1)
1481 return(UNIXERROR(ERRDOS,ERRnoaccess));
1483 delete_pending = fsp->delete_on_close;
1487 info_level = SVAL(params,0);
1489 DEBUG(3,("call_trans2qfilepathinfo: TRANSACT2_QPATHINFO: level = %d\n", info_level));
1491 srvstr_pull(inbuf, fname, ¶ms[6], sizeof(fname), -1, STR_TERMINATE);
1493 RESOLVE_DFSPATH(fname, conn, inbuf, outbuf);
1495 unix_convert(fname,conn,0,&bad_path,&sbuf);
1496 if (!check_name(fname,conn) ||
1497 (!VALID_STAT(sbuf) && vfs_stat(conn,fname,&sbuf))) {
1498 DEBUG(3,("fileinfo of %s failed (%s)\n",fname,strerror(errno)));
1499 if((errno == ENOENT) && bad_path) {
1500 unix_ERR_class = ERRDOS;
1501 unix_ERR_code = ERRbadpath;
1503 return(UNIXERROR(ERRDOS,ERRbadpath));
1508 DEBUG(3,("call_trans2qfilepathinfo %s level=%d call=%d total_data=%d\n",
1509 fname,info_level,tran_call,total_data));
1511 p = strrchr_m(fname,'/');
1517 mode = dos_mode(conn,fname,&sbuf);
1518 size = sbuf.st_size;
1519 allocation_size = SMB_ROUNDUP_ALLOCATION(sbuf.st_size);
1524 params = Realloc(*pparams,2);
1526 return ERROR_DOS(ERRDOS,ERRnomem);
1528 memset((char *)params,'\0',2);
1529 data_size = max_data_bytes + 1024;
1530 pdata = Realloc(*ppdata, data_size);
1531 if ( pdata == NULL )
1532 return ERROR_DOS(ERRDOS,ERRnomem);
1535 if (total_data > 0 && IVAL(pdata,0) == total_data) {
1536 /* uggh, EAs for OS2 */
1537 DEBUG(4,("Rejecting EA request with total_data=%d\n",total_data));
1538 return ERROR_DOS(ERRDOS,ERReasnotsupported);
1541 memset((char *)pdata,'\0',data_size);
1543 c_time = get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(conn)));
1545 if (lp_dos_filetime_resolution(SNUM(conn))) {
1547 sbuf.st_atime &= ~1;
1548 sbuf.st_mtime &= ~1;
1549 sbuf.st_mtime &= ~1;
1552 switch (info_level) {
1553 case SMB_INFO_STANDARD:
1554 case SMB_INFO_QUERY_EA_SIZE:
1555 data_size = (info_level==1?22:26);
1556 put_dos_date2(pdata,l1_fdateCreation,c_time);
1557 put_dos_date2(pdata,l1_fdateLastAccess,sbuf.st_atime);
1558 put_dos_date2(pdata,l1_fdateLastWrite,sbuf.st_mtime); /* write time */
1559 SIVAL(pdata,l1_cbFile,(uint32)size);
1560 SIVAL(pdata,l1_cbFileAlloc,(uint32)allocation_size);
1561 SSVAL(pdata,l1_attrFile,mode);
1562 SIVAL(pdata,l1_attrFile+2,4); /* this is what OS2 does */
1565 case SMB_INFO_QUERY_EAS_FROM_LIST:
1567 put_dos_date2(pdata,0,c_time);
1568 put_dos_date2(pdata,4,sbuf.st_atime);
1569 put_dos_date2(pdata,8,sbuf.st_mtime);
1570 SIVAL(pdata,12,(uint32)size);
1571 SIVAL(pdata,16,(uint32)allocation_size);
1572 SIVAL(pdata,20,mode);
1575 case SMB_INFO_QUERY_ALL_EAS:
1577 SIVAL(pdata,0,data_size);
1581 return ERROR_DOS(ERRDOS,ERRbadfunc); /* os/2 needs this */
1583 case SMB_FILE_BASIC_INFORMATION:
1584 case SMB_QUERY_FILE_BASIC_INFO:
1586 if (info_level == SMB_QUERY_FILE_BASIC_INFO)
1587 data_size = 36; /* w95 returns 40 bytes not 36 - why ?. */
1592 put_long_date(pdata,c_time);
1593 put_long_date(pdata+8,sbuf.st_atime);
1594 put_long_date(pdata+16,sbuf.st_mtime); /* write time */
1595 put_long_date(pdata+24,sbuf.st_mtime); /* change time */
1596 SIVAL(pdata,32,mode);
1598 DEBUG(5,("SMB_QFBI - "));
1600 time_t create_time = c_time;
1601 DEBUG(5,("create: %s ", ctime(&create_time)));
1603 DEBUG(5,("access: %s ", ctime(&sbuf.st_atime)));
1604 DEBUG(5,("write: %s ", ctime(&sbuf.st_mtime)));
1605 DEBUG(5,("change: %s ", ctime(&sbuf.st_mtime)));
1606 DEBUG(5,("mode: %x\n", mode));
1610 case SMB_FILE_STANDARD_INFORMATION:
1611 case SMB_QUERY_FILE_STANDARD_INFO:
1613 /* Fake up allocation size. */
1614 SOFF_T(pdata,0,allocation_size);
1615 SOFF_T(pdata,8,size);
1616 SIVAL(pdata,16,sbuf.st_nlink);
1618 CVAL(pdata,21) = (mode&aDIR)?1:0;
1621 case SMB_FILE_EA_INFORMATION:
1622 case SMB_QUERY_FILE_EA_INFO:
1626 /* Get the 8.3 name - used if NT SMB was negotiated. */
1627 case SMB_QUERY_FILE_ALT_NAME_INFO:
1631 pstrcpy(short_name,base_name);
1632 /* Mangle if not already 8.3 */
1633 if(!is_8_3(short_name, True)) {
1634 if(!name_map_mangle(short_name,True,True,SNUM(conn)))
1637 len = srvstr_push(outbuf, pdata+4, short_name, -1, STR_TERMINATE|STR_UPPER);
1638 data_size = 4 + len;
1643 case SMB_QUERY_FILE_NAME_INFO:
1645 * The first part of this code is essential
1646 * to get security descriptors to work on mapped
1647 * drives. Don't ask how I discovered this unless
1648 * you like hearing about me suffering.... :-). JRA.
1650 if(strequal(".", fname)) {
1651 len = srvstr_push(outbuf, pdata+4, "\\", -1, STR_TERMINATE);
1653 len = srvstr_push(outbuf, pdata+4, fname, -1, STR_TERMINATE);
1655 data_size = 4 + len;
1659 case SMB_FILE_END_OF_FILE_INFORMATION:
1660 case SMB_QUERY_FILE_END_OF_FILEINFO:
1662 SOFF_T(pdata,0,size);
1665 case SMB_FILE_ALLOCATION_INFORMATION:
1666 case SMB_QUERY_FILE_ALLOCATION_INFO:
1668 SOFF_T(pdata,0,allocation_size);
1671 case SMB_QUERY_FILE_ALL_INFO:
1672 put_long_date(pdata,c_time);
1673 put_long_date(pdata+8,sbuf.st_atime);
1674 put_long_date(pdata+16,sbuf.st_mtime); /* write time */
1675 put_long_date(pdata+24,sbuf.st_mtime); /* change time */
1676 SIVAL(pdata,32,mode);
1678 SOFF_T(pdata,0,allocation_size);
1679 SOFF_T(pdata,8,size);
1680 SIVAL(pdata,16,sbuf.st_nlink);
1681 CVAL(pdata,20) = delete_pending;
1682 CVAL(pdata,21) = (mode&aDIR)?1:0;
1684 SINO_T(pdata,0,(SMB_INO_T)sbuf.st_ino);
1685 pdata += 8; /* index number */
1686 pdata += 4; /* EA info */
1688 SIVAL(pdata,0,0xA9);
1690 SIVAL(pdata,0,0xd01BF);
1692 SOFF_T(pdata,0,pos); /* current offset */
1694 SIVAL(pdata,0,mode); /* is this the right sort of mode info? */
1696 pdata += 4; /* alignment */
1697 len = srvstr_push(outbuf, pdata+4, fname, -1, STR_TERMINATE);
1700 data_size = PTR_DIFF(pdata,(*ppdata));
1703 case SMB_FILE_INTERNAL_INFORMATION:
1704 /* This should be an index number - looks like dev/ino to me :-) */
1705 SIVAL(pdata,0,sbuf.st_dev);
1706 SIVAL(pdata,4,sbuf.st_ino);
1710 case SMB_FILE_ACCESS_INFORMATION:
1711 SIVAL(pdata,0,0x12019F); /* ??? */
1715 case SMB_FILE_NAME_INFORMATION:
1716 /* Pathname with leading '\'. */
1721 pstrcpy(new_fname, "\\");
1722 pstrcat(new_fname, fname);
1723 byte_len = dos_PutUniCode(pdata+4,new_fname,max_data_bytes,False);
1724 SIVAL(pdata,0,byte_len);
1725 data_size = 4 + byte_len;
1729 case SMB_FILE_DISPOSITION_INFORMATION:
1731 CVAL(pdata,0) = delete_pending;
1734 case SMB_FILE_POSITION_INFORMATION:
1736 SOFF_T(pdata,0,pos);
1739 case SMB_FILE_MODE_INFORMATION:
1740 SIVAL(pdata,0,mode);
1744 case SMB_FILE_ALIGNMENT_INFORMATION:
1745 SIVAL(pdata,0,0); /* No alignment needed. */
1750 /* Not yet finished... JRA */
1756 put_long_date(pdata,c_time);
1757 put_long_date(pdata+8,sbuf.st_atime);
1758 put_long_date(pdata+16,sbuf.st_mtime); /* write time */
1759 put_long_date(pdata+24,sbuf.st_mtime); /* change time */
1760 SIVAL(pdata,32,mode);
1761 SIVAL(pdata,36,0); /* ??? */
1762 SIVAL(pdata,40,0x20); /* ??? */
1763 SIVAL(pdata,44,0); /* ??? */
1764 SOFF_T(pdata,48,size);
1765 SIVAL(pdata,56,0x1); /* ??? */
1766 SIVAL(pdata,60,0); /* ??? */
1767 SIVAL(pdata,64,0); /* ??? */
1768 SIVAL(pdata,68,length); /* Following string length in bytes. */
1769 dos_PutUniCode(pdata+72,,False);
1774 case SMB_FILE_ALTERNATE_NAME_INFORMATION:
1775 /* Last component of pathname. */
1777 size_t byte_len = dos_PutUniCode(pdata+4,fname,max_data_bytes,False);
1778 SIVAL(pdata,0,byte_len);
1779 data_size = 4 + byte_len;
1783 case SMB_FILE_STREAM_INFORMATION:
1787 size_t byte_len = dos_PutUniCode(pdata+24,"::$DATA", 0xE, False);
1788 SIVAL(pdata,0,0); /* ??? */
1789 SIVAL(pdata,4,byte_len); /* Byte length of unicode string ::$DATA */
1790 SOFF_T(pdata,8,size);
1791 SIVAL(pdata,16,allocation_size);
1792 SIVAL(pdata,20,0); /* ??? */
1793 data_size = 24 + byte_len;
1797 case SMB_FILE_COMPRESSION_INFORMATION:
1798 SOFF_T(pdata,0,size);
1799 SIVAL(pdata,8,0); /* ??? */
1800 SIVAL(pdata,12,0); /* ??? */
1804 case SMB_FILE_NETWORK_OPEN_INFORMATION:
1805 put_long_date(pdata,c_time);
1806 put_long_date(pdata+8,sbuf.st_atime);
1807 put_long_date(pdata+16,sbuf.st_mtime); /* write time */
1808 put_long_date(pdata+24,sbuf.st_mtime); /* change time */
1809 SIVAL(pdata,32,allocation_size);
1810 SOFF_T(pdata,40,size);
1811 SIVAL(pdata,48,mode);
1812 SIVAL(pdata,52,0); /* ??? */
1816 case SMB_FILE_ATTRIBUTE_TAG_INFORMATION:
1817 SIVAL(pdata,0,mode);
1823 /* NT4 server just returns "invalid query" to this - if we try to answer
1824 it then NTws gets a BSOD! (tridge) */
1825 case SMB_QUERY_FILE_STREAM_INFO:
1827 SIVAL(pdata,4,(uint32)size);
1828 SIVAL(pdata,12,(uint32)allocation_size);
1829 len = srvstr_push(outbuf, pdata+24, fname, -1, STR_TERMINATE);
1830 SIVAL(pdata,20,len);
1831 data_size = 24 + len;
1836 return ERROR_DOS(ERRDOS,ERRunknownlevel);
1839 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, data_size);
1844 /****************************************************************************
1845 Deal with the internal needs of setting the delete on close flag. Note that
1846 as the tdb locking is recursive, it is safe to call this from within
1847 open_file_shared. JRA.
1848 ****************************************************************************/
1850 NTSTATUS set_delete_on_close_internal(files_struct *fsp, BOOL delete_on_close)
1853 * Only allow delete on close for writable shares.
1856 if (delete_on_close && !CAN_WRITE(fsp->conn)) {
1857 DEBUG(10,("set_delete_on_close_internal: file %s delete on close flag set but write access denied on share.\n",
1859 return NT_STATUS_ACCESS_DENIED;
1862 * Only allow delete on close for files/directories opened with delete intent.
1865 if (delete_on_close && !GET_DELETE_ACCESS_REQUESTED(fsp->share_mode)) {
1866 DEBUG(10,("set_delete_on_close_internal: file %s delete on close flag set but delete access denied.\n",
1868 return NT_STATUS_ACCESS_DENIED;
1871 if(fsp->is_directory) {
1872 fsp->directory_delete_on_close = delete_on_close;
1873 DEBUG(10, ("set_delete_on_close_internal: %s delete on close flag for fnum = %d, directory %s\n",
1874 delete_on_close ? "Added" : "Removed", fsp->fnum, fsp->fsp_name ));
1875 } else if(fsp->stat_open) {
1877 DEBUG(10, ("set_delete_on_close_internal: %s delete on close flag for fnum = %d, stat open %s\n",
1878 delete_on_close ? "Added" : "Removed", fsp->fnum, fsp->fsp_name ));
1882 files_struct *iterate_fsp;
1885 * Modify the share mode entry for all files open
1886 * on this device and inode to tell other smbds we have
1887 * changed the delete on close flag. This will be noticed
1888 * in the close code, the last closer will delete the file
1892 DEBUG(10,("set_delete_on_close_internal: %s delete on close flag for fnum = %d, file %s\n",
1893 delete_on_close ? "Adding" : "Removing", fsp->fnum, fsp->fsp_name ));
1895 if (lock_share_entry_fsp(fsp) == False)
1896 return NT_STATUS_ACCESS_DENIED;
1898 if (!modify_delete_flag(fsp->dev, fsp->inode, delete_on_close)) {
1899 DEBUG(0,("set_delete_on_close_internal: failed to change delete on close flag for file %s\n",
1901 unlock_share_entry_fsp(fsp);
1902 return NT_STATUS_ACCESS_DENIED;
1909 unlock_share_entry_fsp(fsp);
1912 * Go through all files we have open on the same device and
1913 * inode (hanging off the same hash bucket) and set the DELETE_ON_CLOSE_FLAG.
1914 * Other smbd's that have this file open will look in the share_mode on close.
1915 * take care of this (rare) case in close_file(). See the comment there.
1916 * NB. JRA. We don't really need to do this anymore - all should be taken
1917 * care of in the share_mode changes in the tdb.
1920 for(iterate_fsp = file_find_di_first(fsp->dev, fsp->inode);
1921 iterate_fsp; iterate_fsp = file_find_di_next(iterate_fsp))
1922 fsp->delete_on_close = delete_on_close;
1925 * Set the delete on close flag in the fsp.
1927 fsp->delete_on_close = delete_on_close;
1929 DEBUG(10, ("set_delete_on_close_internal: %s delete on close flag for fnum = %d, file %s\n",
1930 delete_on_close ? "Added" : "Removed", fsp->fnum, fsp->fsp_name ));
1934 return NT_STATUS_OK;
1937 /****************************************************************************
1938 Reply to a TRANS2_SETFILEINFO (set file info by fileid).
1939 ****************************************************************************/
1941 static int call_trans2setfilepathinfo(connection_struct *conn,
1942 char *inbuf, char *outbuf, int length,
1943 int bufsize, char **pparams,
1944 char **ppdata, int total_data)
1946 char *params = *pparams;
1947 char *pdata = *ppdata;
1948 uint16 tran_call = SVAL(inbuf, smb_setup0);
1953 SMB_STRUCT_STAT sbuf;
1956 BOOL bad_path = False;
1957 files_struct *fsp = NULL;
1959 if (tran_call == TRANSACT2_SETFILEINFO) {
1960 fsp = file_fsp(params,0);
1961 info_level = SVAL(params,2);
1963 if(fsp && (fsp->is_directory || fsp->stat_open)) {
1965 * This is actually a SETFILEINFO on a directory
1966 * handle (returned from an NT SMB). NT5.0 seems
1967 * to do this call. JRA.
1969 pstrcpy(fname, fsp->fsp_name);
1970 unix_convert(fname,conn,0,&bad_path,&sbuf);
1971 if (!check_name(fname,conn) || (!VALID_STAT(sbuf))) {
1972 DEBUG(3,("fileinfo of %s failed (%s)\n",fname,strerror(errno)));
1973 if((errno == ENOENT) && bad_path) {
1974 unix_ERR_class = ERRDOS;
1975 unix_ERR_code = ERRbadpath;
1977 return(UNIXERROR(ERRDOS,ERRbadpath));
1979 } else if (fsp && fsp->print_file) {
1981 * Doing a DELETE_ON_CLOSE should cancel a print job.
1983 if ((info_level == SMB_SET_FILE_DISPOSITION_INFO) && CVAL(pdata,0)) {
1984 fsp->share_mode = FILE_DELETE_ON_CLOSE;
1986 DEBUG(3,("call_trans2setfilepathinfo: Cancelling print job (%s)\n", fsp->fsp_name ));
1989 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
1994 * Original code - this is an open file.
1996 CHECK_FSP(fsp,conn);
1998 pstrcpy(fname, fsp->fsp_name);
2001 if (vfs_fstat(fsp,fd,&sbuf) != 0) {
2002 DEBUG(3,("fstat of fnum %d failed (%s)\n",fsp->fnum, strerror(errno)));
2003 return(UNIXERROR(ERRDOS,ERRbadfid));
2008 info_level = SVAL(params,0);
2009 srvstr_pull(inbuf, fname, ¶ms[6], sizeof(fname), -1, STR_TERMINATE);
2010 unix_convert(fname,conn,0,&bad_path,&sbuf);
2011 if(!check_name(fname, conn)) {
2012 if((errno == ENOENT) && bad_path) {
2013 unix_ERR_class = ERRDOS;
2014 unix_ERR_code = ERRbadpath;
2016 return(UNIXERROR(ERRDOS,ERRbadpath));
2019 if(!VALID_STAT(sbuf)) {
2020 DEBUG(3,("stat of %s failed (%s)\n", fname, strerror(errno)));
2021 if((errno == ENOENT) && bad_path) {
2022 unix_ERR_class = ERRDOS;
2023 unix_ERR_code = ERRbadpath;
2025 return(UNIXERROR(ERRDOS,ERRbadpath));
2029 if (!CAN_WRITE(conn))
2030 return ERROR_DOS(ERRSRV,ERRaccess);
2032 DEBUG(3,("call_trans2setfilepathinfo(%d) %s info_level=%d totdata=%d\n",
2033 tran_call,fname,info_level,total_data));
2035 /* Realloc the parameter and data sizes */
2036 params = Realloc(*pparams,2);
2038 return ERROR_DOS(ERRDOS,ERRnomem);
2043 size = sbuf.st_size;
2044 tvs.modtime = sbuf.st_mtime;
2045 tvs.actime = sbuf.st_atime;
2046 mode = dos_mode(conn,fname,&sbuf);
2048 if (total_data > 4 && IVAL(pdata,0) == total_data) {
2049 /* uggh, EAs for OS2 */
2050 DEBUG(4,("Rejecting EA request with total_data=%d\n",total_data));
2051 return ERROR_DOS(ERRDOS,ERReasnotsupported);
2054 switch (info_level) {
2055 case SMB_INFO_STANDARD:
2056 case SMB_INFO_QUERY_EA_SIZE:
2059 tvs.actime = make_unix_date2(pdata+l1_fdateLastAccess);
2062 tvs.modtime = make_unix_date2(pdata+l1_fdateLastWrite);
2064 mode = SVAL(pdata,l1_attrFile);
2065 size = IVAL(pdata,l1_cbFile);
2069 /* XXXX um, i don't think this is right.
2070 it's also not in the cifs6.txt spec.
2072 case SMB_INFO_QUERY_EAS_FROM_LIST:
2073 tvs.actime = make_unix_date2(pdata+8);
2074 tvs.modtime = make_unix_date2(pdata+12);
2075 size = IVAL(pdata,16);
2076 mode = IVAL(pdata,24);
2079 /* XXXX nor this. not in cifs6.txt, either. */
2080 case SMB_INFO_QUERY_ALL_EAS:
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 case SMB_SET_FILE_BASIC_INFO:
2088 case SMB_FILE_BASIC_INFORMATION:
2090 /* Patch to do this correctly from Paul Eggert <eggert@twinsun.com>. */
2092 time_t changed_time;
2094 /* Ignore create time at offset pdata. */
2097 tvs.actime = interpret_long_date(pdata+8);
2099 write_time = interpret_long_date(pdata+16);
2100 changed_time = interpret_long_date(pdata+24);
2102 tvs.modtime = MIN(write_time, changed_time);
2104 /* Prefer a defined time to an undefined one. */
2105 if (tvs.modtime == (time_t)0 || tvs.modtime == (time_t)-1)
2106 tvs.modtime = (write_time == (time_t)0 || write_time == (time_t)-1
2107 ? changed_time : write_time);
2110 mode = IVAL(pdata,32);
2114 case SMB_FILE_ALLOCATION_INFORMATION:
2115 case SMB_SET_FILE_ALLOCATION_INFO:
2118 SMB_OFF_T allocation_size = IVAL(pdata,0);
2119 #ifdef LARGE_SMB_OFF_T
2120 allocation_size |= (((SMB_OFF_T)IVAL(pdata,4)) << 32);
2121 #else /* LARGE_SMB_OFF_T */
2122 if (IVAL(pdata,4) != 0) /* more than 32 bits? */
2123 return ERROR_DOS(ERRDOS,ERRunknownlevel);
2124 #endif /* LARGE_SMB_OFF_T */
2125 DEBUG(10,("call_trans2setfilepathinfo: Set file allocation info for file %s to %.0f\n",
2126 fname, (double)allocation_size ));
2128 if(allocation_size != sbuf.st_size) {
2129 SMB_STRUCT_STAT new_sbuf;
2131 DEBUG(10,("call_trans2setfilepathinfo: file %s : setting new allocation size to %.0f\n",
2132 fname, (double)allocation_size ));
2135 files_struct *new_fsp = NULL;
2136 int access_mode = 0;
2139 if(global_oplock_break) {
2140 /* Queue this file modify as we are the process of an oplock break. */
2142 DEBUG(2,("call_trans2setfilepathinfo: queueing message due to being "));
2143 DEBUGADD(2,( "in oplock break state.\n"));
2145 push_oplock_pending_smb_message(inbuf, length);
2149 new_fsp = open_file_shared(conn, fname, &sbuf,
2150 SET_OPEN_MODE(DOS_OPEN_RDWR),
2151 (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN),
2152 0, 0, &access_mode, &action);
2154 if (new_fsp == NULL)
2155 return(UNIXERROR(ERRDOS,ERRbadpath));
2156 ret = vfs_allocate_file_space(new_fsp, allocation_size);
2157 if (vfs_fstat(new_fsp,new_fsp->fd,&new_sbuf) != 0) {
2158 DEBUG(3,("fstat of fnum %d failed (%s)\n",new_fsp->fnum, strerror(errno)));
2161 close_file(new_fsp,True);
2163 ret = vfs_allocate_file_space(fsp, size);
2164 if (vfs_fstat(fsp,fd,&new_sbuf) != 0) {
2165 DEBUG(3,("fstat of fnum %d failed (%s)\n",fsp->fnum, strerror(errno)));
2170 return ERROR_NT(NT_STATUS_DISK_FULL);
2172 /* Allocate can trucate size... */
2173 size = new_sbuf.st_size;
2179 case SMB_FILE_END_OF_FILE_INFORMATION:
2180 case SMB_SET_FILE_END_OF_FILE_INFO:
2182 size = IVAL(pdata,0);
2183 #ifdef LARGE_SMB_OFF_T
2184 size |= (((SMB_OFF_T)IVAL(pdata,4)) << 32);
2185 #else /* LARGE_SMB_OFF_T */
2186 if (IVAL(pdata,4) != 0) /* more than 32 bits? */
2187 return ERROR_DOS(ERRDOS,ERRunknownlevel);
2188 #endif /* LARGE_SMB_OFF_T */
2189 DEBUG(10,("call_trans2setfilepathinfo: Set end of file info for file %s to %.0f\n", fname, (double)size ));
2193 case SMB_FILE_DISPOSITION_INFORMATION:
2194 case SMB_SET_FILE_DISPOSITION_INFO: /* Set delete on close for open file. */
2196 BOOL delete_on_close = (CVAL(pdata,0) ? True : False);
2199 if (tran_call != TRANSACT2_SETFILEINFO)
2200 return ERROR_DOS(ERRDOS,ERRunknownlevel);
2203 return(UNIXERROR(ERRDOS,ERRbadfid));
2205 status = set_delete_on_close_internal(fsp, delete_on_close);
2207 if (NT_STATUS_V(status) != NT_STATUS_V(NT_STATUS_OK))
2208 return ERROR_NT(status);
2214 return ERROR_DOS(ERRDOS,ERRunknownlevel);
2217 /* get some defaults (no modifications) if any info is zero or -1. */
2218 if (tvs.actime == (time_t)0 || tvs.actime == (time_t)-1)
2219 tvs.actime = sbuf.st_atime;
2221 if (tvs.modtime == (time_t)0 || tvs.modtime == (time_t)-1)
2222 tvs.modtime = sbuf.st_mtime;
2224 DEBUG(6,("actime: %s " , ctime(&tvs.actime)));
2225 DEBUG(6,("modtime: %s ", ctime(&tvs.modtime)));
2226 DEBUG(6,("size: %.0f ", (double)size));
2227 DEBUG(6,("mode: %x\n" , mode));
2229 if(!((info_level == SMB_SET_FILE_END_OF_FILE_INFO) ||
2230 (info_level == SMB_SET_FILE_ALLOCATION_INFO) ||
2231 (info_level == SMB_FILE_ALLOCATION_INFORMATION) ||
2232 (info_level == SMB_FILE_END_OF_FILE_INFORMATION))) {
2235 * Only do this test if we are not explicitly
2236 * changing the size of a file.
2239 size = sbuf.st_size;
2243 * Try and set the times, size and mode of this file -
2244 * if they are different from the current values
2246 if (sbuf.st_mtime != tvs.modtime || sbuf.st_atime != tvs.actime) {
2249 * This was a setfileinfo on an open file.
2250 * NT does this a lot. It's actually pointless
2251 * setting the time here, as it will be overwritten
2252 * on the next write, so we save the request
2253 * away and will set it on file code. JRA.
2256 if (tvs.modtime != (time_t)0 && tvs.modtime != (time_t)-1) {
2257 DEBUG(10,("call_trans2setfilepathinfo: setting pending modtime to %s\n", ctime(&tvs.modtime) ));
2258 fsp->pending_modtime = tvs.modtime;
2263 DEBUG(10,("call_trans2setfilepathinfo: setting utimes to modified values.\n"));
2265 if(file_utime(conn, fname, &tvs)!=0)
2266 return(UNIXERROR(ERRDOS,ERRnoaccess));
2270 /* check the mode isn't different, before changing it */
2271 if ((mode != 0) && (mode != dos_mode(conn, fname, &sbuf))) {
2273 DEBUG(10,("call_trans2setfilepathinfo: file %s : setting dos mode %x\n", fname, mode ));
2275 if(file_chmod(conn, fname, mode, NULL)) {
2276 DEBUG(2,("chmod of %s failed (%s)\n", fname, strerror(errno)));
2277 return(UNIXERROR(ERRDOS,ERRnoaccess));
2281 if(size != sbuf.st_size) {
2283 DEBUG(10,("call_trans2setfilepathinfo: file %s : setting new size to %.0f\n",
2284 fname, (double)size ));
2287 files_struct *new_fsp = NULL;
2288 int access_mode = 0;
2291 if(global_oplock_break) {
2292 /* Queue this file modify as we are the process of an oplock break. */
2294 DEBUG(2,("call_trans2setfilepathinfo: queueing message due to being "));
2295 DEBUGADD(2,( "in oplock break state.\n"));
2297 push_oplock_pending_smb_message(inbuf, length);
2301 new_fsp = open_file_shared(conn, fname, &sbuf,
2302 SET_OPEN_MODE(DOS_OPEN_RDWR),
2303 (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN),
2304 0, 0, &access_mode, &action);
2306 if (new_fsp == NULL)
2307 return(UNIXERROR(ERRDOS,ERRbadpath));
2308 vfs_set_filelen(new_fsp, size);
2309 close_file(new_fsp,True);
2311 vfs_set_filelen(fsp, size);
2317 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
2322 /****************************************************************************
2323 Reply to a TRANS2_MKDIR (make directory with extended attributes).
2324 ****************************************************************************/
2326 static int call_trans2mkdir(connection_struct *conn,
2327 char *inbuf, char *outbuf, int length, int bufsize,
2328 char **pparams, char **ppdata)
2330 char *params = *pparams;
2333 SMB_STRUCT_STAT sbuf;
2334 BOOL bad_path = False;
2336 if (!CAN_WRITE(conn))
2337 return ERROR_DOS(ERRSRV,ERRaccess);
2339 srvstr_pull(inbuf, directory, ¶ms[4], sizeof(directory), -1, STR_TERMINATE);
2341 DEBUG(3,("call_trans2mkdir : name = %s\n", directory));
2343 unix_convert(directory,conn,0,&bad_path,&sbuf);
2344 if (check_name(directory,conn))
2345 ret = vfs_mkdir(conn,directory,unix_mode(conn,aDIR,directory));
2349 DEBUG(5,("call_trans2mkdir error (%s)\n", strerror(errno)));
2350 if((errno == ENOENT) && bad_path)
2352 unix_ERR_class = ERRDOS;
2353 unix_ERR_code = ERRbadpath;
2355 return(UNIXERROR(ERRDOS,ERRnoaccess));
2358 /* Realloc the parameter and data sizes */
2359 params = Realloc(*pparams,2);
2360 if(params == NULL) {
2361 return ERROR_DOS(ERRDOS,ERRnomem);
2367 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
2372 /****************************************************************************
2373 Reply to a TRANS2_FINDNOTIFYFIRST (start monitoring a directory for changes).
2374 We don't actually do this - we just send a null response.
2375 ****************************************************************************/
2377 static int call_trans2findnotifyfirst(connection_struct *conn,
2378 char *inbuf, char *outbuf,
2379 int length, int bufsize,
2380 char **pparams, char **ppdata)
2382 static uint16 fnf_handle = 257;
2383 char *params = *pparams;
2384 uint16 info_level = SVAL(params,4);
2386 DEBUG(3,("call_trans2findnotifyfirst - info_level %d\n", info_level));
2394 return ERROR_DOS(ERRDOS,ERRunknownlevel);
2397 /* Realloc the parameter and data sizes */
2398 params = Realloc(*pparams,6);
2399 if(params == NULL) {
2400 return ERROR_DOS(ERRDOS,ERRnomem);
2404 SSVAL(params,0,fnf_handle);
2405 SSVAL(params,2,0); /* No changes */
2406 SSVAL(params,4,0); /* No EA errors */
2413 send_trans2_replies(outbuf, bufsize, params, 6, *ppdata, 0);
2418 /****************************************************************************
2419 Reply to a TRANS2_FINDNOTIFYNEXT (continue monitoring a directory for
2420 changes). Currently this does nothing.
2421 ****************************************************************************/
2423 static int call_trans2findnotifynext(connection_struct *conn,
2424 char *inbuf, char *outbuf,
2425 int length, int bufsize,
2426 char **pparams, char **ppdata)
2428 char *params = *pparams;
2430 DEBUG(3,("call_trans2findnotifynext\n"));
2432 /* Realloc the parameter and data sizes */
2433 params = Realloc(*pparams,4);
2434 if(params == NULL) {
2435 return ERROR_DOS(ERRDOS,ERRnomem);
2439 SSVAL(params,0,0); /* No changes */
2440 SSVAL(params,2,0); /* No EA errors */
2442 send_trans2_replies(outbuf, bufsize, params, 4, *ppdata, 0);
2447 /****************************************************************************
2448 Reply to a TRANS2_GET_DFS_REFERRAL - Shirish Kalele <kalele@veritas.com>.
2449 ****************************************************************************/
2451 static int call_trans2getdfsreferral(connection_struct *conn, char* inbuf,
2452 char* outbuf, int length, int bufsize,
2453 char** pparams, char** ppdata)
2455 char *params = *pparams;
2458 int max_referral_level = SVAL(params,0);
2461 DEBUG(10,("call_trans2getdfsreferral\n"));
2463 if(!lp_host_msdfs())
2464 return ERROR_DOS(ERRDOS,ERRbadfunc);
2466 srvstr_pull(inbuf, pathname, ¶ms[2], sizeof(pathname), -1, STR_TERMINATE);
2468 if((reply_size = setup_dfs_referral(pathname,max_referral_level,ppdata)) < 0)
2469 return ERROR_DOS(ERRDOS,ERRbadfile);
2471 SSVAL(outbuf,smb_flg2,SVAL(outbuf,smb_flg2) | FLAGS2_DFS_PATHNAMES);
2472 send_trans2_replies(outbuf,bufsize,0,0,*ppdata,reply_size);
2477 #define LMCAT_SPL 0x53
2478 #define LMFUNC_GETJOBID 0x60
2480 /****************************************************************************
2481 Reply to a TRANS2_IOCTL - used for OS/2 printing.
2482 ****************************************************************************/
2484 static int call_trans2ioctl(connection_struct *conn, char* inbuf,
2485 char* outbuf, int length, int bufsize,
2486 char** pparams, char** ppdata)
2488 char *pdata = *ppdata;
2489 files_struct *fsp = file_fsp(inbuf,smb_vwv15);
2491 if ((SVAL(inbuf,(smb_setup+4)) == LMCAT_SPL) &&
2492 (SVAL(inbuf,(smb_setup+6)) == LMFUNC_GETJOBID)) {
2493 pdata = Realloc(*ppdata, 32);
2495 return ERROR_DOS(ERRDOS,ERRnomem);
2499 /* NOTE - THIS IS ASCII ONLY AT THE MOMENT - NOT SURE IF OS/2
2500 CAN ACCEPT THIS IN UNICODE. JRA. */
2502 SSVAL(pdata,0,fsp->print_jobid); /* Job number */
2503 srvstr_push( outbuf, pdata + 2, global_myname, 15, STR_ASCII|STR_TERMINATE); /* Our NetBIOS name */
2504 srvstr_push( outbuf, pdata+18, lp_servicename(SNUM(conn)), 13, STR_ASCII|STR_TERMINATE); /* Service name */
2505 send_trans2_replies(outbuf,bufsize,*pparams,0,*ppdata,32);
2508 DEBUG(2,("Unknown TRANS2_IOCTL\n"));
2509 return ERROR_DOS(ERRSRV,ERRerror);
2513 /****************************************************************************
2514 Reply to a SMBfindclose (stop trans2 directory search).
2515 ****************************************************************************/
2517 int reply_findclose(connection_struct *conn,
2518 char *inbuf,char *outbuf,int length,int bufsize)
2521 int dptr_num=SVALS(inbuf,smb_vwv0);
2522 START_PROFILE(SMBfindclose);
2524 DEBUG(3,("reply_findclose, dptr_num = %d\n", dptr_num));
2526 dptr_close(&dptr_num);
2528 outsize = set_message(outbuf,0,0,True);
2530 DEBUG(3,("SMBfindclose dptr_num = %d\n", dptr_num));
2532 END_PROFILE(SMBfindclose);
2536 /****************************************************************************
2537 Reply to a SMBfindnclose (stop FINDNOTIFYFIRST directory search).
2538 ****************************************************************************/
2540 int reply_findnclose(connection_struct *conn,
2541 char *inbuf,char *outbuf,int length,int bufsize)
2545 START_PROFILE(SMBfindnclose);
2547 dptr_num = SVAL(inbuf,smb_vwv0);
2549 DEBUG(3,("reply_findnclose, dptr_num = %d\n", dptr_num));
2551 /* We never give out valid handles for a
2552 findnotifyfirst - so any dptr_num is ok here.
2555 outsize = set_message(outbuf,0,0,True);
2557 DEBUG(3,("SMB_findnclose dptr_num = %d\n", dptr_num));
2559 END_PROFILE(SMBfindnclose);
2563 /****************************************************************************
2564 Reply to a SMBtranss2 - just ignore it!
2565 ****************************************************************************/
2567 int reply_transs2(connection_struct *conn,
2568 char *inbuf,char *outbuf,int length,int bufsize)
2570 START_PROFILE(SMBtranss2);
2571 DEBUG(4,("Ignoring transs2 of length %d\n",length));
2572 END_PROFILE(SMBtranss2);
2576 /****************************************************************************
2577 Reply to a SMBtrans2.
2578 ****************************************************************************/
2580 int reply_trans2(connection_struct *conn,
2581 char *inbuf,char *outbuf,int length,int bufsize)
2584 unsigned int total_params = SVAL(inbuf, smb_tpscnt);
2585 unsigned int total_data =SVAL(inbuf, smb_tdscnt);
2587 unsigned int max_param_reply = SVAL(inbuf, smb_mprcnt);
2588 unsigned int max_data_reply = SVAL(inbuf, smb_mdrcnt);
2589 unsigned int max_setup_fields = SVAL(inbuf, smb_msrcnt);
2590 BOOL close_tid = BITSETW(inbuf+smb_flags,0);
2591 BOOL no_final_response = BITSETW(inbuf+smb_flags,1);
2592 int32 timeout = IVALS(inbuf,smb_timeout);
2594 unsigned int suwcnt = SVAL(inbuf, smb_suwcnt);
2595 unsigned int tran_call = SVAL(inbuf, smb_setup0);
2596 char *params = NULL, *data = NULL;
2597 int num_params, num_params_sofar, num_data, num_data_sofar;
2598 START_PROFILE(SMBtrans2);
2600 if(global_oplock_break && (tran_call == TRANSACT2_OPEN)) {
2601 /* Queue this open message as we are the process of an
2604 DEBUG(2,("reply_trans2: queueing message trans2open due to being "));
2605 DEBUGADD(2,( "in oplock break state.\n"));
2607 push_oplock_pending_smb_message(inbuf, length);
2608 END_PROFILE(SMBtrans2);
2612 if (IS_IPC(conn) && (tran_call != TRANSACT2_OPEN)
2613 && (tran_call != TRANSACT2_GET_DFS_REFERRAL)) {
2614 END_PROFILE(SMBtrans2);
2615 return ERROR_DOS(ERRSRV,ERRaccess);
2618 outsize = set_message(outbuf,0,0,True);
2620 /* All trans2 messages we handle have smb_sucnt == 1 - ensure this
2621 is so as a sanity check */
2624 * Need to have rc=0 for ioctl to get job id for OS/2.
2625 * Network printing will fail if function is not successful.
2626 * Similar function in reply.c will be used if protocol
2627 * is LANMAN1.0 instead of LM1.2X002.
2628 * Until DosPrintSetJobInfo with PRJINFO3 is supported,
2629 * outbuf doesn't have to be set(only job id is used).
2631 if ( (suwcnt == 4) && (tran_call == TRANSACT2_IOCTL) &&
2632 (SVAL(inbuf,(smb_setup+4)) == LMCAT_SPL) &&
2633 (SVAL(inbuf,(smb_setup+6)) == LMFUNC_GETJOBID)) {
2634 DEBUG(2,("Got Trans2 DevIOctl jobid\n"));
2636 DEBUG(2,("Invalid smb_sucnt in trans2 call(%d)\n",suwcnt));
2637 DEBUG(2,("Transaction is %d\n",tran_call));
2638 END_PROFILE(SMBtrans2);
2639 return ERROR_DOS(ERRSRV,ERRerror);
2643 /* Allocate the space for the maximum needed parameters and data */
2644 if (total_params > 0)
2645 params = (char *)malloc(total_params);
2647 data = (char *)malloc(total_data);
2649 if ((total_params && !params) || (total_data && !data)) {
2650 DEBUG(2,("Out of memory in reply_trans2\n"));
2653 END_PROFILE(SMBtrans2);
2654 return ERROR_DOS(ERRDOS,ERRnomem);
2657 /* Copy the param and data bytes sent with this request into
2658 the params buffer */
2659 num_params = num_params_sofar = SVAL(inbuf,smb_pscnt);
2660 num_data = num_data_sofar = SVAL(inbuf, smb_dscnt);
2662 if (num_params > total_params || num_data > total_data)
2663 exit_server("invalid params in reply_trans2");
2666 memcpy( params, smb_base(inbuf) + SVAL(inbuf, smb_psoff), num_params);
2668 memcpy( data, smb_base(inbuf) + SVAL(inbuf, smb_dsoff), num_data);
2670 if(num_data_sofar < total_data || num_params_sofar < total_params) {
2671 /* We need to send an interim response then receive the rest
2672 of the parameter/data bytes */
2673 outsize = set_message(outbuf,0,0,True);
2674 if (!send_smb(smbd_server_fd(),outbuf))
2675 exit_server("reply_trans2: send_smb failed.");
2677 while (num_data_sofar < total_data ||
2678 num_params_sofar < total_params) {
2681 ret = receive_next_smb(inbuf,bufsize,SMB_SECONDARY_WAIT);
2684 (CVAL(inbuf, smb_com) != SMBtranss2)) || !ret) {
2685 outsize = set_message(outbuf,0,0,True);
2687 DEBUG(0,("reply_trans2: Invalid secondary trans2 packet\n"));
2689 DEBUG(0,("reply_trans2: %s in getting secondary trans2 response.\n",
2690 (smb_read_error == READ_ERROR) ? "error" : "timeout" ));
2693 END_PROFILE(SMBtrans2);
2694 return ERROR_DOS(ERRSRV,ERRerror);
2697 /* Revise total_params and total_data in case
2698 they have changed downwards */
2699 total_params = SVAL(inbuf, smb_tpscnt);
2700 total_data = SVAL(inbuf, smb_tdscnt);
2701 num_params_sofar += (num_params = SVAL(inbuf,smb_spscnt));
2702 num_data_sofar += ( num_data = SVAL(inbuf, smb_sdscnt));
2703 if (num_params_sofar > total_params || num_data_sofar > total_data)
2704 exit_server("data overflow in trans2");
2706 memcpy( ¶ms[ SVAL(inbuf, smb_spsdisp)],
2707 smb_base(inbuf) + SVAL(inbuf, smb_spsoff), num_params);
2708 memcpy( &data[SVAL(inbuf, smb_sdsdisp)],
2709 smb_base(inbuf)+ SVAL(inbuf, smb_sdsoff), num_data);
2713 if (Protocol >= PROTOCOL_NT1) {
2714 SSVAL(outbuf,smb_flg2,SVAL(outbuf,smb_flg2) | 0x40); /* IS_LONG_NAME */
2717 /* Now we must call the relevant TRANS2 function */
2719 case TRANSACT2_OPEN:
2720 START_PROFILE_NESTED(Trans2_open);
2721 outsize = call_trans2open(conn,
2722 inbuf, outbuf, bufsize,
2724 END_PROFILE_NESTED(Trans2_open);
2727 case TRANSACT2_FINDFIRST:
2728 START_PROFILE_NESTED(Trans2_findfirst);
2729 outsize = call_trans2findfirst(conn, inbuf, outbuf,
2730 bufsize, ¶ms, &data);
2731 END_PROFILE_NESTED(Trans2_findfirst);
2734 case TRANSACT2_FINDNEXT:
2735 START_PROFILE_NESTED(Trans2_findnext);
2736 outsize = call_trans2findnext(conn, inbuf, outbuf,
2739 END_PROFILE_NESTED(Trans2_findnext);
2742 case TRANSACT2_QFSINFO:
2743 START_PROFILE_NESTED(Trans2_qfsinfo);
2744 outsize = call_trans2qfsinfo(conn, inbuf, outbuf,
2745 length, bufsize, ¶ms,
2747 END_PROFILE_NESTED(Trans2_qfsinfo);
2750 case TRANSACT2_SETFSINFO:
2751 START_PROFILE_NESTED(Trans2_setfsinfo);
2752 outsize = call_trans2setfsinfo(conn, inbuf, outbuf,
2755 END_PROFILE_NESTED(Trans2_setfsinfo);
2758 case TRANSACT2_QPATHINFO:
2759 case TRANSACT2_QFILEINFO:
2760 START_PROFILE_NESTED(Trans2_qpathinfo);
2761 outsize = call_trans2qfilepathinfo(conn, inbuf, outbuf,
2763 ¶ms, &data, total_data);
2764 END_PROFILE_NESTED(Trans2_qpathinfo);
2766 case TRANSACT2_SETPATHINFO:
2767 case TRANSACT2_SETFILEINFO:
2768 START_PROFILE_NESTED(Trans2_setpathinfo);
2769 outsize = call_trans2setfilepathinfo(conn, inbuf, outbuf,
2773 END_PROFILE_NESTED(Trans2_setpathinfo);
2776 case TRANSACT2_FINDNOTIFYFIRST:
2777 START_PROFILE_NESTED(Trans2_findnotifyfirst);
2778 outsize = call_trans2findnotifyfirst(conn, inbuf, outbuf,
2781 END_PROFILE_NESTED(Trans2_findnotifyfirst);
2784 case TRANSACT2_FINDNOTIFYNEXT:
2785 START_PROFILE_NESTED(Trans2_findnotifynext);
2786 outsize = call_trans2findnotifynext(conn, inbuf, outbuf,
2789 END_PROFILE_NESTED(Trans2_findnotifynext);
2791 case TRANSACT2_MKDIR:
2792 START_PROFILE_NESTED(Trans2_mkdir);
2793 outsize = call_trans2mkdir(conn, inbuf, outbuf, length,
2794 bufsize, ¶ms, &data);
2795 END_PROFILE_NESTED(Trans2_mkdir);
2798 case TRANSACT2_GET_DFS_REFERRAL:
2799 START_PROFILE_NESTED(Trans2_get_dfs_referral);
2800 outsize = call_trans2getdfsreferral(conn,inbuf,outbuf,length,
2801 bufsize, ¶ms, &data);
2802 END_PROFILE_NESTED(Trans2_get_dfs_referral);
2804 case TRANSACT2_IOCTL:
2805 START_PROFILE_NESTED(Trans2_ioctl);
2806 outsize = call_trans2ioctl(conn,inbuf,outbuf,length,
2807 bufsize,¶ms,&data);
2808 END_PROFILE_NESTED(Trans2_ioctl);
2811 /* Error in request */
2812 DEBUG(2,("Unknown request %d in trans2 call\n", tran_call));
2815 END_PROFILE(SMBtrans2);
2816 return ERROR_DOS(ERRSRV,ERRerror);
2819 /* As we do not know how many data packets will need to be
2820 returned here the various call_trans2xxxx calls
2821 must send their own. Thus a call_trans2xxx routine only
2822 returns a value other than -1 when it wants to send
2828 END_PROFILE(SMBtrans2);
2829 return outsize; /* If a correct response was needed the
2830 call_trans2xxx calls have already sent
2831 it. If outsize != -1 then it is returning */