2 Unix SMB/Netbios implementation.
4 SMB transaction2 handling
5 Copyright (C) Jeremy Allison 1994-1998
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.
26 extern int DEBUGLEVEL;
28 extern BOOL case_sensitive;
29 extern int smb_read_error;
30 extern fstring local_machine;
31 extern int global_oplock_break;
32 extern uint32 global_client_caps;
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 ****************************************************************************/
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 = 3;
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 send_smb(smbd_server_fd(),outbuf);
71 /* When sending params and data ensure that both are nicely aligned */
72 /* Only do this alignment when there is also data to send - else
73 can cause NT redirector problems. */
74 if (((params_to_send % 4) != 0) && (data_to_send != 0))
75 data_alignment_offset = 4 - (params_to_send % 4);
77 /* Space is bufsize minus Netbios over TCP header minus SMB header */
78 /* The alignment_offset is to align the param bytes on an even byte
79 boundary. NT 4.0 Beta needs this to work correctly. */
80 useable_space = bufsize - ((smb_buf(outbuf)+
81 alignment_offset+data_alignment_offset) -
84 /* useable_space can never be more than max_send minus the
86 useable_space = MIN(useable_space,
87 max_send - (alignment_offset+data_alignment_offset));
90 while (params_to_send || data_to_send)
92 /* Calculate whether we will totally or partially fill this packet */
93 total_sent_thistime = params_to_send + data_to_send +
94 alignment_offset + data_alignment_offset;
95 /* We can never send more than useable_space */
97 * Note that 'useable_space' does not include the alignment offsets,
98 * but we must include the alignment offsets in the calculation of
99 * the length of the data we send over the wire, as the alignment offsets
100 * are sent here. Fix from Marc_Jacobsen@hp.com.
102 total_sent_thistime = MIN(total_sent_thistime, useable_space+
103 alignment_offset + data_alignment_offset);
105 set_message(outbuf, 10, total_sent_thistime, True);
107 /* Set total params and data to be sent */
108 SSVAL(outbuf,smb_tprcnt,paramsize);
109 SSVAL(outbuf,smb_tdrcnt,datasize);
111 /* Calculate how many parameters and data we can fit into
112 this packet. Parameters get precedence */
114 params_sent_thistime = MIN(params_to_send,useable_space);
115 data_sent_thistime = useable_space - params_sent_thistime;
116 data_sent_thistime = MIN(data_sent_thistime,data_to_send);
118 SSVAL(outbuf,smb_prcnt, params_sent_thistime);
120 /* smb_proff is the offset from the start of the SMB header to the
121 parameter bytes, however the first 4 bytes of outbuf are
122 the Netbios over TCP header. Thus use smb_base() to subtract
123 them from the calculation */
125 SSVAL(outbuf,smb_proff,((smb_buf(outbuf)+alignment_offset) - smb_base(outbuf)));
127 if(params_sent_thistime == 0)
128 SSVAL(outbuf,smb_prdisp,0);
130 /* Absolute displacement of param bytes sent in this packet */
131 SSVAL(outbuf,smb_prdisp,pp - params);
133 SSVAL(outbuf,smb_drcnt, data_sent_thistime);
134 if(data_sent_thistime == 0)
136 SSVAL(outbuf,smb_droff,0);
137 SSVAL(outbuf,smb_drdisp, 0);
141 /* The offset of the data bytes is the offset of the
142 parameter bytes plus the number of parameters being sent this time */
143 SSVAL(outbuf,smb_droff,((smb_buf(outbuf)+alignment_offset) -
144 smb_base(outbuf)) + params_sent_thistime + data_alignment_offset);
145 SSVAL(outbuf,smb_drdisp, pd - pdata);
148 /* Copy the param bytes into the packet */
149 if(params_sent_thistime)
150 memcpy((smb_buf(outbuf)+alignment_offset),pp,params_sent_thistime);
151 /* Copy in the data bytes */
152 if(data_sent_thistime)
153 memcpy(smb_buf(outbuf)+alignment_offset+params_sent_thistime+
154 data_alignment_offset,pd,data_sent_thistime);
156 DEBUG(9,("t2_rep: params_sent_thistime = %d, data_sent_thistime = %d, useable_space = %d\n",
157 params_sent_thistime, data_sent_thistime, useable_space));
158 DEBUG(9,("t2_rep: params_to_send = %d, data_to_send = %d, paramsize = %d, datasize = %d\n",
159 params_to_send, data_to_send, paramsize, datasize));
161 /* Send the packet */
162 send_smb(smbd_server_fd(),outbuf);
164 pp += params_sent_thistime;
165 pd += data_sent_thistime;
167 params_to_send -= params_sent_thistime;
168 data_to_send -= data_sent_thistime;
171 if(params_to_send < 0 || data_to_send < 0)
173 DEBUG(0,("send_trans2_replies failed sanity check pts = %d, dts = %d\n!!!",
174 params_to_send, data_to_send));
183 /****************************************************************************
184 reply to a TRANSACT2_OPEN
185 ****************************************************************************/
186 static int call_trans2open(connection_struct *conn, char *inbuf, char *outbuf,
188 char **pparams, char **ppdata)
190 char *params = *pparams;
191 int16 open_mode = SVAL(params, 2);
192 int16 open_attr = SVAL(params,6);
193 BOOL oplock_request = (((SVAL(params,0)|(1<<1))>>1) | ((SVAL(params,0)|(1<<2))>>1));
195 BOOL return_additional_info = BITSETW(params,0);
196 int16 open_sattr = SVAL(params, 4);
197 time_t open_time = make_unix_date3(params+8);
199 int16 open_ofun = SVAL(params,12);
200 int32 open_size = IVAL(params,14);
201 char *pname = ¶ms[28];
205 int fmode=0,mtime=0,rmode;
207 SMB_STRUCT_STAT sbuf;
209 BOOL bad_path = False;
212 srvstr_pull(inbuf, fname, pname, sizeof(fname), -1, STR_TERMINATE);
214 DEBUG(3,("trans2open %s mode=%d attr=%d ofun=%d size=%d\n",
215 fname,open_mode, open_attr, open_ofun, open_size));
218 return(ERROR(ERRSRV,ERRaccess));
221 /* XXXX we need to handle passed times, sattr and flags */
223 unix_convert(fname,conn,0,&bad_path,&sbuf);
225 if (!check_name(fname,conn))
227 if((errno == ENOENT) && bad_path)
229 unix_ERR_class = ERRDOS;
230 unix_ERR_code = ERRbadpath;
232 return(UNIXERROR(ERRDOS,ERRnoaccess));
235 unixmode = unix_mode(conn,open_attr | aARCH, fname);
237 fsp = open_file_shared(conn,fname,&sbuf,open_mode,open_ofun,unixmode,
238 oplock_request, &rmode,&smb_action);
242 if((errno == ENOENT) && bad_path)
244 unix_ERR_class = ERRDOS;
245 unix_ERR_code = ERRbadpath;
247 return(UNIXERROR(ERRDOS,ERRnoaccess));
251 fmode = dos_mode(conn,fname,&sbuf);
252 mtime = sbuf.st_mtime;
255 close_file(fsp,False);
256 return(ERROR(ERRDOS,ERRnoaccess));
259 /* Realloc the size of parameters and data we will return */
260 params = Realloc(*pparams, 28);
261 if( params == NULL ) {
262 return(ERROR(ERRDOS,ERRnomem));
266 memset((char *)params,'\0',28);
267 SSVAL(params,0,fsp->fnum);
268 SSVAL(params,2,fmode);
269 put_dos_date2(params,4, mtime);
270 SIVAL(params,8, (uint32)size);
271 SSVAL(params,12,rmode);
273 if (oplock_request && lp_fake_oplocks(SNUM(conn))) {
274 smb_action |= EXTENDED_OPLOCK_GRANTED;
277 SSVAL(params,18,smb_action);
279 * WARNING - this may need to be changed if SMB_INO_T <> 4 bytes.
281 SIVAL(params,20,inode);
283 /* Send the required number of replies */
284 send_trans2_replies(outbuf, bufsize, params, 28, *ppdata, 0);
289 /*********************************************************
290 * Routine to check if a given string matches exactly.
291 * as a special case a mask of "." does NOT match. That
292 * is required for correct wildcard semantics
293 * Case can be significant or not.
294 **********************************************************/
295 static BOOL exact_match(char *str,char *mask, BOOL case_sig)
297 if (mask[0] == '.' && mask[1] == 0) return False;
298 if (case_sig) return strcmp(str,mask)==0;
299 return strcasecmp(str,mask) == 0;
302 /****************************************************************************
303 get a level dependent lanman2 dir entry.
304 ****************************************************************************/
305 static BOOL get_lanman2_dir_entry(connection_struct *conn,
306 void *inbuf, void *outbuf,
307 char *path_mask,int dirtype,int info_level,
308 int requires_resume_key,
309 BOOL dont_descend,char **ppdata,
310 char *base_data, int space_remaining,
311 BOOL *out_of_space, BOOL *got_exact_match,
316 SMB_STRUCT_STAT sbuf;
320 char *p, *q, *pdata = *ppdata;
326 time_t mdate=0, adate=0, cdate=0;
329 int nt_extmode; /* Used for NT connections instead of mode */
330 BOOL needslash = ( conn->dirpath[strlen(conn->dirpath) -1] != '/');
333 *out_of_space = False;
334 *got_exact_match = False;
339 p = strrchr(path_mask,'/');
348 pstrcpy(mask, path_mask);
354 /* Needed if we run out of space */
355 prev_dirpos = TellDir(conn->dirptr);
356 dname = ReadDirName(conn->dirptr);
359 * Due to bugs in NT client redirectors we are not using
360 * resume keys any more - set them to zero.
361 * Check out the related comments in findfirst/findnext.
367 DEBUG(8,("get_lanman2_dir_entry:readdir on dirptr 0x%lx now at offset %d\n",
368 (long)conn->dirptr,TellDir(conn->dirptr)));
373 pstrcpy(fname,dname);
375 if(!(got_match = *got_exact_match = exact_match(fname, mask, case_sensitive))) {
376 got_match = mask_match(fname, mask, case_sensitive);
379 if(!got_match && !is_8_3(fname, False)) {
382 * It turns out that NT matches wildcards against
383 * both long *and* short names. This may explain some
384 * of the wildcard wierdness from old DOS clients
385 * that some people have been seeing.... JRA.
389 pstrcpy( newname, fname);
390 name_map_mangle( newname, True, False, SNUM(conn));
391 if(!(got_match = *got_exact_match = exact_match(newname, mask, case_sensitive)))
392 got_match = mask_match(newname, mask, case_sensitive);
397 BOOL isdots = (strequal(fname,"..") || strequal(fname,"."));
398 if (dont_descend && !isdots)
401 pstrcpy(pathreal,conn->dirpath);
403 pstrcat(pathreal,"/");
404 pstrcat(pathreal,dname);
405 if (vfs_stat(conn,pathreal,&sbuf) != 0)
407 /* Needed to show the msdfs symlinks as directories */
408 if(!lp_host_msdfs() || !lp_msdfs_root(SNUM(conn))
409 || !is_msdfs_link(conn, pathreal))
411 DEBUG(5,("get_lanman2_dir_entry:Couldn't stat [%s] (%s)\n",
412 pathreal,strerror(errno)));
417 DEBUG(5,("get_lanman2_dir_entry: Masquerading msdfs link %s as a directory\n", pathreal));
418 sbuf.st_mode = (sbuf.st_mode & 0xFFF) | S_IFDIR;
422 mode = dos_mode(conn,pathreal,&sbuf);
424 if (!dir_check_ftype(conn,mode,&sbuf,dirtype)) {
425 DEBUG(5,("[%s] attribs didn't match %x\n",fname,dirtype));
430 mdate = sbuf.st_mtime;
431 adate = sbuf.st_atime;
432 cdate = get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(conn)));
436 DEBUG(5,("get_lanman2_dir_entry found %s fname=%s\n",pathreal,fname));
442 name_map_mangle(fname,False,True,SNUM(conn));
447 nt_extmode = mode ? mode : FILE_ATTRIBUTE_NORMAL;
452 if(requires_resume_key) {
456 put_dos_date2(p,l1_fdateCreation,cdate);
457 put_dos_date2(p,l1_fdateLastAccess,adate);
458 put_dos_date2(p,l1_fdateLastWrite,mdate);
459 SIVAL(p,l1_cbFile,(uint32)size);
460 SIVAL(p,l1_cbFileAlloc,SMB_ROUNDUP(size,1024));
461 SSVAL(p,l1_attrFile,mode);
464 len = srvstr_push(outbuf, p, fname, -1,
465 STR_TERMINATE|STR_CONVERT);
472 if(requires_resume_key) {
476 put_dos_date2(p,l2_fdateCreation,cdate);
477 put_dos_date2(p,l2_fdateLastAccess,adate);
478 put_dos_date2(p,l2_fdateLastWrite,mdate);
479 SIVAL(p,l2_cbFile,(uint32)size);
480 SIVAL(p,l2_cbFileAlloc,SMB_ROUNDUP(size,1024));
481 SSVAL(p,l2_attrFile,mode);
482 SIVAL(p,l2_cbList,0); /* No extended attributes */
485 len = srvstr_push(outbuf, p, fname, -1,
486 STR_TERMINATE|STR_CONVERT);
493 put_dos_date2(p,4,cdate);
494 put_dos_date2(p,8,adate);
495 put_dos_date2(p,12,mdate);
496 SIVAL(p,16,(uint32)size);
497 SIVAL(p,20,SMB_ROUNDUP(size,1024));
502 len = srvstr_push(outbuf, p, fname, -1,
503 STR_TERMINATE|STR_CONVERT);
509 if(requires_resume_key) {
514 put_dos_date2(p,4,cdate);
515 put_dos_date2(p,8,adate);
516 put_dos_date2(p,12,mdate);
517 SIVAL(p,16,(uint32)size);
518 SIVAL(p,20,SMB_ROUNDUP(size,1024));
522 len = srvstr_push(outbuf, p, fname, -1,
523 STR_TERMINATE|STR_CONVERT);
526 SIVAL(q,4,PTR_DIFF(p, q));
530 case SMB_FIND_FILE_BOTH_DIRECTORY_INFO:
531 was_8_3 = is_8_3(fname, True);
533 SIVAL(p,0,reskey); p += 4;
534 put_long_date(p,cdate); p += 8;
535 put_long_date(p,adate); p += 8;
536 put_long_date(p,mdate); p += 8;
537 put_long_date(p,mdate); p += 8;
541 SIVAL(p,0,nt_extmode); p += 4;
543 SIVAL(p,0,0); p += 4;
545 pstring mangled_name;
546 pstrcpy(mangled_name, fname);
547 name_map_mangle(mangled_name,True,True,SNUM(conn));
548 mangled_name[12] = 0;
549 len = srvstr_push(outbuf, p+2, mangled_name, 24,
550 STR_CONVERT|STR_UPPER);
557 len = srvstr_push(outbuf, p, fname, -1,
558 STR_TERMINATE|STR_CONVERT);
561 len = PTR_DIFF(p, pdata);
562 len = (len + 3) & ~3;
567 case SMB_FIND_FILE_DIRECTORY_INFO:
569 SIVAL(p,0,reskey); p += 4;
570 put_long_date(p,cdate); p += 8;
571 put_long_date(p,adate); p += 8;
572 put_long_date(p,mdate); p += 8;
573 put_long_date(p,mdate); p += 8;
577 SIVAL(p,0,nt_extmode); p += 4;
579 len = srvstr_push(outbuf, p, fname, -1,
580 STR_TERMINATE|STR_CONVERT);
583 len = PTR_DIFF(p, pdata);
584 len = (len + 3) & ~3;
590 case SMB_FIND_FILE_FULL_DIRECTORY_INFO:
592 SIVAL(p,0,reskey); p += 4;
593 put_long_date(p,cdate); p += 8;
594 put_long_date(p,adate); p += 8;
595 put_long_date(p,mdate); p += 8;
596 put_long_date(p,mdate); p += 8;
600 SIVAL(p,0,nt_extmode); p += 4;
602 SIVAL(p,0,0); p += 4;
604 len = srvstr_push(outbuf, p, fname, -1,
605 STR_TERMINATE|STR_CONVERT);
609 len = PTR_DIFF(p, pdata);
610 len = (len + 3) & ~3;
615 case SMB_FIND_FILE_NAMES_INFO:
617 SIVAL(p,0,reskey); p += 4;
619 len = srvstr_push(outbuf, p, fname, -1,
620 STR_TERMINATE|STR_CONVERT);
623 len = PTR_DIFF(p, pdata);
624 len = (len + 3) & ~3;
634 if (PTR_DIFF(p,pdata) > space_remaining) {
635 /* Move the dirptr back to prev_dirpos */
636 SeekDir(conn->dirptr, prev_dirpos);
637 *out_of_space = True;
638 DEBUG(9,("get_lanman2_dir_entry: out of space\n"));
639 return False; /* Not finished - just out of space */
642 /* Setup the last_filename pointer, as an offset from base_data */
643 *last_name_off = PTR_DIFF(nameptr,base_data);
644 /* Advance the data pointer to the next slot */
651 /****************************************************************************
652 Reply to a TRANS2_FINDFIRST.
653 ****************************************************************************/
655 static int call_trans2findfirst(connection_struct *conn,
656 char *inbuf, char *outbuf, int bufsize,
657 char **pparams, char **ppdata)
659 /* We must be careful here that we don't return more than the
660 allowed number of data bytes. If this means returning fewer than
661 maxentries then so be it. We assume that the redirector has
662 enough room for the fixed number of parameter bytes it has
664 uint32 max_data_bytes = SVAL(inbuf, smb_mdrcnt);
665 char *params = *pparams;
666 char *pdata = *ppdata;
667 int dirtype = SVAL(params,0);
668 int maxentries = SVAL(params,2);
669 BOOL close_after_first = BITSETW(params+4,0);
670 BOOL close_if_end = BITSETW(params+4,1);
671 BOOL requires_resume_key = BITSETW(params+4,2);
672 int info_level = SVAL(params,6);
680 BOOL finished = False;
681 BOOL dont_descend = False;
682 BOOL out_of_space = False;
684 BOOL bad_path = False;
685 SMB_STRUCT_STAT sbuf;
687 *directory = *mask = 0;
689 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",
690 dirtype, maxentries, close_after_first, close_if_end, requires_resume_key,
691 info_level, max_data_bytes));
699 case SMB_FIND_FILE_DIRECTORY_INFO:
700 case SMB_FIND_FILE_FULL_DIRECTORY_INFO:
701 case SMB_FIND_FILE_NAMES_INFO:
702 case SMB_FIND_FILE_BOTH_DIRECTORY_INFO:
705 return(ERROR(ERRDOS,ERRunknownlevel));
708 srvstr_pull(inbuf, directory, params+12, sizeof(directory), -1, STR_TERMINATE);
710 RESOLVE_FINDFIRST_DFSPATH(directory, conn, inbuf, outbuf);
712 unix_convert(directory,conn,0,&bad_path,&sbuf);
713 if(!check_name(directory,conn)) {
714 if((errno == ENOENT) && bad_path)
716 unix_ERR_class = ERRDOS;
717 unix_ERR_code = ERRbadpath;
721 /* Ugly - NT specific hack - maybe not needed ? (JRA) */
722 if((errno == ENOTDIR) && (Protocol >= PROTOCOL_NT1) &&
723 (get_remote_arch() == RA_WINNT))
725 unix_ERR_class = ERRDOS;
726 unix_ERR_code = ERRbaddirectory;
730 return(UNIXERROR(ERRDOS,ERRbadpath));
733 p = strrchr(directory,'/');
735 pstrcpy(mask,directory);
736 pstrcpy(directory,"./");
742 DEBUG(5,("dir=%s, mask = %s\n",directory, mask));
744 pdata = Realloc(*ppdata, max_data_bytes + 1024);
745 if( pdata == NULL ) {
746 return(ERROR(ERRDOS,ERRnomem));
749 memset((char *)pdata,'\0',max_data_bytes + 1024);
751 /* Realloc the params space */
752 params = Realloc(*pparams, 10);
753 if( params == NULL ) {
754 return(ERROR(ERRDOS,ERRnomem));
758 dptr_num = dptr_create(conn,directory, False, True ,SVAL(inbuf,smb_pid));
760 return(UNIXERROR(ERRDOS,ERRbadfile));
762 /* Save the wildcard match and attribs we are using on this directory -
763 needed as lanman2 assumes these are being saved between calls */
765 if(!(wcard = strdup(mask))) {
766 dptr_close(&dptr_num);
767 return(ERROR(ERRDOS,ERRnomem));
770 dptr_set_wcard(dptr_num, wcard);
771 dptr_set_attr(dptr_num, dirtype);
773 DEBUG(4,("dptr_num is %d, wcard = %s, attr = %d\n",dptr_num, wcard, dirtype));
775 /* We don't need to check for VOL here as this is returned by
776 a different TRANS2 call. */
778 DEBUG(8,("dirpath=<%s> dontdescend=<%s>\n",
779 conn->dirpath,lp_dontdescend(SNUM(conn))));
780 if (in_list(conn->dirpath,lp_dontdescend(SNUM(conn)),case_sensitive))
784 space_remaining = max_data_bytes;
785 out_of_space = False;
787 for (i=0;(i<maxentries) && !finished && !out_of_space;i++)
789 BOOL got_exact_match = False;
791 /* this is a heuristic to avoid seeking the dirptr except when
792 absolutely necessary. It allows for a filename of about 40 chars */
793 if (space_remaining < DIRLEN_GUESS && numentries > 0)
800 finished = !get_lanman2_dir_entry(conn,
802 mask,dirtype,info_level,
803 requires_resume_key,dont_descend,
804 &p,pdata,space_remaining, &out_of_space, &got_exact_match,
808 if (finished && out_of_space)
811 if (!finished && !out_of_space)
815 * As an optimisation if we know we aren't looking
816 * for a wildcard name (ie. the name matches the wildcard exactly)
817 * then we can finish on any (first) match.
818 * This speeds up large directory searches. JRA.
824 space_remaining = max_data_bytes - PTR_DIFF(p,pdata);
827 /* Check if we can close the dirptr */
828 if(close_after_first || (finished && close_if_end))
830 DEBUG(5,("call_trans2findfirst - (2) closing dptr_num %d\n", dptr_num));
831 dptr_close(&dptr_num);
835 * If there are no matching entries we must return ERRDOS/ERRbadfile -
836 * from observation of NT.
841 dptr_close(&dptr_num);
842 return(ERROR(ERRDOS,ERRbadfile));
845 /* At this point pdata points to numentries directory entries. */
847 /* Set up the return parameter block */
848 SSVAL(params,0,dptr_num);
849 SSVAL(params,2,numentries);
850 SSVAL(params,4,finished);
851 SSVAL(params,6,0); /* Never an EA error */
852 SSVAL(params,8,last_name_off);
854 send_trans2_replies( outbuf, bufsize, params, 10, pdata, PTR_DIFF(p,pdata));
856 if ((! *directory) && dptr_path(dptr_num))
857 slprintf(directory,sizeof(directory)-1, "(%s)",dptr_path(dptr_num));
859 DEBUG( 4, ( "%s mask=%s directory=%s dirtype=%d numentries=%d\n",
860 smb_fn_name(CVAL(inbuf,smb_com)),
861 mask, directory, dirtype, numentries ) );
864 * Force a name mangle here to ensure that the
865 * mask as an 8.3 name is top of the mangled cache.
866 * The reasons for this are subtle. Don't remove
867 * this code unless you know what you are doing
868 * (see PR#13758). JRA.
871 if(!is_8_3( mask, False))
872 name_map_mangle(mask, True, True, SNUM(conn));
878 /****************************************************************************
879 reply to a TRANS2_FINDNEXT
880 ****************************************************************************/
881 static int call_trans2findnext(connection_struct *conn,
882 char *inbuf, char *outbuf,
883 int length, int bufsize,
884 char **pparams, char **ppdata)
886 /* We must be careful here that we don't return more than the
887 allowed number of data bytes. If this means returning fewer than
888 maxentries then so be it. We assume that the redirector has
889 enough room for the fixed number of parameter bytes it has
891 int max_data_bytes = SVAL(inbuf, smb_mdrcnt);
892 char *params = *pparams;
893 char *pdata = *ppdata;
894 int dptr_num = SVAL(params,0);
895 int maxentries = SVAL(params,2);
896 uint16 info_level = SVAL(params,4);
897 uint32 resume_key = IVAL(params,6);
898 BOOL close_after_request = BITSETW(params+10,0);
899 BOOL close_if_end = BITSETW(params+10,1);
900 BOOL requires_resume_key = BITSETW(params+10,2);
901 BOOL continue_bit = BITSETW(params+10,3);
908 int i, last_name_off=0;
909 BOOL finished = False;
910 BOOL dont_descend = False;
911 BOOL out_of_space = False;
914 *mask = *directory = *resume_name = 0;
916 srvstr_pull(inbuf, resume_name, params+12, sizeof(resume_name), -1, STR_TERMINATE|STR_CONVERT);
918 DEBUG(3,("call_trans2findnext: dirhandle = %d, max_data_bytes = %d, maxentries = %d, \
919 close_after_request=%d, close_if_end = %d requires_resume_key = %d \
920 resume_key = %d resume name = %s continue=%d level = %d\n",
921 dptr_num, max_data_bytes, maxentries, close_after_request, close_if_end,
922 requires_resume_key, resume_key, resume_name, continue_bit, info_level));
930 case SMB_FIND_FILE_DIRECTORY_INFO:
931 case SMB_FIND_FILE_FULL_DIRECTORY_INFO:
932 case SMB_FIND_FILE_NAMES_INFO:
933 case SMB_FIND_FILE_BOTH_DIRECTORY_INFO:
936 return(ERROR(ERRDOS,ERRunknownlevel));
939 pdata = Realloc( *ppdata, max_data_bytes + 1024);
941 return(ERROR(ERRDOS,ERRnomem));
944 memset((char *)pdata,'\0',max_data_bytes + 1024);
946 /* Realloc the params space */
947 params = Realloc(*pparams, 6*SIZEOFWORD);
948 if( params == NULL ) {
949 return(ERROR(ERRDOS,ERRnomem));
953 /* Check that the dptr is valid */
954 if(!(conn->dirptr = dptr_fetch_lanman2(dptr_num)))
955 return(ERROR(ERRDOS,ERRnofiles));
957 string_set(&conn->dirpath,dptr_path(dptr_num));
959 /* Get the wildcard mask from the dptr */
960 if((p = dptr_wcard(dptr_num))== NULL) {
961 DEBUG(2,("dptr_num %d has no wildcard\n", dptr_num));
962 return (ERROR(ERRDOS,ERRnofiles));
965 pstrcpy(directory,conn->dirpath);
967 /* Get the attr mask from the dptr */
968 dirtype = dptr_attr(dptr_num);
970 DEBUG(3,("dptr_num is %d, mask = %s, attr = %x, dirptr=(0x%lX,%d)\n",
971 dptr_num, mask, dirtype,
973 TellDir(conn->dirptr)));
975 /* We don't need to check for VOL here as this is returned by
976 a different TRANS2 call. */
978 DEBUG(8,("dirpath=<%s> dontdescend=<%s>\n",conn->dirpath,lp_dontdescend(SNUM(conn))));
979 if (in_list(conn->dirpath,lp_dontdescend(SNUM(conn)),case_sensitive))
983 space_remaining = max_data_bytes;
984 out_of_space = False;
987 * Seek to the correct position. We no longer use the resume key but
988 * depend on the last file name instead.
990 if(requires_resume_key && *resume_name && !continue_bit)
993 * Fix for NT redirector problem triggered by resume key indexes
994 * changing between directory scans. We now return a resume key of 0
995 * and instead look for the filename to continue from (also given
996 * to us by NT/95/smbfs/smbclient). If no other scans have been done between the
997 * findfirst/findnext (as is usual) then the directory pointer
998 * should already be at the correct place. Check this by scanning
999 * backwards looking for an exact (ie. case sensitive) filename match.
1000 * If we get to the beginning of the directory and haven't found it then scan
1001 * forwards again looking for a match. JRA.
1004 int current_pos, start_pos;
1006 void *dirptr = conn->dirptr;
1007 start_pos = TellDir(dirptr);
1008 for(current_pos = start_pos; current_pos >= 0; current_pos--)
1010 DEBUG(7,("call_trans2findnext: seeking to pos %d\n", current_pos));
1012 SeekDir(dirptr, current_pos);
1013 dname = ReadDirName(dirptr);
1016 * Remember, name_map_mangle is called by
1017 * get_lanman2_dir_entry(), so the resume name
1018 * could be mangled. Ensure we do the same
1023 name_map_mangle( dname, False, True, SNUM(conn));
1025 if(dname && strcsequal( resume_name, dname))
1027 SeekDir(dirptr, current_pos+1);
1028 DEBUG(7,("call_trans2findnext: got match at pos %d\n", current_pos+1 ));
1034 * Scan forward from start if not found going backwards.
1039 DEBUG(7,("call_trans2findnext: notfound: seeking to pos %d\n", start_pos));
1040 SeekDir(dirptr, start_pos);
1041 for(current_pos = start_pos; (dname = ReadDirName(dirptr)) != NULL; SeekDir(dirptr,++current_pos))
1044 * Remember, name_map_mangle is called by
1045 * get_lanman2_dir_entry(), so the resume name
1046 * could be mangled. Ensure we do the same
1051 name_map_mangle( dname, False, True, SNUM(conn));
1053 if(dname && strcsequal( resume_name, dname))
1055 SeekDir(dirptr, current_pos+1);
1056 DEBUG(7,("call_trans2findnext: got match at pos %d\n", current_pos+1 ));
1060 } /* end if current_pos */
1061 } /* end if requires_resume_key && !continue_bit */
1063 for (i=0;(i<(int)maxentries) && !finished && !out_of_space ;i++)
1065 BOOL got_exact_match = False;
1067 /* this is a heuristic to avoid seeking the dirptr except when
1068 absolutely necessary. It allows for a filename of about 40 chars */
1069 if (space_remaining < DIRLEN_GUESS && numentries > 0)
1071 out_of_space = True;
1076 finished = !get_lanman2_dir_entry(conn,
1078 mask,dirtype,info_level,
1079 requires_resume_key,dont_descend,
1080 &p,pdata,space_remaining, &out_of_space, &got_exact_match,
1084 if (finished && out_of_space)
1087 if (!finished && !out_of_space)
1091 * As an optimisation if we know we aren't looking
1092 * for a wildcard name (ie. the name matches the wildcard exactly)
1093 * then we can finish on any (first) match.
1094 * This speeds up large directory searches. JRA.
1100 space_remaining = max_data_bytes - PTR_DIFF(p,pdata);
1103 /* Check if we can close the dirptr */
1104 if(close_after_request || (finished && close_if_end))
1106 DEBUG(5,("call_trans2findnext: closing dptr_num = %d\n", dptr_num));
1107 dptr_close(&dptr_num); /* This frees up the saved mask */
1111 /* Set up the return parameter block */
1112 SSVAL(params,0,numentries);
1113 SSVAL(params,2,finished);
1114 SSVAL(params,4,0); /* Never an EA error */
1115 SSVAL(params,6,last_name_off);
1117 send_trans2_replies( outbuf, bufsize, params, 8, pdata, PTR_DIFF(p,pdata));
1119 if ((! *directory) && dptr_path(dptr_num))
1120 slprintf(directory,sizeof(directory)-1, "(%s)",dptr_path(dptr_num));
1122 DEBUG( 3, ( "%s mask=%s directory=%s dirtype=%d numentries=%d\n",
1123 smb_fn_name(CVAL(inbuf,smb_com)),
1124 mask, directory, dirtype, numentries ) );
1129 /****************************************************************************
1130 reply to a TRANS2_QFSINFO (query filesystem info)
1131 ****************************************************************************/
1133 static int call_trans2qfsinfo(connection_struct *conn,
1134 char *inbuf, char *outbuf,
1135 int length, int bufsize,
1136 char **pparams, char **ppdata)
1138 int max_data_bytes = SVAL(inbuf, smb_mdrcnt);
1139 char *pdata = *ppdata;
1140 char *params = *pparams;
1141 uint16 info_level = SVAL(params,0);
1144 char *vname = volume_label(SNUM(conn));
1145 int snum = SNUM(conn);
1146 char *fstype = lp_fstype(SNUM(conn));
1148 DEBUG(3,("call_trans2qfsinfo: level = %d\n", info_level));
1150 if(vfs_stat(conn,".",&st)!=0) {
1151 DEBUG(2,("call_trans2qfsinfo: stat of . failed (%s)\n", strerror(errno)));
1152 return (ERROR(ERRSRV,ERRinvdevice));
1155 pdata = Realloc(*ppdata, max_data_bytes + 1024);
1156 if ( pdata == NULL ) {
1157 return(ERROR(ERRDOS,ERRnomem));
1160 memset((char *)pdata,'\0',max_data_bytes + 1024);
1166 SMB_BIG_UINT dfree,dsize,bsize;
1168 conn->vfs_ops.disk_free(conn,".",False,&bsize,&dfree,&dsize);
1169 SIVAL(pdata,l1_idFileSystem,st.st_dev);
1170 SIVAL(pdata,l1_cSectorUnit,bsize/512);
1171 SIVAL(pdata,l1_cUnit,dsize);
1172 SIVAL(pdata,l1_cUnitAvail,dfree);
1173 SSVAL(pdata,l1_cbSector,512);
1174 DEBUG(5,("call_trans2qfsinfo : bsize=%u, id=%x, cSectorUnit=%u, cUnit=%u, cUnitAvail=%u, cbSector=%d\n",
1175 (unsigned int)bsize, (unsigned int)st.st_dev, ((unsigned int)bsize)/512, (unsigned int)dsize,
1176 (unsigned int)dfree, 512));
1180 /* Return volume name */
1182 * Add volume serial number - hash of a combination of
1183 * the called hostname and the service name.
1185 SIVAL(pdata,0,str_checksum(lp_servicename(snum)) ^ (str_checksum(local_machine)<<16) );
1186 len = srvstr_push(outbuf, pdata+l2_vol_szVolLabel, vname, -1,
1187 STR_TERMINATE|STR_CONVERT);
1188 SCVAL(pdata,l2_vol_cch,len);
1189 data_len = l2_vol_szVolLabel + len;
1190 DEBUG(5,("call_trans2qfsinfo : time = %x, namelen = %d, name = %s\n",
1191 (unsigned)st.st_ctime, len, vname));
1194 case SMB_QUERY_FS_ATTRIBUTE_INFO:
1195 SIVAL(pdata,0,FILE_CASE_PRESERVED_NAMES|FILE_CASE_SENSITIVE_SEARCH|
1196 FILE_DEVICE_IS_MOUNTED|
1197 (lp_nt_acl_support() ? FILE_PERSISTENT_ACLS : 0)); /* FS ATTRIBUTES */
1198 SIVAL(pdata,4,128); /* Max filename component length */
1199 len = srvstr_push(outbuf, pdata+12, fstype, -1, STR_TERMINATE|STR_CONVERT);
1201 data_len = 12 + len;
1204 case SMB_QUERY_FS_LABEL_INFO:
1205 len = srvstr_push(outbuf, pdata+4, vname, -1, STR_TERMINATE|STR_CONVERT);
1209 case SMB_QUERY_FS_VOLUME_INFO:
1211 * Add volume serial number - hash of a combination of
1212 * the called hostname and the service name.
1214 SIVAL(pdata,8,str_checksum(lp_servicename(snum)) ^
1215 (str_checksum(local_machine)<<16));
1217 len = srvstr_push(outbuf, pdata+18, vname, -1, STR_TERMINATE|STR_CONVERT);
1218 SIVAL(pdata,12,len);
1220 DEBUG(5,("call_trans2qfsinfo : SMB_QUERY_FS_VOLUME_INFO namelen = %d, vol = %s\n",
1221 (int)strlen(vname),vname));
1223 case SMB_QUERY_FS_SIZE_INFO:
1225 SMB_BIG_UINT dfree,dsize,bsize;
1227 conn->vfs_ops.disk_free(conn,".",False,&bsize,&dfree,&dsize);
1228 SBIG_UINT(pdata,0,dsize);
1229 SBIG_UINT(pdata,8,dfree);
1230 SIVAL(pdata,16,bsize/512);
1231 SIVAL(pdata,20,512);
1234 case SMB_QUERY_FS_DEVICE_INFO:
1236 SIVAL(pdata,0,0); /* dev type */
1237 SIVAL(pdata,4,0); /* characteristics */
1239 case SMB_MAC_QUERY_FS_INFO:
1241 * Thursby MAC extension... ONLY on NTFS filesystems
1242 * once we do streams then we don't need this
1244 if (strequal(lp_fstype(SNUM(conn)),"NTFS")) {
1246 SIVAL(pdata,84,0x100); /* Don't support mac... */
1251 return(ERROR(ERRDOS,ERRunknownlevel));
1255 send_trans2_replies( outbuf, bufsize, params, 0, pdata, data_len);
1257 DEBUG( 4, ( "%s info_level = %d\n",
1258 smb_fn_name(CVAL(inbuf,smb_com)), info_level) );
1263 /****************************************************************************
1264 reply to a TRANS2_SETFSINFO (set filesystem info)
1265 ****************************************************************************/
1266 static int call_trans2setfsinfo(connection_struct *conn,
1267 char *inbuf, char *outbuf, int length,
1269 char **pparams, char **ppdata)
1271 /* Just say yes we did it - there is nothing that
1272 can be set here so it doesn't matter. */
1274 DEBUG(3,("call_trans2setfsinfo\n"));
1276 if (!CAN_WRITE(conn))
1277 return(ERROR(ERRSRV,ERRaccess));
1279 outsize = set_message(outbuf,10,0,True);
1284 /****************************************************************************
1285 Reply to a TRANS2_QFILEPATHINFO or TRANSACT2_QFILEINFO (query file info by
1286 file name or file id).
1287 ****************************************************************************/
1289 static int call_trans2qfilepathinfo(connection_struct *conn,
1290 char *inbuf, char *outbuf, int length,
1292 char **pparams,char **ppdata,
1295 int max_data_bytes = SVAL(inbuf, smb_mdrcnt);
1296 char *params = *pparams;
1297 char *pdata = *ppdata;
1298 uint16 tran_call = SVAL(inbuf, smb_setup0);
1302 unsigned int data_size;
1303 SMB_STRUCT_STAT sbuf;
1308 BOOL bad_path = False;
1309 BOOL delete_pending = False;
1312 if (tran_call == TRANSACT2_QFILEINFO) {
1313 files_struct *fsp = file_fsp(params,0);
1314 info_level = SVAL(params,2);
1316 DEBUG(3,("call_trans2qfilepathinfo: TRANSACT2_QFILEINFO: level = %d\n",
1319 if(fsp && (fsp->is_directory || fsp->stat_open)) {
1321 * This is actually a QFILEINFO on a directory
1322 * handle (returned from an NT SMB). NT5.0 seems
1323 * to do this call. JRA.
1325 pstrcpy(fname, fsp->fsp_name);
1326 unix_convert(fname,conn,0,&bad_path,&sbuf);
1327 if (!check_name(fname,conn) ||
1328 (!VALID_STAT(sbuf) && vfs_stat(conn,fname,&sbuf))) {
1329 DEBUG(3,("fileinfo of %s failed (%s)\n",fname,strerror(errno)));
1330 if((errno == ENOENT) && bad_path) {
1331 unix_ERR_class = ERRDOS;
1332 unix_ERR_code = ERRbadpath;
1334 return(UNIXERROR(ERRDOS,ERRbadpath));
1337 delete_pending = fsp->directory_delete_on_close;
1340 * Original code - this is an open file.
1342 CHECK_FSP(fsp,conn);
1345 pstrcpy(fname, fsp->fsp_name);
1346 if (vfs_fstat(fsp,fsp->fd,&sbuf) != 0) {
1347 DEBUG(3,("fstat of fnum %d failed (%s)\n",
1348 fsp->fnum, strerror(errno)));
1349 return(UNIXERROR(ERRDOS,ERRbadfid));
1351 if((pos = fsp->conn->vfs_ops.lseek(fsp,fsp->fd,0,SEEK_CUR)) == -1)
1352 return(UNIXERROR(ERRDOS,ERRnoaccess));
1354 delete_pending = fsp->delete_on_close;
1358 info_level = SVAL(params,0);
1360 DEBUG(3,("call_trans2qfilepathinfo: TRANSACT2_QPATHINFO: level = %d\n",
1363 srvstr_pull(inbuf, fname, ¶ms[6], sizeof(fname), -1, STR_TERMINATE);
1365 RESOLVE_DFSPATH(fname, conn, inbuf, outbuf);
1367 unix_convert(fname,conn,0,&bad_path,&sbuf);
1368 if (!check_name(fname,conn) ||
1369 (!VALID_STAT(sbuf) && vfs_stat(conn,fname,&sbuf))) {
1370 DEBUG(3,("fileinfo of %s failed (%s)\n",fname,strerror(errno)));
1371 if((errno == ENOENT) && bad_path) {
1372 unix_ERR_class = ERRDOS;
1373 unix_ERR_code = ERRbadpath;
1375 return(UNIXERROR(ERRDOS,ERRbadpath));
1380 DEBUG(3,("call_trans2qfilepathinfo %s level=%d call=%d total_data=%d\n",
1381 fname,info_level,tran_call,total_data));
1383 p = strrchr(fname,'/');
1390 mode = dos_mode(conn,fname,&sbuf);
1391 size = sbuf.st_size;
1392 if (mode & aDIR) size = 0;
1394 params = Realloc(*pparams,2);
1395 if (params == NULL) {
1396 return(ERROR(ERRDOS,ERRnomem));
1399 memset((char *)params,'\0',2);
1400 data_size = max_data_bytes + 1024;
1401 pdata = Realloc(*ppdata, data_size);
1402 if ( pdata == NULL ) {
1403 return(ERROR(ERRDOS,ERRnomem));
1407 if (total_data > 0 && IVAL(pdata,0) == total_data) {
1408 /* uggh, EAs for OS2 */
1409 DEBUG(4,("Rejecting EA request with total_data=%d\n",total_data));
1410 return(ERROR(ERRDOS,ERROR_EAS_NOT_SUPPORTED));
1413 memset((char *)pdata,'\0',data_size);
1417 case SMB_INFO_STANDARD:
1418 case SMB_INFO_QUERY_EA_SIZE:
1419 data_size = (info_level==1?22:26);
1420 put_dos_date2(pdata,l1_fdateCreation,get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(conn))));
1421 put_dos_date2(pdata,l1_fdateLastAccess,sbuf.st_atime);
1422 put_dos_date2(pdata,l1_fdateLastWrite,sbuf.st_mtime); /* write time */
1423 SIVAL(pdata,l1_cbFile,(uint32)size);
1424 SIVAL(pdata,l1_cbFileAlloc,SMB_ROUNDUP(size,1024));
1425 SSVAL(pdata,l1_attrFile,mode);
1426 SIVAL(pdata,l1_attrFile+2,4); /* this is what OS2 does */
1429 case SMB_INFO_QUERY_EAS_FROM_LIST:
1431 put_dos_date2(pdata,0,get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(conn))));
1432 put_dos_date2(pdata,4,sbuf.st_atime);
1433 put_dos_date2(pdata,8,sbuf.st_mtime);
1434 SIVAL(pdata,12,(uint32)size);
1435 SIVAL(pdata,16,SMB_ROUNDUP(size,1024));
1436 SIVAL(pdata,20,mode);
1439 case SMB_INFO_QUERY_ALL_EAS:
1441 SIVAL(pdata,0,data_size);
1445 return(ERROR(ERRDOS,ERRbadfunc)); /* os/2 needs this */
1447 case SMB_QUERY_FILE_BASIC_INFO:
1448 data_size = 36; /* w95 returns 40 bytes not 36 - why ?. */
1449 put_long_date(pdata,get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(conn))));
1450 put_long_date(pdata+8,sbuf.st_atime);
1451 put_long_date(pdata+16,sbuf.st_mtime); /* write time */
1452 put_long_date(pdata+24,sbuf.st_mtime); /* change time */
1453 SIVAL(pdata,32,mode);
1455 DEBUG(5,("SMB_QFBI - "));
1457 time_t create_time = get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(conn)));
1458 DEBUG(5,("create: %s ", ctime(&create_time)));
1460 DEBUG(5,("access: %s ", ctime(&sbuf.st_atime)));
1461 DEBUG(5,("write: %s ", ctime(&sbuf.st_mtime)));
1462 DEBUG(5,("change: %s ", ctime(&sbuf.st_mtime)));
1463 DEBUG(5,("mode: %x\n", mode));
1467 case SMB_QUERY_FILE_STANDARD_INFO:
1469 SOFF_T(pdata,0,size);
1470 SOFF_T(pdata,8,size);
1471 SIVAL(pdata,16,sbuf.st_nlink);
1473 CVAL(pdata,21) = (mode&aDIR)?1:0;
1476 case SMB_QUERY_FILE_EA_INFO:
1480 /* Get the 8.3 name - used if NT SMB was negotiated. */
1481 case SMB_QUERY_FILE_ALT_NAME_INFO:
1485 pstrcpy(short_name,base_name);
1486 /* Mangle if not already 8.3 */
1487 if(!is_8_3(short_name, True))
1489 if(!name_map_mangle(short_name,True,True,SNUM(conn)))
1492 len = srvstr_push(outbuf, pdata+4, short_name, -1,
1493 STR_TERMINATE|STR_CONVERT|STR_UPPER);
1494 data_size = 4 + len;
1499 case SMB_QUERY_FILE_NAME_INFO:
1501 * The first part of this code is essential
1502 * to get security descriptors to work on mapped
1503 * drives. Don't ask how I discovered this unless
1504 * you like hearing about me suffering.... :-). JRA.
1506 if(strequal(".", fname)) {
1507 len = srvstr_push(outbuf, pdata+4, "\\", -1, STR_TERMINATE|STR_CONVERT);
1509 len = srvstr_push(outbuf, pdata+4, fname, -1, STR_TERMINATE|STR_CONVERT);
1511 data_size = 4 + len;
1515 case SMB_QUERY_FILE_ALLOCATION_INFO:
1516 case SMB_QUERY_FILE_END_OF_FILEINFO:
1518 SOFF_T(pdata,0,size);
1521 case SMB_QUERY_FILE_ALL_INFO:
1522 put_long_date(pdata,get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(conn))));
1523 put_long_date(pdata+8,sbuf.st_atime);
1524 put_long_date(pdata+16,sbuf.st_mtime); /* write time */
1525 put_long_date(pdata+24,sbuf.st_mtime); /* change time */
1526 SIVAL(pdata,32,mode);
1528 SOFF_T(pdata,0,size);
1529 SOFF_T(pdata,8,size);
1530 SIVAL(pdata,16,sbuf.st_nlink);
1531 CVAL(pdata,20) = delete_pending;
1532 CVAL(pdata,21) = (mode&aDIR)?1:0;
1534 SINO_T(pdata,0,(SMB_INO_T)sbuf.st_ino);
1535 pdata += 8; /* index number */
1536 pdata += 4; /* EA info */
1538 SIVAL(pdata,0,0xA9);
1540 SIVAL(pdata,0,0xd01BF);
1542 SOFF_T(pdata,0,pos); /* current offset */
1544 SIVAL(pdata,0,mode); /* is this the right sort of mode info? */
1546 pdata += 4; /* alignment */
1547 len = srvstr_push(outbuf, pdata+4, fname, -1, STR_TERMINATE|STR_CONVERT);
1550 data_size = PTR_DIFF(pdata,(*ppdata));
1554 /* NT4 server just returns "invalid query" to this - if we try to answer
1555 it then NTws gets a BSOD! (tridge) */
1556 case SMB_QUERY_FILE_STREAM_INFO:
1558 SIVAL(pdata,4,size);
1559 SIVAL(pdata,12,size);
1560 len = srvstr_push(outbuf, pdata+24, fname, -1, STR_TERMINATE|STR_CONVERT);
1561 SIVAL(pdata,20,len);
1562 data_size = 24 + len;
1567 return(ERROR(ERRDOS,ERRunknownlevel));
1570 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, data_size);
1575 /****************************************************************************
1576 reply to a TRANS2_SETFILEINFO (set file info by fileid)
1577 ****************************************************************************/
1578 static int call_trans2setfilepathinfo(connection_struct *conn,
1579 char *inbuf, char *outbuf, int length,
1580 int bufsize, char **pparams,
1581 char **ppdata, int total_data)
1583 char *params = *pparams;
1584 char *pdata = *ppdata;
1585 uint16 tran_call = SVAL(inbuf, smb_setup0);
1590 SMB_STRUCT_STAT sbuf;
1594 BOOL bad_path = False;
1595 files_struct *fsp = NULL;
1597 if (tran_call == TRANSACT2_SETFILEINFO) {
1598 fsp = file_fsp(params,0);
1599 info_level = SVAL(params,2);
1601 if(fsp && (fsp->is_directory || fsp->stat_open)) {
1603 * This is actually a SETFILEINFO on a directory
1604 * handle (returned from an NT SMB). NT5.0 seems
1605 * to do this call. JRA.
1607 fname = fsp->fsp_name;
1608 unix_convert(fname,conn,0,&bad_path,&sbuf);
1609 if (!check_name(fname,conn) || (!VALID_STAT(sbuf))) {
1610 DEBUG(3,("fileinfo of %s failed (%s)\n",fname,strerror(errno)));
1611 if((errno == ENOENT) && bad_path)
1613 unix_ERR_class = ERRDOS;
1614 unix_ERR_code = ERRbadpath;
1616 return(UNIXERROR(ERRDOS,ERRbadpath));
1618 } else if (fsp->print_file) {
1620 * Doing a DELETE_ON_CLOSE should cancel a print job.
1622 if ((info_level == SMB_SET_FILE_DISPOSITION_INFO) && CVAL(pdata,0)) {
1623 fsp->share_mode = FILE_DELETE_ON_CLOSE;
1625 DEBUG(3,("call_trans2setfilepathinfo: Cancelling print job (%s)\n",
1629 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
1634 * Original code - this is an open file.
1636 CHECK_FSP(fsp,conn);
1639 fname = fsp->fsp_name;
1642 if (vfs_fstat(fsp,fd,&sbuf) != 0) {
1643 DEBUG(3,("fstat of fnum %d failed (%s)\n",fsp->fnum, strerror(errno)));
1644 return(UNIXERROR(ERRDOS,ERRbadfid));
1649 info_level = SVAL(params,0);
1651 pstrcpy(fname,¶ms[6]);
1652 unix_convert(fname,conn,0,&bad_path,&sbuf);
1653 if(!check_name(fname, conn))
1655 if((errno == ENOENT) && bad_path)
1657 unix_ERR_class = ERRDOS;
1658 unix_ERR_code = ERRbadpath;
1660 return(UNIXERROR(ERRDOS,ERRbadpath));
1663 if(!VALID_STAT(sbuf)) {
1664 DEBUG(3,("stat of %s failed (%s)\n", fname, strerror(errno)));
1665 if((errno == ENOENT) && bad_path)
1667 unix_ERR_class = ERRDOS;
1668 unix_ERR_code = ERRbadpath;
1670 return(UNIXERROR(ERRDOS,ERRbadpath));
1674 if (!CAN_WRITE(conn))
1675 return(ERROR(ERRSRV,ERRaccess));
1677 DEBUG(3,("call_trans2setfilepathinfo(%d) %s info_level=%d totdata=%d\n",
1678 tran_call,fname,info_level,total_data));
1680 /* Realloc the parameter and data sizes */
1681 params = Realloc(*pparams,2);
1682 if(params == NULL) {
1683 return(ERROR(ERRDOS,ERRnomem));
1689 size = sbuf.st_size;
1690 tvs.modtime = sbuf.st_mtime;
1691 tvs.actime = sbuf.st_atime;
1692 mode = dos_mode(conn,fname,&sbuf);
1694 if (total_data > 0 && IVAL(pdata,0) == total_data) {
1695 /* uggh, EAs for OS2 */
1696 DEBUG(4,("Rejecting EA request with total_data=%d\n",total_data));
1697 return(ERROR(ERRDOS,ERROR_EAS_NOT_SUPPORTED));
1702 case SMB_INFO_STANDARD:
1703 case SMB_INFO_QUERY_EA_SIZE:
1706 tvs.actime = make_unix_date2(pdata+l1_fdateLastAccess);
1709 tvs.modtime = make_unix_date2(pdata+l1_fdateLastWrite);
1711 mode = SVAL(pdata,l1_attrFile);
1712 size = IVAL(pdata,l1_cbFile);
1716 /* XXXX um, i don't think this is right.
1717 it's also not in the cifs6.txt spec.
1719 case SMB_INFO_QUERY_EAS_FROM_LIST:
1720 tvs.actime = make_unix_date2(pdata+8);
1721 tvs.modtime = make_unix_date2(pdata+12);
1722 size = IVAL(pdata,16);
1723 mode = IVAL(pdata,24);
1726 /* XXXX nor this. not in cifs6.txt, either. */
1727 case SMB_INFO_QUERY_ALL_EAS:
1728 tvs.actime = make_unix_date2(pdata+8);
1729 tvs.modtime = make_unix_date2(pdata+12);
1730 size = IVAL(pdata,16);
1731 mode = IVAL(pdata,24);
1734 case SMB_SET_FILE_BASIC_INFO:
1736 /* Patch to do this correctly from Paul Eggert <eggert@twinsun.com>. */
1738 time_t changed_time;
1740 /* Ignore create time at offset pdata. */
1743 tvs.actime = interpret_long_date(pdata+8);
1745 write_time = interpret_long_date(pdata+16);
1746 changed_time = interpret_long_date(pdata+24);
1748 tvs.modtime = MIN(write_time, changed_time);
1750 /* Prefer a defined time to an undefined one. */
1751 if (tvs.modtime == (time_t)0 || tvs.modtime == (time_t)-1)
1752 tvs.modtime = (write_time == (time_t)0 || write_time == (time_t)-1
1756 #if 0 /* Needs more testing... */
1757 /* Test from Luke to prevent Win95 from
1758 setting incorrect values here.
1760 if (tvs.actime < tvs.modtime)
1761 return(ERROR(ERRDOS,ERRnoaccess));
1762 #endif /* Needs more testing... */
1765 mode = IVAL(pdata,32);
1770 * NT seems to use this call with a size of zero
1771 * to mean truncate the file. JRA.
1774 case SMB_SET_FILE_ALLOCATION_INFO:
1776 SMB_OFF_T newsize = IVAL(pdata,0);
1777 #ifdef LARGE_SMB_OFF_T
1778 newsize |= (((SMB_OFF_T)IVAL(pdata,4)) << 32);
1779 #else /* LARGE_SMB_OFF_T */
1780 if (IVAL(pdata,4) != 0) /* more than 32 bits? */
1781 return(ERROR(ERRDOS,ERRunknownlevel));
1782 #endif /* LARGE_SMB_OFF_T */
1783 DEBUG(10,("call_trans2setfilepathinfo: Set file allocation info for file %s to %.0f\n", fname, (double)newsize ));
1789 case SMB_SET_FILE_END_OF_FILE_INFO:
1791 size = IVAL(pdata,0);
1792 #ifdef LARGE_SMB_OFF_T
1793 size |= (((SMB_OFF_T)IVAL(pdata,4)) << 32);
1794 #else /* LARGE_SMB_OFF_T */
1795 if (IVAL(pdata,4) != 0) /* more than 32 bits? */
1796 return(ERROR(ERRDOS,ERRunknownlevel));
1797 #endif /* LARGE_SMB_OFF_T */
1798 DEBUG(10,("call_trans2setfilepathinfo: Set end of file info for file %s to %.0f\n", fname, (double)size ));
1802 case SMB_SET_FILE_DISPOSITION_INFO: /* Set delete on close for open file. */
1804 if ((tran_call == TRANSACT2_SETFILEINFO) && (fsp != NULL))
1806 BOOL delete_on_close = (CVAL(pdata,0) ? True : False);
1808 if(fsp->is_directory)
1810 fsp->directory_delete_on_close = delete_on_close;
1811 DEBUG(10, ("call_trans2setfilepathinfo: %s delete on close flag for fnum = %d, directory %s\n",
1812 delete_on_close ? "Added" : "Removed", fsp->fnum, fsp->fsp_name ));
1815 else if(fsp->stat_open)
1817 DEBUG(10, ("call_trans2setfilepathinfo: %s delete on close flag for fnum = %d, stat open %s\n",
1818 delete_on_close ? "Added" : "Removed", fsp->fnum, fsp->fsp_name ));
1824 * We can only set the delete on close flag if
1825 * the share mode contained ALLOW_SHARE_DELETE
1828 if(!GET_ALLOW_SHARE_DELETE(fsp->share_mode))
1829 return(ERROR(ERRDOS,ERRnoaccess));
1832 * If the flag has been set then
1833 * modify the share mode entry for all files we have open
1834 * on this device and inode to tell other smbds we have
1835 * changed the delete on close flag.
1838 if(delete_on_close && !GET_DELETE_ON_CLOSE_FLAG(fsp->share_mode))
1841 files_struct *iterate_fsp;
1842 SMB_DEV_T dev = fsp->dev;
1843 SMB_INO_T inode = fsp->inode;
1844 int num_share_modes;
1845 share_mode_entry *current_shares = NULL;
1847 if (lock_share_entry_fsp(fsp) == False)
1848 return(ERROR(ERRDOS,ERRnoaccess));
1851 * Before we allow this we need to ensure that all current opens
1852 * on the file have the GET_ALLOW_SHARE_DELETE flag set. If they
1853 * do not then we deny this (as we are essentially deleting the
1854 * file at this point.
1857 num_share_modes = get_share_modes(conn, dev, inode, ¤t_shares);
1858 for(i = 0; i < num_share_modes; i++)
1860 if(!GET_ALLOW_SHARE_DELETE(current_shares[i].share_mode))
1862 DEBUG(5,("call_trans2setfilepathinfo: refusing to set delete on close flag for fnum = %d, \
1863 file %s as a share exists that was not opened with FILE_DELETE access.\n",
1864 fsp->fnum, fsp->fsp_name ));
1869 unlock_share_entry_fsp(fsp);
1872 * current_shares was malloced by get_share_modes - free it here.
1875 free((char *)current_shares);
1878 * Even though share violation would be more appropriate here,
1879 * return ERRnoaccess as that's what NT does.
1882 return(ERROR(ERRDOS,ERRnoaccess));
1887 * current_shares was malloced by get_share_modes - free it here.
1890 free((char *)current_shares);
1892 DEBUG(10,("call_trans2setfilepathinfo: %s delete on close flag for fnum = %d, file %s\n",
1893 delete_on_close ? "Adding" : "Removing", fsp->fnum, fsp->fsp_name ));
1896 * Go through all files we have open on the same device and
1897 * inode (hanging off the same hash bucket) and set the DELETE_ON_CLOSE_FLAG.
1898 * Other smbd's that have this file open will have to fend for themselves. We
1899 * take care of this (rare) case in close_file(). See the comment there.
1902 for(iterate_fsp = file_find_di_first(dev, inode); iterate_fsp;
1903 iterate_fsp = file_find_di_next(iterate_fsp))
1905 int new_share_mode = (delete_on_close ?
1906 (iterate_fsp->share_mode | DELETE_ON_CLOSE_FLAG) :
1907 (iterate_fsp->share_mode & ~DELETE_ON_CLOSE_FLAG) );
1909 DEBUG(10,("call_trans2setfilepathinfo: Changing share mode for fnum %d, file %s \
1910 dev = %x, inode = %.0f from %x to %x\n",
1911 iterate_fsp->fnum, iterate_fsp->fsp_name, (unsigned int)dev,
1912 (double)inode, iterate_fsp->share_mode, new_share_mode ));
1914 if(modify_share_mode(iterate_fsp, new_share_mode, iterate_fsp->oplock_type)==False)
1915 DEBUG(0,("call_trans2setfilepathinfo: failed to change delete on close for fnum %d, \
1916 dev = %x, inode = %.0f\n", iterate_fsp->fnum, (unsigned int)dev, (double)inode));
1920 * Set the delete on close flag in the reference
1921 * counted struct. Delete when the last reference
1924 fsp->delete_on_close = delete_on_close;
1926 unlock_share_entry_fsp(fsp);
1928 DEBUG(10, ("call_trans2setfilepathinfo: %s delete on close flag for fnum = %d, file %s\n",
1929 delete_on_close ? "Added" : "Removed", fsp->fnum, fsp->fsp_name ));
1931 } /* end if(delete_on_close && !GET_DELETE_ON_CLOSE_FLAG(fsp->share_mode)) */
1932 } /* end if is_directory. */
1934 return(ERROR(ERRDOS,ERRunknownlevel));
1940 return(ERROR(ERRDOS,ERRunknownlevel));
1944 /* get some defaults (no modifications) if any info is zero or -1. */
1945 if (tvs.actime == (time_t)0 || tvs.actime == (time_t)-1)
1946 tvs.actime = sbuf.st_atime;
1948 if (tvs.modtime == (time_t)0 || tvs.modtime == (time_t)-1)
1949 tvs.modtime = sbuf.st_mtime;
1951 DEBUG(6,("actime: %s " , ctime(&tvs.actime)));
1952 DEBUG(6,("modtime: %s ", ctime(&tvs.modtime)));
1953 DEBUG(6,("size: %.0f ", (double)size));
1954 DEBUG(6,("mode: %x\n" , mode));
1956 if(!((info_level == SMB_SET_FILE_END_OF_FILE_INFO) ||
1957 (info_level == SMB_SET_FILE_ALLOCATION_INFO))) {
1959 * Only do this test if we are not explicitly
1960 * changing the size of a file.
1963 size = sbuf.st_size;
1966 /* Try and set the times, size and mode of this file -
1967 if they are different from the current values
1969 if (sbuf.st_mtime != tvs.modtime || sbuf.st_atime != tvs.actime) {
1972 * This was a setfileinfo on an open file.
1973 * NT does this a lot. It's actually pointless
1974 * setting the time here, as it will be overwritten
1975 * on the next write, so we save the request
1976 * away and will set it on file code. JRA.
1979 if (tvs.modtime != (time_t)0 && tvs.modtime != (time_t)-1) {
1980 DEBUG(10,("call_trans2setfilepathinfo: setting pending modtime to %s\n",
1981 ctime(&tvs.modtime) ));
1982 fsp->pending_modtime = tvs.modtime;
1987 DEBUG(10,("call_trans2setfilepathinfo: setting utimes to modified values.\n"));
1989 if(file_utime(conn, fname, &tvs)!=0)
1990 return(UNIXERROR(ERRDOS,ERRnoaccess));
1994 /* check the mode isn't different, before changing it */
1995 if ((mode != 0) && (mode != dos_mode(conn, fname, &sbuf))) {
1997 DEBUG(10,("call_trans2setfilepathinfo: file %s : setting dos mode %x\n",
2000 if(file_chmod(conn, fname, mode, NULL)) {
2001 DEBUG(2,("chmod of %s failed (%s)\n", fname, strerror(errno)));
2002 return(UNIXERROR(ERRDOS,ERRnoaccess));
2006 if(size != sbuf.st_size) {
2008 DEBUG(10,("call_trans2setfilepathinfo: file %s : setting new size to %.0f\n",
2009 fname, (double)size ));
2012 files_struct *new_fsp = NULL;
2013 int access_mode = 0;
2016 if(global_oplock_break) {
2017 /* Queue this file modify as we are the process of an oplock break. */
2019 DEBUG(2,("call_trans2setfilepathinfo: queueing message due to being "));
2020 DEBUGADD(2,( "in oplock break state.\n"));
2022 push_oplock_pending_smb_message(inbuf, length);
2026 new_fsp = open_file_shared(conn, fname, &sbuf,
2027 SET_OPEN_MODE(DOS_OPEN_RDWR),
2028 (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN),
2029 0, 0, &access_mode, &action);
2031 if (new_fsp == NULL)
2032 return(UNIXERROR(ERRDOS,ERRbadpath));
2033 vfs_set_filelen(new_fsp, size);
2034 close_file(new_fsp,True);
2036 vfs_set_filelen(fsp, size);
2042 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
2047 /****************************************************************************
2048 reply to a TRANS2_MKDIR (make directory with extended attributes).
2049 ****************************************************************************/
2050 static int call_trans2mkdir(connection_struct *conn,
2051 char *inbuf, char *outbuf, int length, int bufsize,
2052 char **pparams, char **ppdata)
2054 char *params = *pparams;
2057 SMB_STRUCT_STAT sbuf;
2058 BOOL bad_path = False;
2060 if (!CAN_WRITE(conn))
2061 return(ERROR(ERRSRV,ERRaccess));
2063 pstrcpy(directory, ¶ms[4]);
2065 DEBUG(3,("call_trans2mkdir : name = %s\n", directory));
2067 unix_convert(directory,conn,0,&bad_path,&sbuf);
2068 if (check_name(directory,conn))
2069 ret = vfs_mkdir(conn,directory,unix_mode(conn,aDIR,directory));
2073 DEBUG(5,("call_trans2mkdir error (%s)\n", strerror(errno)));
2074 if((errno == ENOENT) && bad_path)
2076 unix_ERR_class = ERRDOS;
2077 unix_ERR_code = ERRbadpath;
2079 return(UNIXERROR(ERRDOS,ERRnoaccess));
2082 /* Realloc the parameter and data sizes */
2083 params = Realloc(*pparams,2);
2084 if(params == NULL) {
2085 return(ERROR(ERRDOS,ERRnomem));
2091 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
2096 /****************************************************************************
2097 reply to a TRANS2_FINDNOTIFYFIRST (start monitoring a directory for changes)
2098 We don't actually do this - we just send a null response.
2099 ****************************************************************************/
2100 static int call_trans2findnotifyfirst(connection_struct *conn,
2101 char *inbuf, char *outbuf,
2102 int length, int bufsize,
2103 char **pparams, char **ppdata)
2105 static uint16 fnf_handle = 257;
2106 char *params = *pparams;
2107 uint16 info_level = SVAL(params,4);
2109 DEBUG(3,("call_trans2findnotifyfirst - info_level %d\n", info_level));
2117 return(ERROR(ERRDOS,ERRunknownlevel));
2120 /* Realloc the parameter and data sizes */
2121 params = Realloc(*pparams,6);
2122 if(params == NULL) {
2123 return(ERROR(ERRDOS,ERRnomem));
2127 SSVAL(params,0,fnf_handle);
2128 SSVAL(params,2,0); /* No changes */
2129 SSVAL(params,4,0); /* No EA errors */
2136 send_trans2_replies(outbuf, bufsize, params, 6, *ppdata, 0);
2141 /****************************************************************************
2142 reply to a TRANS2_FINDNOTIFYNEXT (continue monitoring a directory for
2143 changes). Currently this does nothing.
2144 ****************************************************************************/
2145 static int call_trans2findnotifynext(connection_struct *conn,
2146 char *inbuf, char *outbuf,
2147 int length, int bufsize,
2148 char **pparams, char **ppdata)
2150 char *params = *pparams;
2152 DEBUG(3,("call_trans2findnotifynext\n"));
2154 /* Realloc the parameter and data sizes */
2155 params = Realloc(*pparams,4);
2156 if(params == NULL) {
2157 return(ERROR(ERRDOS,ERRnomem));
2161 SSVAL(params,0,0); /* No changes */
2162 SSVAL(params,2,0); /* No EA errors */
2164 send_trans2_replies(outbuf, bufsize, params, 4, *ppdata, 0);
2169 /****************************************************************************
2170 reply to a TRANS2_GET_DFS_REFERRAL - Shirish Kalele <kalele@veritas.com>
2171 ****************************************************************************/
2172 static int call_trans2getdfsreferral(connection_struct *conn, char* inbuf,
2173 char* outbuf, int length, int bufsize,
2174 char** pparams, char** ppdata)
2176 char *params = *pparams;
2177 enum remote_arch_types ra_type = get_remote_arch();
2178 BOOL NT_arch = ((ra_type == RA_WINNT) || (ra_type == RA_WIN2K));
2181 int max_referral_level = SVAL(params,0);
2184 DEBUG(10,("call_trans2getdfsreferral\n"));
2186 if(!lp_host_msdfs())
2187 return(ERROR(ERRDOS,ERRbadfunc));
2189 /* if pathname is in UNICODE, convert to DOS */
2190 /* NT always sends in UNICODE, may not set UNICODE flag */
2191 if(NT_arch || (SVAL(inbuf,smb_flg2) & FLAGS2_UNICODE_STRINGS))
2193 unistr_to_dos(pathname, ¶ms[2], sizeof(pathname));
2194 DEBUG(10,("UNICODE referral for %s\n",pathname));
2197 pstrcpy(pathname,¶ms[2]);
2199 if((reply_size = setup_dfs_referral(pathname,max_referral_level,ppdata)) < 0)
2200 return(ERROR(ERRDOS,ERRbadfile));
2202 SSVAL(outbuf,smb_flg2,SVAL(outbuf,smb_flg2) | FLAGS2_UNICODE_STRINGS |
2203 FLAGS2_DFS_PATHNAMES);
2204 send_trans2_replies(outbuf,bufsize,0,0,*ppdata,reply_size);
2210 /****************************************************************************
2211 reply to a SMBfindclose (stop trans2 directory search)
2212 ****************************************************************************/
2213 int reply_findclose(connection_struct *conn,
2214 char *inbuf,char *outbuf,int length,int bufsize)
2217 int dptr_num=SVALS(inbuf,smb_vwv0);
2218 START_PROFILE(SMBfindclose);
2220 DEBUG(3,("reply_findclose, dptr_num = %d\n", dptr_num));
2222 dptr_close(&dptr_num);
2224 outsize = set_message(outbuf,0,0,True);
2226 DEBUG(3,("SMBfindclose dptr_num = %d\n", dptr_num));
2228 END_PROFILE(SMBfindclose);
2232 /****************************************************************************
2233 reply to a SMBfindnclose (stop FINDNOTIFYFIRST directory search)
2234 ****************************************************************************/
2235 int reply_findnclose(connection_struct *conn,
2236 char *inbuf,char *outbuf,int length,int bufsize)
2240 START_PROFILE(SMBfindnclose);
2242 dptr_num = SVAL(inbuf,smb_vwv0);
2244 DEBUG(3,("reply_findnclose, dptr_num = %d\n", dptr_num));
2246 /* We never give out valid handles for a
2247 findnotifyfirst - so any dptr_num is ok here.
2250 outsize = set_message(outbuf,0,0,True);
2252 DEBUG(3,("SMB_findnclose dptr_num = %d\n", dptr_num));
2254 END_PROFILE(SMBfindnclose);
2259 /****************************************************************************
2260 reply to a SMBtranss2 - just ignore it!
2261 ****************************************************************************/
2262 int reply_transs2(connection_struct *conn,
2263 char *inbuf,char *outbuf,int length,int bufsize)
2265 START_PROFILE(SMBtranss2);
2266 DEBUG(4,("Ignoring transs2 of length %d\n",length));
2267 END_PROFILE(SMBtranss2);
2271 /****************************************************************************
2272 reply to a SMBtrans2
2273 ****************************************************************************/
2274 int reply_trans2(connection_struct *conn,
2275 char *inbuf,char *outbuf,int length,int bufsize)
2278 unsigned int total_params = SVAL(inbuf, smb_tpscnt);
2279 unsigned int total_data =SVAL(inbuf, smb_tdscnt);
2281 unsigned int max_param_reply = SVAL(inbuf, smb_mprcnt);
2282 unsigned int max_data_reply = SVAL(inbuf, smb_mdrcnt);
2283 unsigned int max_setup_fields = SVAL(inbuf, smb_msrcnt);
2284 BOOL close_tid = BITSETW(inbuf+smb_flags,0);
2285 BOOL no_final_response = BITSETW(inbuf+smb_flags,1);
2286 int32 timeout = IVALS(inbuf,smb_timeout);
2288 unsigned int suwcnt = SVAL(inbuf, smb_suwcnt);
2289 unsigned int tran_call = SVAL(inbuf, smb_setup0);
2290 char *params = NULL, *data = NULL;
2291 int num_params, num_params_sofar, num_data, num_data_sofar;
2292 START_PROFILE(SMBtrans2);
2294 if(global_oplock_break && (tran_call == TRANSACT2_OPEN)) {
2295 /* Queue this open message as we are the process of an
2298 DEBUG(2,("reply_trans2: queueing message trans2open due to being "));
2299 DEBUGADD(2,( "in oplock break state.\n"));
2301 push_oplock_pending_smb_message(inbuf, length);
2302 END_PROFILE(SMBtrans2);
2306 if (IS_IPC(conn) && (tran_call != TRANSACT2_OPEN)
2307 && (tran_call != TRANSACT2_GET_DFS_REFERRAL)) {
2308 END_PROFILE(SMBtrans2);
2309 return(ERROR(ERRSRV,ERRaccess));
2312 outsize = set_message(outbuf,0,0,True);
2314 /* All trans2 messages we handle have smb_sucnt == 1 - ensure this
2315 is so as a sanity check */
2317 DEBUG(2,("Invalid smb_sucnt in trans2 call\n"));
2318 END_PROFILE(SMBtrans2);
2319 return(ERROR(ERRSRV,ERRerror));
2322 /* Allocate the space for the maximum needed parameters and data */
2323 if (total_params > 0)
2324 params = (char *)malloc(total_params);
2326 data = (char *)malloc(total_data);
2328 if ((total_params && !params) || (total_data && !data)) {
2329 DEBUG(2,("Out of memory in reply_trans2\n"));
2334 END_PROFILE(SMBtrans2);
2335 return(ERROR(ERRDOS,ERRnomem));
2338 /* Copy the param and data bytes sent with this request into
2339 the params buffer */
2340 num_params = num_params_sofar = SVAL(inbuf,smb_pscnt);
2341 num_data = num_data_sofar = SVAL(inbuf, smb_dscnt);
2343 if (num_params > total_params || num_data > total_data)
2344 exit_server("invalid params in reply_trans2");
2347 memcpy( params, smb_base(inbuf) + SVAL(inbuf, smb_psoff), num_params);
2349 memcpy( data, smb_base(inbuf) + SVAL(inbuf, smb_dsoff), num_data);
2351 if(num_data_sofar < total_data || num_params_sofar < total_params) {
2352 /* We need to send an interim response then receive the rest
2353 of the parameter/data bytes */
2354 outsize = set_message(outbuf,0,0,True);
2355 send_smb(smbd_server_fd(),outbuf);
2357 while (num_data_sofar < total_data ||
2358 num_params_sofar < total_params) {
2361 ret = receive_next_smb(inbuf,bufsize,SMB_SECONDARY_WAIT);
2364 (CVAL(inbuf, smb_com) != SMBtranss2)) || !ret) {
2365 outsize = set_message(outbuf,0,0,True);
2367 DEBUG(0,("reply_trans2: Invalid secondary trans2 packet\n"));
2369 DEBUG(0,("reply_trans2: %s in getting secondary trans2 response.\n",
2370 (smb_read_error == READ_ERROR) ? "error" : "timeout" ));
2375 END_PROFILE(SMBtrans2);
2376 return(ERROR(ERRSRV,ERRerror));
2379 /* Revise total_params and total_data in case
2380 they have changed downwards */
2381 total_params = SVAL(inbuf, smb_tpscnt);
2382 total_data = SVAL(inbuf, smb_tdscnt);
2383 num_params_sofar += (num_params = SVAL(inbuf,smb_spscnt));
2384 num_data_sofar += ( num_data = SVAL(inbuf, smb_sdscnt));
2385 if (num_params_sofar > total_params || num_data_sofar > total_data)
2386 exit_server("data overflow in trans2");
2388 memcpy( ¶ms[ SVAL(inbuf, smb_spsdisp)],
2389 smb_base(inbuf) + SVAL(inbuf, smb_spsoff), num_params);
2390 memcpy( &data[SVAL(inbuf, smb_sdsdisp)],
2391 smb_base(inbuf)+ SVAL(inbuf, smb_sdsoff), num_data);
2395 if (Protocol >= PROTOCOL_NT1) {
2396 SSVAL(outbuf,smb_flg2,SVAL(outbuf,smb_flg2) | 0x40); /* IS_LONG_NAME */
2399 /* Now we must call the relevant TRANS2 function */
2401 case TRANSACT2_OPEN:
2402 START_PROFILE_NESTED(Trans2_open);
2403 outsize = call_trans2open(conn,
2404 inbuf, outbuf, bufsize,
2406 END_PROFILE_NESTED(Trans2_open);
2409 case TRANSACT2_FINDFIRST:
2410 START_PROFILE_NESTED(Trans2_findfirst);
2411 outsize = call_trans2findfirst(conn, inbuf, outbuf,
2412 bufsize, ¶ms, &data);
2413 END_PROFILE_NESTED(Trans2_findfirst);
2416 case TRANSACT2_FINDNEXT:
2417 START_PROFILE_NESTED(Trans2_findnext);
2418 outsize = call_trans2findnext(conn, inbuf, outbuf,
2421 END_PROFILE_NESTED(Trans2_findnext);
2424 case TRANSACT2_QFSINFO:
2425 START_PROFILE_NESTED(Trans2_qfsinfo);
2426 outsize = call_trans2qfsinfo(conn, inbuf, outbuf,
2427 length, bufsize, ¶ms,
2429 END_PROFILE_NESTED(Trans2_qfsinfo);
2432 case TRANSACT2_SETFSINFO:
2433 START_PROFILE_NESTED(Trans2_setfsinfo);
2434 outsize = call_trans2setfsinfo(conn, inbuf, outbuf,
2437 END_PROFILE_NESTED(Trans2_setfsinfo);
2440 case TRANSACT2_QPATHINFO:
2441 case TRANSACT2_QFILEINFO:
2442 START_PROFILE_NESTED(Trans2_qpathinfo);
2443 outsize = call_trans2qfilepathinfo(conn, inbuf, outbuf,
2445 ¶ms, &data, total_data);
2446 END_PROFILE_NESTED(Trans2_qpathinfo);
2448 case TRANSACT2_SETPATHINFO:
2449 case TRANSACT2_SETFILEINFO:
2450 START_PROFILE_NESTED(Trans2_setpathinfo);
2451 outsize = call_trans2setfilepathinfo(conn, inbuf, outbuf,
2455 END_PROFILE_NESTED(Trans2_setpathinfo);
2458 case TRANSACT2_FINDNOTIFYFIRST:
2459 START_PROFILE_NESTED(Trans2_findnotifyfirst);
2460 outsize = call_trans2findnotifyfirst(conn, inbuf, outbuf,
2463 END_PROFILE_NESTED(Trans2_findnotifyfirst);
2466 case TRANSACT2_FINDNOTIFYNEXT:
2467 START_PROFILE_NESTED(Trans2_findnotifynext);
2468 outsize = call_trans2findnotifynext(conn, inbuf, outbuf,
2471 END_PROFILE_NESTED(Trans2_findnotifynext);
2473 case TRANSACT2_MKDIR:
2474 START_PROFILE_NESTED(Trans2_mkdir);
2475 outsize = call_trans2mkdir(conn, inbuf, outbuf, length,
2476 bufsize, ¶ms, &data);
2477 END_PROFILE_NESTED(Trans2_mkdir);
2480 case TRANSACT2_GET_DFS_REFERRAL:
2481 START_PROFILE_NESTED(Trans2_get_dfs_referral);
2482 outsize = call_trans2getdfsreferral(conn,inbuf,outbuf,length,
2483 bufsize, ¶ms, &data);
2484 END_PROFILE_NESTED(Trans2_get_dfs_referral);
2487 /* Error in request */
2488 DEBUG(2,("Unknown request %d in trans2 call\n", tran_call));
2493 END_PROFILE(SMBtrans2);
2494 return (ERROR(ERRSRV,ERRerror));
2497 /* As we do not know how many data packets will need to be
2498 returned here the various call_trans2xxxx calls
2499 must send their own. Thus a call_trans2xxx routine only
2500 returns a value other than -1 when it wants to send
2508 END_PROFILE(SMBtrans2);
2509 return outsize; /* If a correct response was needed the
2510 call_trans2xxx calls have already sent
2511 it. If outsize != -1 then it is returning */