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.
27 extern int DEBUGLEVEL;
29 extern BOOL case_sensitive;
31 extern int smb_read_error;
32 extern fstring local_machine;
33 extern int global_oplock_break;
34 extern uint32 global_client_caps;
36 /****************************************************************************
37 Send the required number of replies back.
38 We assume all fields other than the data fields are
39 set correctly for the type of call.
40 HACK ! Always assumes smb_setup field is zero.
41 ****************************************************************************/
42 static int send_trans2_replies(char *outbuf, int bufsize, char *params,
43 int paramsize, char *pdata, int datasize)
45 /* As we are using a protocol > LANMAN1 then the max_send
46 variable must have been set in the sessetupX call.
47 This takes precedence over the max_xmit field in the
48 global struct. These different max_xmit variables should
49 be merged as this is now too confusing */
52 int data_to_send = datasize;
53 int params_to_send = paramsize;
57 int params_sent_thistime, data_sent_thistime, total_sent_thistime;
58 int alignment_offset = 3;
59 int data_alignment_offset = 0;
61 /* Initially set the wcnt area to be 10 - this is true for all
63 set_message(outbuf,10,0,True);
65 /* If there genuinely are no parameters or data to send just send
67 if(params_to_send == 0 && data_to_send == 0)
69 send_smb(Client,outbuf);
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);
121 if(params_sent_thistime == 0)
123 SSVAL(outbuf,smb_proff,0);
124 SSVAL(outbuf,smb_prdisp,0);
128 /* smb_proff is the offset from the start of the SMB header to the
129 parameter bytes, however the first 4 bytes of outbuf are
130 the Netbios over TCP header. Thus use smb_base() to subtract
131 them from the calculation */
132 SSVAL(outbuf,smb_proff,((smb_buf(outbuf)+alignment_offset) - smb_base(outbuf)));
133 /* Absolute displacement of param bytes sent in this packet */
134 SSVAL(outbuf,smb_prdisp,pp - params);
137 SSVAL(outbuf,smb_drcnt, data_sent_thistime);
138 if(data_sent_thistime == 0)
140 SSVAL(outbuf,smb_droff,0);
141 SSVAL(outbuf,smb_drdisp, 0);
145 /* The offset of the data bytes is the offset of the
146 parameter bytes plus the number of parameters being sent this time */
147 SSVAL(outbuf,smb_droff,((smb_buf(outbuf)+alignment_offset) -
148 smb_base(outbuf)) + params_sent_thistime + data_alignment_offset);
149 SSVAL(outbuf,smb_drdisp, pd - pdata);
152 /* Copy the param bytes into the packet */
153 if(params_sent_thistime)
154 memcpy((smb_buf(outbuf)+alignment_offset),pp,params_sent_thistime);
155 /* Copy in the data bytes */
156 if(data_sent_thistime)
157 memcpy(smb_buf(outbuf)+alignment_offset+params_sent_thistime+
158 data_alignment_offset,pd,data_sent_thistime);
160 DEBUG(9,("t2_rep: params_sent_thistime = %d, data_sent_thistime = %d, useable_space = %d\n",
161 params_sent_thistime, data_sent_thistime, useable_space));
162 DEBUG(9,("t2_rep: params_to_send = %d, data_to_send = %d, paramsize = %d, datasize = %d\n",
163 params_to_send, data_to_send, paramsize, datasize));
165 /* Send the packet */
166 send_smb(Client,outbuf);
168 pp += params_sent_thistime;
169 pd += data_sent_thistime;
171 params_to_send -= params_sent_thistime;
172 data_to_send -= data_sent_thistime;
175 if(params_to_send < 0 || data_to_send < 0)
177 DEBUG(0,("send_trans2_replies failed sanity check pts = %d, dts = %d\n!!!",
178 params_to_send, data_to_send));
187 /****************************************************************************
188 reply to a TRANSACT2_OPEN
189 ****************************************************************************/
190 static int call_trans2open(connection_struct *conn, char *inbuf, char *outbuf,
192 char **pparams, char **ppdata)
194 char *params = *pparams;
195 int16 open_mode = SVAL(params, 2);
196 int16 open_attr = SVAL(params,6);
197 BOOL oplock_request = (((SVAL(params,0)|(1<<1))>>1) | ((SVAL(params,0)|(1<<2))>>1));
199 BOOL return_additional_info = BITSETW(params,0);
200 int16 open_sattr = SVAL(params, 4);
201 time_t open_time = make_unix_date3(params+8);
203 int16 open_ofun = SVAL(params,12);
204 int32 open_size = IVAL(params,14);
205 char *pname = ¶ms[28];
206 int16 namelen = strlen(pname)+1;
211 int fmode=0,mtime=0,rmode;
213 SMB_STRUCT_STAT sbuf;
215 BOOL bad_path = False;
218 StrnCpy(fname,pname,namelen);
220 DEBUG(3,("trans2open %s mode=%d attr=%d ofun=%d size=%d\n",
221 fname,open_mode, open_attr, open_ofun, open_size));
223 /* XXXX we need to handle passed times, sattr and flags */
225 unix_convert(fname,conn,0,&bad_path,NULL);
229 return(ERROR(ERRSRV,ERRnofids));
231 if (!check_name(fname,conn))
233 if((errno == ENOENT) && bad_path)
235 unix_ERR_class = ERRDOS;
236 unix_ERR_code = ERRbadpath;
239 return(UNIXERROR(ERRDOS,ERRnoaccess));
242 unixmode = unix_mode(conn,open_attr | aARCH, fname);
244 open_file_shared(fsp,conn,fname,open_mode,open_ofun,unixmode,
245 oplock_request, &rmode,&smb_action);
249 if((errno == ENOENT) && bad_path)
251 unix_ERR_class = ERRDOS;
252 unix_ERR_code = ERRbadpath;
255 return(UNIXERROR(ERRDOS,ERRnoaccess));
258 if (fsp->conn->vfs_ops.fstat(fsp->fd_ptr->fd,&sbuf) != 0) {
259 close_file(fsp,False);
260 return(UNIXERROR(ERRDOS,ERRnoaccess));
264 fmode = dos_mode(conn,fname,&sbuf);
265 mtime = sbuf.st_mtime;
268 close_file(fsp,False);
269 return(ERROR(ERRDOS,ERRnoaccess));
272 /* Realloc the size of parameters and data we will return */
273 params = *pparams = Realloc(*pparams, 28);
275 return(ERROR(ERRDOS,ERRnomem));
277 memset((char *)params,'\0',28);
278 SSVAL(params,0,fsp->fnum);
279 SSVAL(params,2,fmode);
280 put_dos_date2(params,4, mtime);
281 SIVAL(params,8, (uint32)size);
282 SSVAL(params,12,rmode);
284 if (oplock_request && lp_fake_oplocks(SNUM(conn))) {
285 smb_action |= EXTENDED_OPLOCK_GRANTED;
288 SSVAL(params,18,smb_action);
290 * WARNING - this may need to be changed if SMB_INO_T <> 4 bytes.
292 SIVAL(params,20,inode);
294 /* Send the required number of replies */
295 send_trans2_replies(outbuf, bufsize, params, 28, *ppdata, 0);
300 /****************************************************************************
301 get a level dependent lanman2 dir entry.
302 ****************************************************************************/
303 static BOOL get_lanman2_dir_entry(connection_struct *conn,
304 char *path_mask,int dirtype,int info_level,
305 int requires_resume_key,
306 BOOL dont_descend,char **ppdata,
307 char *base_data, int space_remaining,
308 BOOL *out_of_space, BOOL *got_exact_match,
313 SMB_STRUCT_STAT sbuf;
317 char *p, *pdata = *ppdata;
323 time_t mdate=0, adate=0, cdate=0;
325 BOOL isrootdir = (strequal(conn->dirpath,"./") ||
326 strequal(conn->dirpath,".") ||
327 strequal(conn->dirpath,"/"));
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, True);
378 if(!got_match && !is_8_3(fname, False)) {
381 * It turns out that NT matches wildcards against
382 * both long *and* short names. This may explain some
383 * of the wildcard wierdness from old DOS clients
384 * that some people have been seeing.... JRA.
388 pstrcpy( newname, fname);
389 name_map_mangle( newname, True, False, SNUM(conn));
390 if(!(got_match = *got_exact_match = exact_match(newname, mask, case_sensitive)))
391 got_match = mask_match(newname, mask, case_sensitive, True);
396 BOOL isdots = (strequal(fname,"..") || strequal(fname,"."));
397 if (dont_descend && !isdots)
400 if (isrootdir && isdots)
403 pstrcpy(pathreal,conn->dirpath);
405 pstrcat(pathreal,"/");
406 pstrcat(pathreal,dname);
407 if (conn->vfs_ops.stat(dos_to_unix(pathreal,False),&sbuf) != 0)
409 DEBUG(5,("get_lanman2_dir_entry:Couldn't stat [%s] (%s)\n",pathreal,strerror(errno)));
413 mode = dos_mode(conn,pathreal,&sbuf);
415 if (!dir_check_ftype(conn,mode,&sbuf,dirtype)) {
416 DEBUG(5,("[%s] attribs didn't match %x\n",fname,dirtype));
421 mdate = sbuf.st_mtime;
422 adate = sbuf.st_atime;
423 cdate = get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(conn)));
427 DEBUG(5,("get_lanman2_dir_entry found %s fname=%s\n",pathreal,fname));
433 name_map_mangle(fname,False,True,SNUM(conn));
438 nt_extmode = mode ? mode : FILE_ATTRIBUTE_NORMAL;
443 if(requires_resume_key) {
447 put_dos_date2(p,l1_fdateCreation,cdate);
448 put_dos_date2(p,l1_fdateLastAccess,adate);
449 put_dos_date2(p,l1_fdateLastWrite,mdate);
450 SIVAL(p,l1_cbFile,(uint32)size);
451 SIVAL(p,l1_cbFileAlloc,SMB_ROUNDUP(size,1024));
452 SSVAL(p,l1_attrFile,mode);
453 SCVAL(p,l1_cchName,strlen(fname));
454 pstrcpy(p + l1_achName, fname);
455 nameptr = p + l1_achName;
456 p += l1_achName + strlen(fname) + 1;
461 if(requires_resume_key) {
465 put_dos_date2(p,l2_fdateCreation,cdate);
466 put_dos_date2(p,l2_fdateLastAccess,adate);
467 put_dos_date2(p,l2_fdateLastWrite,mdate);
468 SIVAL(p,l2_cbFile,(uint32)size);
469 SIVAL(p,l2_cbFileAlloc,SMB_ROUNDUP(size,1024));
470 SSVAL(p,l2_attrFile,mode);
471 SIVAL(p,l2_cbList,0); /* No extended attributes */
472 SCVAL(p,l2_cchName,strlen(fname));
473 pstrcpy(p + l2_achName, fname);
474 nameptr = p + l2_achName;
475 p += l2_achName + strlen(fname) + 1;
480 put_dos_date2(p,4,cdate);
481 put_dos_date2(p,8,adate);
482 put_dos_date2(p,12,mdate);
483 SIVAL(p,16,(uint32)size);
484 SIVAL(p,20,SMB_ROUNDUP(size,1024));
487 CVAL(p,30) = strlen(fname);
488 pstrcpy(p+31, fname);
490 p += 31 + strlen(fname) + 1;
494 if(requires_resume_key) {
498 SIVAL(p,0,33+strlen(fname)+1);
499 put_dos_date2(p,4,cdate);
500 put_dos_date2(p,8,adate);
501 put_dos_date2(p,12,mdate);
502 SIVAL(p,16,(uint32)size);
503 SIVAL(p,20,SMB_ROUNDUP(size,1024));
505 CVAL(p,32) = strlen(fname);
506 pstrcpy(p + 33, fname);
508 p += 33 + strlen(fname) + 1;
511 case SMB_FIND_FILE_BOTH_DIRECTORY_INFO:
512 was_8_3 = is_8_3(fname, True);
513 len = 94+strlen(fname);
514 len = (len + 3) & ~3;
515 SIVAL(p,0,len); p += 4;
516 SIVAL(p,0,reskey); p += 4;
517 put_long_date(p,cdate); p += 8;
518 put_long_date(p,adate); p += 8;
519 put_long_date(p,mdate); p += 8;
520 put_long_date(p,mdate); p += 8;
524 SIVAL(p,0,nt_extmode); p += 4;
525 SIVAL(p,0,strlen(fname)); p += 4;
526 SIVAL(p,0,0); p += 4;
529 if (!name_map_mangle(p+2,True,True,SNUM(conn)))
534 SSVAL(p,0,strlen(p+2));
537 pstrcpy(p,fname); p += strlen(p);
541 case SMB_FIND_FILE_DIRECTORY_INFO:
542 len = 64+strlen(fname);
543 len = (len + 3) & ~3;
544 SIVAL(p,0,len); p += 4;
545 SIVAL(p,0,reskey); p += 4;
546 put_long_date(p,cdate); p += 8;
547 put_long_date(p,adate); p += 8;
548 put_long_date(p,mdate); p += 8;
549 put_long_date(p,mdate); p += 8;
553 SIVAL(p,0,nt_extmode); p += 4;
554 SIVAL(p,0,strlen(fname)); p += 4;
560 case SMB_FIND_FILE_FULL_DIRECTORY_INFO:
561 len = 68+strlen(fname);
562 len = (len + 3) & ~3;
563 SIVAL(p,0,len); p += 4;
564 SIVAL(p,0,reskey); p += 4;
565 put_long_date(p,cdate); p += 8;
566 put_long_date(p,adate); p += 8;
567 put_long_date(p,mdate); p += 8;
568 put_long_date(p,mdate); p += 8;
572 SIVAL(p,0,nt_extmode); p += 4;
573 SIVAL(p,0,strlen(fname)); p += 4;
574 SIVAL(p,0,0); p += 4;
579 case SMB_FIND_FILE_NAMES_INFO:
580 len = 12+strlen(fname);
581 len = (len + 3) & ~3;
582 SIVAL(p,0,len); p += 4;
583 SIVAL(p,0,reskey); p += 4;
584 SIVAL(p,0,strlen(fname)); p += 4;
594 if (PTR_DIFF(p,pdata) > space_remaining) {
595 /* Move the dirptr back to prev_dirpos */
596 SeekDir(conn->dirptr, prev_dirpos);
597 *out_of_space = True;
598 DEBUG(9,("get_lanman2_dir_entry: out of space\n"));
599 return False; /* Not finished - just out of space */
602 /* Setup the last_filename pointer, as an offset from base_data */
603 *last_name_off = PTR_DIFF(nameptr,base_data);
604 /* Advance the data pointer to the next slot */
610 /****************************************************************************
611 Convert the directory masks formated for the wire.
612 ****************************************************************************/
614 void mask_convert( char *mask)
617 * We know mask is a pstring.
623 if(p[1] != '"' && p[1] != '.') {
624 pstrcpy( expnd, p+1 );
627 safe_strcpy( p+1, expnd, sizeof(pstring) - (p - mask) - 2);
631 if (*p == '>') *p = '?';
632 if (*p == '"') *p = '.';
637 /****************************************************************************
638 Reply to a TRANS2_FINDFIRST.
639 ****************************************************************************/
641 static int call_trans2findfirst(connection_struct *conn,
642 char *inbuf, char *outbuf, int bufsize,
643 char **pparams, char **ppdata)
645 /* We must be careful here that we don't return more than the
646 allowed number of data bytes. If this means returning fewer than
647 maxentries then so be it. We assume that the redirector has
648 enough room for the fixed number of parameter bytes it has
650 uint32 max_data_bytes = SVAL(inbuf, smb_mdrcnt);
651 char *params = *pparams;
652 char *pdata = *ppdata;
653 int dirtype = SVAL(params,0);
654 int maxentries = SVAL(params,2);
655 BOOL close_after_first = BITSETW(params+4,0);
656 BOOL close_if_end = BITSETW(params+4,1);
657 BOOL requires_resume_key = BITSETW(params+4,2);
658 int info_level = SVAL(params,6);
666 BOOL finished = False;
667 BOOL dont_descend = False;
668 BOOL out_of_space = False;
670 BOOL bad_path = False;
672 *directory = *mask = 0;
674 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",
675 dirtype, maxentries, close_after_first, close_if_end, requires_resume_key,
676 info_level, max_data_bytes));
684 case SMB_FIND_FILE_DIRECTORY_INFO:
685 case SMB_FIND_FILE_FULL_DIRECTORY_INFO:
686 case SMB_FIND_FILE_NAMES_INFO:
687 case SMB_FIND_FILE_BOTH_DIRECTORY_INFO:
690 return(ERROR(ERRDOS,ERRunknownlevel));
693 pstrcpy(directory, params + 12); /* Complete directory path with
694 wildcard mask appended */
696 DEBUG(5,("path=%s\n",directory));
698 unix_convert(directory,conn,0,&bad_path,NULL);
699 if(!check_name(directory,conn)) {
700 if((errno == ENOENT) && bad_path)
702 unix_ERR_class = ERRDOS;
703 unix_ERR_code = ERRbadpath;
707 /* Ugly - NT specific hack - maybe not needed ? (JRA) */
708 if((errno == ENOTDIR) && (Protocol >= PROTOCOL_NT1) &&
709 (get_remote_arch() == RA_WINNT))
711 unix_ERR_class = ERRDOS;
712 unix_ERR_code = ERRbaddirectory;
716 return(UNIXERROR(ERRDOS,ERRbadpath));
719 p = strrchr(directory,'/');
721 pstrcpy(mask,directory);
722 pstrcpy(directory,"./");
728 DEBUG(5,("dir=%s, mask = %s\n",directory, mask));
730 pdata = *ppdata = Realloc(*ppdata, max_data_bytes + 1024);
732 return(ERROR(ERRDOS,ERRnomem));
733 memset((char *)pdata,'\0',max_data_bytes + 1024);
735 /* Realloc the params space */
736 params = *pparams = Realloc(*pparams, 10);
738 return(ERROR(ERRDOS,ERRnomem));
740 dptr_num = dptr_create(conn,directory, False, True ,SVAL(inbuf,smb_pid));
742 return(UNIXERROR(ERRDOS,ERRbadfile));
744 /* Convert the formatted mask. */
747 /* Save the wildcard match and attribs we are using on this directory -
748 needed as lanman2 assumes these are being saved between calls */
750 if(!(wcard = strdup(mask))) {
751 dptr_close(&dptr_num);
752 return(ERROR(ERRDOS,ERRnomem));
755 dptr_set_wcard(dptr_num, wcard);
756 dptr_set_attr(dptr_num, dirtype);
758 DEBUG(4,("dptr_num is %d, wcard = %s, attr = %d\n",dptr_num, wcard, dirtype));
760 /* We don't need to check for VOL here as this is returned by
761 a different TRANS2 call. */
763 DEBUG(8,("dirpath=<%s> dontdescend=<%s>\n",
764 conn->dirpath,lp_dontdescend(SNUM(conn))));
765 if (in_list(conn->dirpath,lp_dontdescend(SNUM(conn)),case_sensitive))
769 space_remaining = max_data_bytes;
770 out_of_space = False;
772 for (i=0;(i<maxentries) && !finished && !out_of_space;i++)
774 BOOL got_exact_match;
776 /* this is a heuristic to avoid seeking the dirptr except when
777 absolutely necessary. It allows for a filename of about 40 chars */
778 if (space_remaining < DIRLEN_GUESS && numentries > 0)
785 finished = !get_lanman2_dir_entry(conn,mask,dirtype,info_level,
786 requires_resume_key,dont_descend,
787 &p,pdata,space_remaining, &out_of_space, &got_exact_match,
791 if (finished && out_of_space)
794 if (!finished && !out_of_space)
798 * As an optimisation if we know we aren't looking
799 * for a wildcard name (ie. the name matches the wildcard exactly)
800 * then we can finish on any (first) match.
801 * This speeds up large directory searches. JRA.
807 space_remaining = max_data_bytes - PTR_DIFF(p,pdata);
810 /* Check if we can close the dirptr */
811 if(close_after_first || (finished && close_if_end))
813 DEBUG(5,("call_trans2findfirst - (2) closing dptr_num %d\n", dptr_num));
814 dptr_close(&dptr_num);
818 * If there are no matching entries we must return ERRDOS/ERRbadfile -
819 * from observation of NT.
824 dptr_close(&dptr_num);
825 return(ERROR(ERRDOS,ERRbadfile));
828 /* At this point pdata points to numentries directory entries. */
830 /* Set up the return parameter block */
831 SSVAL(params,0,dptr_num);
832 SSVAL(params,2,numentries);
833 SSVAL(params,4,finished);
834 SSVAL(params,6,0); /* Never an EA error */
835 SSVAL(params,8,last_name_off);
837 send_trans2_replies( outbuf, bufsize, params, 10, pdata, PTR_DIFF(p,pdata));
839 if ((! *directory) && dptr_path(dptr_num))
840 slprintf(directory,sizeof(directory)-1, "(%s)",dptr_path(dptr_num));
842 DEBUG( 4, ( "%s mask=%s directory=%s dirtype=%d numentries=%d\n",
843 smb_fn_name(CVAL(inbuf,smb_com)),
844 mask, directory, dirtype, numentries ) );
847 * Force a name mangle here to ensure that the
848 * mask as an 8.3 name is top of the mangled cache.
849 * The reasons for this are subtle. Don't remove
850 * this code unless you know what you are doing
851 * (see PR#13758). JRA.
854 if(!is_8_3( mask, False))
855 name_map_mangle(mask, True, True, SNUM(conn));
861 /****************************************************************************
862 reply to a TRANS2_FINDNEXT
863 ****************************************************************************/
864 static int call_trans2findnext(connection_struct *conn,
865 char *inbuf, char *outbuf,
866 int length, int bufsize,
867 char **pparams, char **ppdata)
869 /* We must be careful here that we don't return more than the
870 allowed number of data bytes. If this means returning fewer than
871 maxentries then so be it. We assume that the redirector has
872 enough room for the fixed number of parameter bytes it has
874 int max_data_bytes = SVAL(inbuf, smb_mdrcnt);
875 char *params = *pparams;
876 char *pdata = *ppdata;
877 int dptr_num = SVAL(params,0);
878 int maxentries = SVAL(params,2);
879 uint16 info_level = SVAL(params,4);
880 uint32 resume_key = IVAL(params,6);
881 BOOL close_after_request = BITSETW(params+10,0);
882 BOOL close_if_end = BITSETW(params+10,1);
883 BOOL requires_resume_key = BITSETW(params+10,2);
884 BOOL continue_bit = BITSETW(params+10,3);
891 int i, last_name_off=0;
892 BOOL finished = False;
893 BOOL dont_descend = False;
894 BOOL out_of_space = False;
897 *mask = *directory = *resume_name = 0;
899 pstrcpy( resume_name, params+12);
901 DEBUG(3,("call_trans2findnext: dirhandle = %d, max_data_bytes = %d, maxentries = %d, \
902 close_after_request=%d, close_if_end = %d requires_resume_key = %d \
903 resume_key = %d resume name = %s continue=%d level = %d\n",
904 dptr_num, max_data_bytes, maxentries, close_after_request, close_if_end,
905 requires_resume_key, resume_key, resume_name, continue_bit, info_level));
913 case SMB_FIND_FILE_DIRECTORY_INFO:
914 case SMB_FIND_FILE_FULL_DIRECTORY_INFO:
915 case SMB_FIND_FILE_NAMES_INFO:
916 case SMB_FIND_FILE_BOTH_DIRECTORY_INFO:
919 return(ERROR(ERRDOS,ERRunknownlevel));
922 pdata = *ppdata = Realloc( *ppdata, max_data_bytes + 1024);
924 return(ERROR(ERRDOS,ERRnomem));
925 memset((char *)pdata,'\0',max_data_bytes + 1024);
927 /* Realloc the params space */
928 params = *pparams = Realloc(*pparams, 6*SIZEOFWORD);
930 return(ERROR(ERRDOS,ERRnomem));
932 /* Check that the dptr is valid */
933 if(!(conn->dirptr = dptr_fetch_lanman2(dptr_num)))
934 return(ERROR(ERRDOS,ERRnofiles));
936 string_set(&conn->dirpath,dptr_path(dptr_num));
938 /* Get the wildcard mask from the dptr */
939 if((p = dptr_wcard(dptr_num))== NULL) {
940 DEBUG(2,("dptr_num %d has no wildcard\n", dptr_num));
941 return (ERROR(ERRDOS,ERRnofiles));
944 pstrcpy(directory,conn->dirpath);
946 /* Get the attr mask from the dptr */
947 dirtype = dptr_attr(dptr_num);
949 DEBUG(3,("dptr_num is %d, mask = %s, attr = %x, dirptr=(0x%lX,%d)\n",
950 dptr_num, mask, dirtype,
952 TellDir(conn->dirptr)));
954 /* We don't need to check for VOL here as this is returned by
955 a different TRANS2 call. */
957 DEBUG(8,("dirpath=<%s> dontdescend=<%s>\n",conn->dirpath,lp_dontdescend(SNUM(conn))));
958 if (in_list(conn->dirpath,lp_dontdescend(SNUM(conn)),case_sensitive))
962 space_remaining = max_data_bytes;
963 out_of_space = False;
966 * Seek to the correct position. We no longer use the resume key but
967 * depend on the last file name instead.
969 if(requires_resume_key && *resume_name && !continue_bit)
972 * Fix for NT redirector problem triggered by resume key indexes
973 * changing between directory scans. We now return a resume key of 0
974 * and instead look for the filename to continue from (also given
975 * to us by NT/95/smbfs/smbclient). If no other scans have been done between the
976 * findfirst/findnext (as is usual) then the directory pointer
977 * should already be at the correct place. Check this by scanning
978 * backwards looking for an exact (ie. case sensitive) filename match.
979 * If we get to the beginning of the directory and haven't found it then scan
980 * forwards again looking for a match. JRA.
983 int current_pos, start_pos;
985 void *dirptr = conn->dirptr;
986 start_pos = TellDir(dirptr);
987 for(current_pos = start_pos; current_pos >= 0; current_pos--)
989 DEBUG(7,("call_trans2findnext: seeking to pos %d\n", current_pos));
991 SeekDir(dirptr, current_pos);
992 dname = ReadDirName(dirptr);
995 * Remember, name_map_mangle is called by
996 * get_lanman2_dir_entry(), so the resume name
997 * could be mangled. Ensure we do the same
1002 name_map_mangle( dname, False, True, SNUM(conn));
1004 if(dname && strcsequal( resume_name, dname))
1006 SeekDir(dirptr, current_pos+1);
1007 DEBUG(7,("call_trans2findnext: got match at pos %d\n", current_pos+1 ));
1013 * Scan forward from start if not found going backwards.
1018 DEBUG(7,("call_trans2findnext: notfound: seeking to pos %d\n", start_pos));
1019 SeekDir(dirptr, start_pos);
1020 for(current_pos = start_pos; (dname = ReadDirName(dirptr)) != NULL; SeekDir(dirptr,++current_pos))
1023 * Remember, name_map_mangle is called by
1024 * get_lanman2_dir_entry(), so the resume name
1025 * could be mangled. Ensure we do the same
1030 name_map_mangle( dname, False, True, SNUM(conn));
1032 if(dname && strcsequal( resume_name, dname))
1034 SeekDir(dirptr, current_pos+1);
1035 DEBUG(7,("call_trans2findnext: got match at pos %d\n", current_pos+1 ));
1039 } /* end if current_pos */
1040 } /* end if requires_resume_key && !continue_bit */
1042 for (i=0;(i<(int)maxentries) && !finished && !out_of_space ;i++)
1044 BOOL got_exact_match;
1046 /* this is a heuristic to avoid seeking the dirptr except when
1047 absolutely necessary. It allows for a filename of about 40 chars */
1048 if (space_remaining < DIRLEN_GUESS && numentries > 0)
1050 out_of_space = True;
1055 finished = !get_lanman2_dir_entry(conn,mask,dirtype,info_level,
1056 requires_resume_key,dont_descend,
1057 &p,pdata,space_remaining, &out_of_space, &got_exact_match,
1061 if (finished && out_of_space)
1064 if (!finished && !out_of_space)
1068 * As an optimisation if we know we aren't looking
1069 * for a wildcard name (ie. the name matches the wildcard exactly)
1070 * then we can finish on any (first) match.
1071 * This speeds up large directory searches. JRA.
1077 space_remaining = max_data_bytes - PTR_DIFF(p,pdata);
1080 /* Check if we can close the dirptr */
1081 if(close_after_request || (finished && close_if_end))
1083 DEBUG(5,("call_trans2findnext: closing dptr_num = %d\n", dptr_num));
1084 dptr_close(&dptr_num); /* This frees up the saved mask */
1088 /* Set up the return parameter block */
1089 SSVAL(params,0,numentries);
1090 SSVAL(params,2,finished);
1091 SSVAL(params,4,0); /* Never an EA error */
1092 SSVAL(params,6,last_name_off);
1094 send_trans2_replies( outbuf, bufsize, params, 8, pdata, PTR_DIFF(p,pdata));
1096 if ((! *directory) && dptr_path(dptr_num))
1097 slprintf(directory,sizeof(directory)-1, "(%s)",dptr_path(dptr_num));
1099 DEBUG( 3, ( "%s mask=%s directory=%s dirtype=%d numentries=%d\n",
1100 smb_fn_name(CVAL(inbuf,smb_com)),
1101 mask, directory, dirtype, numentries ) );
1106 /****************************************************************************
1107 reply to a TRANS2_QFSINFO (query filesystem info)
1108 ****************************************************************************/
1110 static int call_trans2qfsinfo(connection_struct *conn,
1111 char *inbuf, char *outbuf,
1112 int length, int bufsize,
1113 char **pparams, char **ppdata)
1115 int max_data_bytes = SVAL(inbuf, smb_mdrcnt);
1116 char *pdata = *ppdata;
1117 char *params = *pparams;
1118 uint16 info_level = SVAL(params,0);
1121 char *vname = volume_label(SNUM(conn));
1122 int snum = SNUM(conn);
1123 char *fstype = lp_fstype(SNUM(conn));
1125 DEBUG(3,("call_trans2qfsinfo: level = %d\n", info_level));
1127 if(conn->vfs_ops.stat(".",&st)!=0) {
1128 DEBUG(2,("call_trans2qfsinfo: stat of . failed (%s)\n", strerror(errno)));
1129 return (ERROR(ERRSRV,ERRinvdevice));
1132 pdata = *ppdata = Realloc(*ppdata, max_data_bytes + 1024);
1133 memset((char *)pdata,'\0',max_data_bytes + 1024);
1139 SMB_BIG_UINT dfree,dsize,bsize;
1141 conn->vfs_ops.disk_free(".",False,&bsize,&dfree,&dsize);
1142 SIVAL(pdata,l1_idFileSystem,st.st_dev);
1143 SIVAL(pdata,l1_cSectorUnit,bsize/512);
1144 SIVAL(pdata,l1_cUnit,dsize);
1145 SIVAL(pdata,l1_cUnitAvail,dfree);
1146 SSVAL(pdata,l1_cbSector,512);
1147 DEBUG(5,("call_trans2qfsinfo : bsize=%u, id=%x, cSectorUnit=%u, cUnit=%u, cUnitAvail=%u, cbSector=%d\n",
1148 (unsigned int)bsize, (unsigned int)st.st_dev, ((unsigned int)bsize)/512, (unsigned int)dsize,
1149 (unsigned int)dfree, 512));
1154 /* Return volume name */
1155 int volname_len = MIN(strlen(vname),11);
1156 data_len = l2_vol_szVolLabel + volname_len + 1;
1158 * Add volume serial number - hash of a combination of
1159 * the called hostname and the service name.
1161 SIVAL(pdata,0,str_checksum(lp_servicename(snum)) ^ (str_checksum(local_machine)<<16) );
1162 SCVAL(pdata,l2_vol_cch,volname_len);
1163 StrnCpy(pdata+l2_vol_szVolLabel,vname,volname_len);
1164 DEBUG(5,("call_trans2qfsinfo : time = %x, namelen = %d, name = %s\n",
1165 (unsigned)st.st_ctime, volname_len,
1166 pdata+l2_vol_szVolLabel));
1169 case SMB_QUERY_FS_ATTRIBUTE_INFO:
1172 SIVAL(pdata,0,FILE_CASE_PRESERVED_NAMES|FILE_CASE_SENSITIVE_SEARCH|
1173 lp_nt_acl_support() ? FILE_PERSISTENT_ACLS : 0); /* FS ATTRIBUTES */
1174 #if 0 /* Old code. JRA. */
1175 SIVAL(pdata,0,0x4006); /* FS ATTRIBUTES == long filenames supported? */
1176 #endif /* Old code. */
1178 SIVAL(pdata,4,128); /* Max filename component length */
1179 fstype_len = dos_PutUniCode(pdata+12,unix_to_dos(fstype,False),sizeof(pstring)/2);
1180 SIVAL(pdata,8,fstype_len);
1181 data_len = 12 + fstype_len;
1182 SSVAL(outbuf,smb_flg2,SVAL(outbuf,smb_flg2)|FLAGS2_UNICODE_STRINGS);
1185 case SMB_QUERY_FS_LABEL_INFO:
1186 data_len = 4 + strlen(vname);
1187 SIVAL(pdata,0,strlen(vname));
1188 pstrcpy(pdata+4,vname);
1190 case SMB_QUERY_FS_VOLUME_INFO:
1193 * Add volume serial number - hash of a combination of
1194 * the called hostname and the service name.
1196 SIVAL(pdata,8,str_checksum(lp_servicename(snum)) ^
1197 (str_checksum(local_machine)<<16));
1199 /* NT4 always serves this up as unicode but expects it to be
1200 * delivered as ascii! (tridge && JRA)
1202 if (global_client_caps & CAP_NT_SMBS) {
1203 data_len = 18 + strlen(vname);
1204 SIVAL(pdata,12,strlen(vname));
1205 pstrcpy(pdata+18,vname);
1207 data_len = 18 + 2*strlen(vname);
1208 SIVAL(pdata,12,strlen(vname)*2);
1209 dos_PutUniCode(pdata+18,unix_to_dos(vname,False),sizeof(pstring)/2);
1212 DEBUG(5,("call_trans2qfsinfo : SMB_QUERY_FS_VOLUME_INFO namelen = %d, vol = %s\n",
1213 (int)strlen(vname),vname));
1215 case SMB_QUERY_FS_SIZE_INFO:
1217 SMB_BIG_UINT dfree,dsize,bsize;
1219 conn->vfs_ops.disk_free(".",False,&bsize,&dfree,&dsize);
1220 SBIG_UINT(pdata,0,dsize);
1221 SBIG_UINT(pdata,8,dfree);
1222 SIVAL(pdata,16,bsize/512);
1223 SIVAL(pdata,20,512);
1226 case SMB_QUERY_FS_DEVICE_INFO:
1228 SIVAL(pdata,0,0); /* dev type */
1229 SIVAL(pdata,4,0); /* characteristics */
1231 case SMB_MAC_QUERY_FS_INFO:
1233 * Thursby MAC extension... ONLY on NTFS filesystems
1234 * once we do streams then we don't need this
1236 if (strequal(lp_fstype(SNUM(conn)),"NTFS")) {
1238 SIVAL(pdata,84,0x100); /* Don't support mac... */
1243 return(ERROR(ERRDOS,ERRunknownlevel));
1247 send_trans2_replies( outbuf, bufsize, params, 0, pdata, data_len);
1249 DEBUG( 4, ( "%s info_level = %d\n",
1250 smb_fn_name(CVAL(inbuf,smb_com)), info_level) );
1255 /****************************************************************************
1256 reply to a TRANS2_SETFSINFO (set filesystem info)
1257 ****************************************************************************/
1258 static int call_trans2setfsinfo(connection_struct *conn,
1259 char *inbuf, char *outbuf, int length,
1261 char **pparams, char **ppdata)
1263 /* Just say yes we did it - there is nothing that
1264 can be set here so it doesn't matter. */
1266 DEBUG(3,("call_trans2setfsinfo\n"));
1268 if (!CAN_WRITE(conn))
1269 return(ERROR(ERRSRV,ERRaccess));
1271 outsize = set_message(outbuf,10,0,True);
1276 /****************************************************************************
1277 Reply to a TRANS2_QFILEPATHINFO or TRANSACT2_QFILEINFO (query file info by
1278 file name or file id).
1279 ****************************************************************************/
1281 static int call_trans2qfilepathinfo(connection_struct *conn,
1282 char *inbuf, char *outbuf, int length,
1284 char **pparams,char **ppdata,
1287 int max_data_bytes = SVAL(inbuf, smb_mdrcnt);
1288 char *params = *pparams;
1289 char *pdata = *ppdata;
1290 uint16 tran_call = SVAL(inbuf, smb_setup0);
1294 unsigned int data_size;
1295 SMB_STRUCT_STAT sbuf;
1301 BOOL bad_path = False;
1302 BOOL delete_pending = False;
1304 if (tran_call == TRANSACT2_QFILEINFO) {
1305 files_struct *fsp = file_fsp(params,0);
1306 info_level = SVAL(params,2);
1308 DEBUG(3,("call_trans2qfilepathinfo: TRANSACT2_QFILEINFO: level = %d\n", info_level));
1310 if(fsp && fsp->open && (fsp->is_directory || fsp->stat_open)) {
1312 * This is actually a QFILEINFO on a directory
1313 * handle (returned from an NT SMB). NT5.0 seems
1314 * to do this call. JRA.
1316 fname = fsp->fsp_name;
1317 unix_convert(fname,conn,0,&bad_path,&sbuf);
1318 if (!check_name(fname,conn) ||
1319 (!VALID_STAT(sbuf) && conn->vfs_ops.stat(dos_to_unix(fname,False),&sbuf))) {
1320 DEBUG(3,("fileinfo of %s failed (%s)\n",fname,strerror(errno)));
1321 if((errno == ENOENT) && bad_path)
1323 unix_ERR_class = ERRDOS;
1324 unix_ERR_code = ERRbadpath;
1326 return(UNIXERROR(ERRDOS,ERRbadpath));
1329 delete_pending = fsp->directory_delete_on_close;
1333 * Original code - this is an open file.
1335 CHECK_FSP(fsp,conn);
1338 fname = fsp->fsp_name;
1339 if (fsp->conn->vfs_ops.fstat(fsp->fd_ptr->fd,&sbuf) != 0) {
1340 DEBUG(3,("fstat of fnum %d failed (%s)\n",fsp->fnum, strerror(errno)));
1341 return(UNIXERROR(ERRDOS,ERRbadfid));
1343 if((pos = fsp->conn->vfs_ops.lseek(fsp->fd_ptr->fd,0,SEEK_CUR)) == -1)
1344 return(UNIXERROR(ERRDOS,ERRnoaccess));
1346 delete_pending = fsp->fd_ptr->delete_on_close;
1350 info_level = SVAL(params,0);
1352 DEBUG(3,("call_trans2qfilepathinfo: TRANSACT2_QPATHINFO: level = %d\n", info_level));
1355 pstrcpy(fname,¶ms[6]);
1356 unix_convert(fname,conn,0,&bad_path,&sbuf);
1357 if (!check_name(fname,conn) ||
1358 (!VALID_STAT(sbuf) && conn->vfs_ops.stat(dos_to_unix(fname,False),&sbuf))) {
1359 DEBUG(3,("fileinfo of %s failed (%s)\n",fname,strerror(errno)));
1360 if((errno == ENOENT) && bad_path)
1362 unix_ERR_class = ERRDOS;
1363 unix_ERR_code = ERRbadpath;
1365 return(UNIXERROR(ERRDOS,ERRbadpath));
1370 DEBUG(3,("call_trans2qfilepathinfo %s level=%d call=%d total_data=%d\n",
1371 fname,info_level,tran_call,total_data));
1373 p = strrchr(fname,'/');
1379 mode = dos_mode(conn,fname,&sbuf);
1380 size = sbuf.st_size;
1381 if (mode & aDIR) size = 0;
1383 /* from now on we only want the part after the / */
1386 params = *pparams = Realloc(*pparams,2);
1387 memset((char *)params,'\0',2);
1388 data_size = max_data_bytes + 1024;
1389 pdata = *ppdata = Realloc(*ppdata, data_size);
1391 if (total_data > 0 && IVAL(pdata,0) == total_data) {
1392 /* uggh, EAs for OS2 */
1393 DEBUG(4,("Rejecting EA request with total_data=%d\n",total_data));
1394 return(ERROR(ERRDOS,ERROR_EAS_NOT_SUPPORTED));
1397 memset((char *)pdata,'\0',data_size);
1401 case SMB_INFO_STANDARD:
1402 case SMB_INFO_QUERY_EA_SIZE:
1403 data_size = (info_level==1?22:26);
1404 put_dos_date2(pdata,l1_fdateCreation,get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(conn))));
1405 put_dos_date2(pdata,l1_fdateLastAccess,sbuf.st_atime);
1406 put_dos_date2(pdata,l1_fdateLastWrite,sbuf.st_mtime); /* write time */
1407 SIVAL(pdata,l1_cbFile,(uint32)size);
1408 SIVAL(pdata,l1_cbFileAlloc,SMB_ROUNDUP(size,1024));
1409 SSVAL(pdata,l1_attrFile,mode);
1410 SIVAL(pdata,l1_attrFile+2,4); /* this is what OS2 does */
1413 case SMB_INFO_QUERY_EAS_FROM_LIST:
1415 put_dos_date2(pdata,0,get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(conn))));
1416 put_dos_date2(pdata,4,sbuf.st_atime);
1417 put_dos_date2(pdata,8,sbuf.st_mtime);
1418 SIVAL(pdata,12,(uint32)size);
1419 SIVAL(pdata,16,SMB_ROUNDUP(size,1024));
1420 SIVAL(pdata,20,mode);
1423 case SMB_INFO_QUERY_ALL_EAS:
1425 SIVAL(pdata,0,data_size);
1429 return(ERROR(ERRDOS,ERRbadfunc)); /* os/2 needs this */
1431 case SMB_QUERY_FILE_BASIC_INFO:
1432 data_size = 36; /* w95 returns 40 bytes not 36 - why ?. */
1433 put_long_date(pdata,get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(conn))));
1434 put_long_date(pdata+8,sbuf.st_atime);
1435 put_long_date(pdata+16,sbuf.st_mtime); /* write time */
1436 put_long_date(pdata+24,sbuf.st_mtime); /* change time */
1437 SIVAL(pdata,32,mode);
1439 DEBUG(5,("SMB_QFBI - "));
1441 time_t create_time = get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(conn)));
1442 DEBUG(5,("create: %s ", ctime(&create_time)));
1444 DEBUG(5,("access: %s ", ctime(&sbuf.st_atime)));
1445 DEBUG(5,("write: %s ", ctime(&sbuf.st_mtime)));
1446 DEBUG(5,("change: %s ", ctime(&sbuf.st_mtime)));
1447 DEBUG(5,("mode: %x\n", mode));
1451 case SMB_QUERY_FILE_STANDARD_INFO:
1453 SOFF_T(pdata,0,size);
1454 SOFF_T(pdata,8,size);
1455 SIVAL(pdata,16,sbuf.st_nlink);
1457 CVAL(pdata,21) = (mode&aDIR)?1:0;
1460 case SMB_QUERY_FILE_EA_INFO:
1464 /* Get the 8.3 name - used if NT SMB was negotiated. */
1465 case SMB_QUERY_FILE_ALT_NAME_INFO:
1468 pstrcpy(short_name,p);
1469 /* Mangle if not already 8.3 */
1470 if(!is_8_3(short_name, True))
1472 if(!name_map_mangle(short_name,True,True,SNUM(conn)))
1475 strupper(short_name);
1476 l = strlen(short_name);
1477 dos_PutUniCode(pdata + 4, unix_to_dos(short_name,False),sizeof(pstring)*2);
1478 data_size = 4 + (2*l);
1483 case SMB_QUERY_FILE_NAME_INFO:
1485 * The first part of this code is essential
1486 * to get security descriptors to work on mapped
1487 * drives. Don't ask how I discovered this unless
1488 * you like hearing about me suffering.... :-). JRA.
1490 if(strequal(".", fname) && (global_client_caps & CAP_UNICODE)) {
1492 SSVAL(outbuf,smb_flg2,SVAL(outbuf,smb_flg2)|FLAGS2_UNICODE_STRINGS);
1493 dos_PutUniCode(pdata + 4, unix_to_dos("\\",False),sizeof(pstring)*2);
1495 pstrcpy(pdata+4,fname);
1501 case SMB_QUERY_FILE_ALLOCATION_INFO:
1502 case SMB_QUERY_FILE_END_OF_FILEINFO:
1504 SOFF_T(pdata,0,size);
1507 case SMB_QUERY_FILE_ALL_INFO:
1508 put_long_date(pdata,get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(conn))));
1509 put_long_date(pdata+8,sbuf.st_atime);
1510 put_long_date(pdata+16,sbuf.st_mtime); /* write time */
1511 put_long_date(pdata+24,sbuf.st_mtime); /* change time */
1512 SIVAL(pdata,32,mode);
1514 SOFF_T(pdata,0,size);
1515 SOFF_T(pdata,8,size);
1516 SIVAL(pdata,16,sbuf.st_nlink);
1517 CVAL(pdata,20) = delete_pending;
1518 CVAL(pdata,21) = (mode&aDIR)?1:0;
1520 SINO_T(pdata,0,(SMB_INO_T)sbuf.st_ino);
1521 pdata += 8; /* index number */
1522 pdata += 4; /* EA info */
1524 SIVAL(pdata,0,0xA9);
1526 SIVAL(pdata,0,0xd01BF);
1528 SOFF_T(pdata,0,pos); /* current offset */
1530 SIVAL(pdata,0,mode); /* is this the right sort of mode info? */
1532 pdata += 4; /* alignment */
1534 pstrcpy(pdata+4,fname);
1536 data_size = PTR_DIFF(pdata,(*ppdata));
1540 /* NT4 server just returns "invalid query" to this - if we try to answer
1541 it then NTws gets a BSOD! (tridge) */
1542 case SMB_QUERY_FILE_STREAM_INFO:
1545 SIVAL(pdata,4,size);
1546 SIVAL(pdata,12,size);
1548 pstrcpy(pdata+24,fname);
1553 return(ERROR(ERRDOS,ERRunknownlevel));
1556 send_trans2_replies( outbuf, bufsize, params, 2, *ppdata, data_size);
1561 /****************************************************************************
1562 reply to a TRANS2_SETFILEINFO (set file info by fileid)
1563 ****************************************************************************/
1564 static int call_trans2setfilepathinfo(connection_struct *conn,
1565 char *inbuf, char *outbuf, int length,
1566 int bufsize, char **pparams,
1567 char **ppdata, int total_data)
1569 char *params = *pparams;
1570 char *pdata = *ppdata;
1571 uint16 tran_call = SVAL(inbuf, smb_setup0);
1580 BOOL bad_path = False;
1581 files_struct *fsp = NULL;
1583 if (!CAN_WRITE(conn))
1584 return(ERROR(ERRSRV,ERRaccess));
1586 if (tran_call == TRANSACT2_SETFILEINFO) {
1587 fsp = file_fsp(params,0);
1588 info_level = SVAL(params,2);
1590 if(fsp && fsp->open && (fsp->is_directory || fsp->stat_open)) {
1592 * This is actually a SETFILEINFO on a directory
1593 * handle (returned from an NT SMB). NT5.0 seems
1594 * to do this call. JRA.
1596 fname = fsp->fsp_name;
1597 unix_convert(fname,conn,0,&bad_path,&st);
1598 if (!check_name(fname,conn) ||
1599 (!VALID_STAT(st) && conn->vfs_ops.stat(dos_to_unix(fname,False),&st))) {
1600 DEBUG(3,("fileinfo of %s failed (%s)\n",fname,strerror(errno)));
1601 if((errno == ENOENT) && bad_path)
1603 unix_ERR_class = ERRDOS;
1604 unix_ERR_code = ERRbadpath;
1606 return(UNIXERROR(ERRDOS,ERRbadpath));
1610 * Original code - this is an open file.
1612 CHECK_FSP(fsp,conn);
1615 fname = fsp->fsp_name;
1616 fd = fsp->fd_ptr->fd;
1618 if (fsp->conn->vfs_ops.fstat(fd,&st) != 0) {
1619 DEBUG(3,("fstat of fnum %d failed (%s)\n",fsp->fnum, strerror(errno)));
1620 return(UNIXERROR(ERRDOS,ERRbadfid));
1625 info_level = SVAL(params,0);
1627 pstrcpy(fname,¶ms[6]);
1628 unix_convert(fname,conn,0,&bad_path,&st);
1629 if(!check_name(fname, conn))
1631 if((errno == ENOENT) && bad_path)
1633 unix_ERR_class = ERRDOS;
1634 unix_ERR_code = ERRbadpath;
1636 return(UNIXERROR(ERRDOS,ERRbadpath));
1639 if(!VALID_STAT(st) && conn->vfs_ops.stat(dos_to_unix(fname,False),&st)!=0) {
1640 DEBUG(3,("stat of %s failed (%s)\n", fname, strerror(errno)));
1641 if((errno == ENOENT) && bad_path)
1643 unix_ERR_class = ERRDOS;
1644 unix_ERR_code = ERRbadpath;
1646 return(UNIXERROR(ERRDOS,ERRbadpath));
1650 DEBUG(3,("call_trans2setfilepathinfo(%d) %s info_level=%d totdata=%d\n",
1651 tran_call,fname,info_level,total_data));
1653 /* Realloc the parameter and data sizes */
1654 params = *pparams = Realloc(*pparams,2);
1656 return(ERROR(ERRDOS,ERRnomem));
1661 tvs.modtime = st.st_mtime;
1662 tvs.actime = st.st_atime;
1663 mode = dos_mode(conn,fname,&st);
1665 if (total_data > 0 && IVAL(pdata,0) == total_data) {
1666 /* uggh, EAs for OS2 */
1667 DEBUG(4,("Rejecting EA request with total_data=%d\n",total_data));
1668 return(ERROR(ERRDOS,ERROR_EAS_NOT_SUPPORTED));
1673 case SMB_INFO_STANDARD:
1674 case SMB_INFO_QUERY_EA_SIZE:
1677 tvs.actime = make_unix_date2(pdata+l1_fdateLastAccess);
1680 tvs.modtime = make_unix_date2(pdata+l1_fdateLastWrite);
1682 mode = SVAL(pdata,l1_attrFile);
1683 size = IVAL(pdata,l1_cbFile);
1687 /* XXXX um, i don't think this is right.
1688 it's also not in the cifs6.txt spec.
1690 case SMB_INFO_QUERY_EAS_FROM_LIST:
1691 tvs.actime = make_unix_date2(pdata+8);
1692 tvs.modtime = make_unix_date2(pdata+12);
1693 size = IVAL(pdata,16);
1694 mode = IVAL(pdata,24);
1697 /* XXXX nor this. not in cifs6.txt, either. */
1698 case SMB_INFO_QUERY_ALL_EAS:
1699 tvs.actime = make_unix_date2(pdata+8);
1700 tvs.modtime = make_unix_date2(pdata+12);
1701 size = IVAL(pdata,16);
1702 mode = IVAL(pdata,24);
1705 case SMB_SET_FILE_BASIC_INFO:
1707 /* Patch to do this correctly from Paul Eggert <eggert@twinsun.com>. */
1709 time_t changed_time;
1711 /* Ignore create time at offset pdata. */
1714 tvs.actime = interpret_long_date(pdata+8);
1716 write_time = interpret_long_date(pdata+16);
1717 changed_time = interpret_long_date(pdata+24);
1719 tvs.modtime = MIN(write_time, changed_time);
1721 /* Prefer a defined time to an undefined one. */
1722 if (tvs.modtime == (time_t)0 || tvs.modtime == (time_t)-1)
1723 tvs.modtime = (write_time == (time_t)0 || write_time == (time_t)-1
1727 #if 0 /* Needs more testing... */
1728 /* Test from Luke to prevent Win95 from
1729 setting incorrect values here.
1731 if (tvs.actime < tvs.modtime)
1732 return(ERROR(ERRDOS,ERRnoaccess));
1733 #endif /* Needs more testing... */
1736 mode = IVAL(pdata,32);
1741 * NT seems to use this call with a size of zero
1742 * to mean truncate the file. JRA.
1745 case SMB_SET_FILE_ALLOCATION_INFO:
1747 SMB_OFF_T newsize = IVAL(pdata,0);
1748 #ifdef LARGE_SMB_OFF_T
1749 newsize |= (((SMB_OFF_T)IVAL(pdata,4)) << 32);
1750 #else /* LARGE_SMB_OFF_T */
1751 if (IVAL(pdata,4) != 0) /* more than 32 bits? */
1752 return(ERROR(ERRDOS,ERRunknownlevel));
1753 #endif /* LARGE_SMB_OFF_T */
1754 DEBUG(10,("call_trans2setfilepathinfo: Set file allocation info for file %s to %.0f\n", fname, (double)newsize ));
1760 case SMB_SET_FILE_END_OF_FILE_INFO:
1762 size = IVAL(pdata,0);
1763 #ifdef LARGE_SMB_OFF_T
1764 size |= (((SMB_OFF_T)IVAL(pdata,4)) << 32);
1765 #else /* LARGE_SMB_OFF_T */
1766 if (IVAL(pdata,4) != 0) /* more than 32 bits? */
1767 return(ERROR(ERRDOS,ERRunknownlevel));
1768 #endif /* LARGE_SMB_OFF_T */
1769 DEBUG(10,("call_trans2setfilepathinfo: Set end of file info for file %s to %.0f\n", fname, (double)size ));
1773 case SMB_SET_FILE_DISPOSITION_INFO: /* Set delete on close for open file. */
1775 if ((tran_call == TRANSACT2_SETFILEINFO) && (fsp != NULL))
1777 BOOL delete_on_close = (CVAL(pdata,0) ? True : False);
1779 if(fsp->is_directory)
1781 fsp->directory_delete_on_close = delete_on_close;
1782 DEBUG(10, ("call_trans2setfilepathinfo: %s delete on close flag for fnum = %d, directory %s\n",
1783 delete_on_close ? "Added" : "Removed", fsp->fnum, fsp->fsp_name ));
1786 else if(fsp->stat_open)
1788 DEBUG(10, ("call_trans2setfilepathinfo: %s delete on close flag for fnum = %d, stat open %s\n",
1789 delete_on_close ? "Added" : "Removed", fsp->fnum, fsp->fsp_name ));
1795 * We can only set the delete on close flag if
1796 * the share mode contained ALLOW_SHARE_DELETE
1799 if(lp_share_modes(SNUM(conn)))
1801 if(!GET_ALLOW_SHARE_DELETE(fsp->share_mode))
1802 return(ERROR(ERRDOS,ERRnoaccess));
1805 * If the flag has been set then
1806 * modify the share mode entry for all files we have open
1807 * on this device and inode to tell other smbds we have
1808 * changed the delete on close flag.
1811 if(delete_on_close && !GET_DELETE_ON_CLOSE_FLAG(fsp->share_mode))
1814 files_struct *iterate_fsp;
1815 SMB_DEV_T dev = fsp->fd_ptr->dev;
1816 SMB_INO_T inode = fsp->fd_ptr->inode;
1817 int num_share_modes;
1818 share_mode_entry *current_shares = NULL;
1820 if(lock_share_entry(fsp->conn, dev, inode) == False)
1821 return(ERROR(ERRDOS,ERRnoaccess));
1824 * Before we allow this we need to ensure that all current opens
1825 * on the file have the GET_ALLOW_SHARE_DELETE flag set. If they
1826 * do not then we deny this (as we are essentially deleting the
1827 * file at this point.
1830 num_share_modes = get_share_modes(conn, dev, inode, ¤t_shares);
1831 for(i = 0; i < num_share_modes; i++)
1833 if(!GET_ALLOW_SHARE_DELETE(current_shares[i].share_mode))
1835 DEBUG(5,("call_trans2setfilepathinfo: refusing to set delete on close flag for fnum = %d, \
1836 file %s as a share exists that was not opened with FILE_DELETE access.\n",
1837 fsp->fnum, fsp->fsp_name ));
1842 unlock_share_entry(fsp->conn, dev, inode);
1845 * current_shares was malloced by get_share_modes - free it here.
1848 free((char *)current_shares);
1851 * Even though share violation would be more appropriate here,
1852 * return ERRnoaccess as that's what NT does.
1855 return(ERROR(ERRDOS,ERRnoaccess));
1860 * current_shares was malloced by get_share_modes - free it here.
1863 free((char *)current_shares);
1865 DEBUG(10,("call_trans2setfilepathinfo: %s delete on close flag for fnum = %d, file %s\n",
1866 delete_on_close ? "Adding" : "Removing", fsp->fnum, fsp->fsp_name ));
1869 * Go through all files we have open on the same device and
1870 * inode (hanging off the same hash bucket) and set the DELETE_ON_CLOSE_FLAG.
1871 * Other smbd's that have this file open will have to fend for themselves. We
1872 * take care of this (rare) case in close_file(). See the comment there.
1875 for(iterate_fsp = file_find_di_first(dev, inode); iterate_fsp;
1876 iterate_fsp = file_find_di_next(iterate_fsp))
1878 int new_share_mode = (delete_on_close ?
1879 (iterate_fsp->share_mode | DELETE_ON_CLOSE_FLAG) :
1880 (iterate_fsp->share_mode & ~DELETE_ON_CLOSE_FLAG) );
1882 DEBUG(10,("call_trans2setfilepathinfo: Changing share mode for fnum %d, file %s \
1883 dev = %x, inode = %.0f from %x to %x\n",
1884 iterate_fsp->fnum, iterate_fsp->fsp_name, (unsigned int)dev,
1885 (double)inode, iterate_fsp->share_mode, new_share_mode ));
1887 if(modify_share_mode(iterate_fsp, new_share_mode, iterate_fsp->oplock_type)==False)
1888 DEBUG(0,("call_trans2setfilepathinfo: failed to change delete on close for fnum %d, \
1889 dev = %x, inode = %.0f\n", iterate_fsp->fnum, (unsigned int)dev, (double)inode));
1893 * Set the delete on close flag in the reference
1894 * counted struct. Delete when the last reference
1897 fsp->fd_ptr->delete_on_close = delete_on_close;
1899 unlock_share_entry(fsp->conn, dev, inode);
1901 DEBUG(10, ("call_trans2setfilepathinfo: %s delete on close flag for fnum = %d, file %s\n",
1902 delete_on_close ? "Added" : "Removed", fsp->fnum, fsp->fsp_name ));
1904 } /* end if(delete_on_close && !GET_DELETE_ON_CLOSE_FLAG(fsp->share_mode)) */
1905 } /* end if lp_share_modes() */
1906 } /* end if is_directory. */
1908 return(ERROR(ERRDOS,ERRunknownlevel));
1914 return(ERROR(ERRDOS,ERRunknownlevel));
1918 /* get some defaults (no modifications) if any info is zero or -1. */
1919 if (tvs.actime == (time_t)0 || tvs.actime == (time_t)-1)
1920 tvs.actime = st.st_atime;
1922 if (tvs.modtime == (time_t)0 || tvs.modtime == (time_t)-1)
1923 tvs.modtime = st.st_mtime;
1925 DEBUG(6,("actime: %s " , ctime(&tvs.actime)));
1926 DEBUG(6,("modtime: %s ", ctime(&tvs.modtime)));
1927 DEBUG(6,("size: %.0f ", (double)size));
1928 DEBUG(6,("mode: %x\n" , mode));
1930 if(!((info_level == SMB_SET_FILE_END_OF_FILE_INFO) ||
1931 (info_level == SMB_SET_FILE_ALLOCATION_INFO))) {
1933 * Only do this test if we are not explicitly
1934 * changing the size of a file.
1940 /* Try and set the times, size and mode of this file -
1941 if they are different from the current values
1943 if (st.st_mtime != tvs.modtime || st.st_atime != tvs.actime) {
1946 * This was a setfileinfo on an open file.
1947 * NT does this a lot. It's actually pointless
1948 * setting the time here, as it will be overwritten
1949 * on the next write, so we save the request
1950 * away and will set it on file code. JRA.
1953 if (tvs.modtime != (time_t)0 && tvs.modtime != (time_t)-1) {
1954 DEBUG(10,("call_trans2setfilepathinfo: setting pending modtime to %s\n",
1955 ctime(&tvs.modtime) ));
1956 fsp->pending_modtime = tvs.modtime;
1961 DEBUG(10,("call_trans2setfilepathinfo: setting utimes to modified values.\n"));
1963 if(file_utime(conn, fname, &tvs)!=0)
1964 return(UNIXERROR(ERRDOS,ERRnoaccess));
1968 /* check the mode isn't different, before changing it */
1969 if ((mode != 0) && (mode != dos_mode(conn, fname, &st))) {
1971 DEBUG(10,("call_trans2setfilepathinfo: file %s : setting dos mode %x\n",
1974 if(file_chmod(conn, fname, mode, NULL)) {
1975 DEBUG(2,("chmod of %s failed (%s)\n", fname, strerror(errno)));
1976 return(UNIXERROR(ERRDOS,ERRnoaccess));
1980 if(size != st.st_size) {
1982 DEBUG(10,("call_trans2setfilepathinfo: file %s : setting new size to %.0f\n",
1983 fname, (double)size ));
1986 fd = conn->vfs_ops.open(dos_to_unix(fname,False),O_RDWR,0);
1988 return(UNIXERROR(ERRDOS,ERRbadpath));
1989 set_filelen(fd, size); /* tpot vfs */
1990 conn->vfs_ops.close(fd);
1992 set_filelen(fd, size); /* tpot vfs */
1996 set_filelen_write_cache(fsp, size);
2001 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
2006 /****************************************************************************
2007 reply to a TRANS2_MKDIR (make directory with extended attributes).
2008 ****************************************************************************/
2009 static int call_trans2mkdir(connection_struct *conn,
2010 char *inbuf, char *outbuf, int length, int bufsize,
2011 char **pparams, char **ppdata)
2013 char *params = *pparams;
2016 BOOL bad_path = False;
2018 if (!CAN_WRITE(conn))
2019 return(ERROR(ERRSRV,ERRaccess));
2021 pstrcpy(directory, ¶ms[4]);
2023 DEBUG(3,("call_trans2mkdir : name = %s\n", directory));
2025 unix_convert(directory,conn,0,&bad_path,NULL);
2026 if (check_name(directory,conn))
2027 ret = conn->vfs_ops.mkdir(dos_to_unix(directory,False),
2028 unix_mode(conn,aDIR,directory));
2032 DEBUG(5,("call_trans2mkdir error (%s)\n", strerror(errno)));
2033 if((errno == ENOENT) && bad_path)
2035 unix_ERR_class = ERRDOS;
2036 unix_ERR_code = ERRbadpath;
2038 return(UNIXERROR(ERRDOS,ERRnoaccess));
2041 /* Realloc the parameter and data sizes */
2042 params = *pparams = Realloc(*pparams,2);
2044 return(ERROR(ERRDOS,ERRnomem));
2048 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
2053 /****************************************************************************
2054 reply to a TRANS2_FINDNOTIFYFIRST (start monitoring a directory for changes)
2055 We don't actually do this - we just send a null response.
2056 ****************************************************************************/
2057 static int call_trans2findnotifyfirst(connection_struct *conn,
2058 char *inbuf, char *outbuf,
2059 int length, int bufsize,
2060 char **pparams, char **ppdata)
2062 static uint16 fnf_handle = 257;
2063 char *params = *pparams;
2064 uint16 info_level = SVAL(params,4);
2066 DEBUG(3,("call_trans2findnotifyfirst - info_level %d\n", info_level));
2074 return(ERROR(ERRDOS,ERRunknownlevel));
2077 /* Realloc the parameter and data sizes */
2078 params = *pparams = Realloc(*pparams,6);
2080 return(ERROR(ERRDOS,ERRnomem));
2082 SSVAL(params,0,fnf_handle);
2083 SSVAL(params,2,0); /* No changes */
2084 SSVAL(params,4,0); /* No EA errors */
2091 send_trans2_replies(outbuf, bufsize, params, 6, *ppdata, 0);
2096 /****************************************************************************
2097 reply to a TRANS2_FINDNOTIFYNEXT (continue monitoring a directory for
2098 changes). Currently this does nothing.
2099 ****************************************************************************/
2100 static int call_trans2findnotifynext(connection_struct *conn,
2101 char *inbuf, char *outbuf,
2102 int length, int bufsize,
2103 char **pparams, char **ppdata)
2105 char *params = *pparams;
2107 DEBUG(3,("call_trans2findnotifynext\n"));
2109 /* Realloc the parameter and data sizes */
2110 params = *pparams = Realloc(*pparams,4);
2112 return(ERROR(ERRDOS,ERRnomem));
2114 SSVAL(params,0,0); /* No changes */
2115 SSVAL(params,2,0); /* No EA errors */
2117 send_trans2_replies(outbuf, bufsize, params, 4, *ppdata, 0);
2122 /****************************************************************************
2123 reply to a SMBfindclose (stop trans2 directory search)
2124 ****************************************************************************/
2125 int reply_findclose(connection_struct *conn,
2126 char *inbuf,char *outbuf,int length,int bufsize)
2129 int dptr_num=SVALS(inbuf,smb_vwv0);
2131 DEBUG(3,("reply_findclose, dptr_num = %d\n", dptr_num));
2133 dptr_close(&dptr_num);
2135 outsize = set_message(outbuf,0,0,True);
2137 DEBUG(3,("SMBfindclose dptr_num = %d\n", dptr_num));
2142 /****************************************************************************
2143 reply to a SMBfindnclose (stop FINDNOTIFYFIRST directory search)
2144 ****************************************************************************/
2145 int reply_findnclose(connection_struct *conn,
2146 char *inbuf,char *outbuf,int length,int bufsize)
2151 dptr_num = SVAL(inbuf,smb_vwv0);
2153 DEBUG(3,("reply_findnclose, dptr_num = %d\n", dptr_num));
2155 /* We never give out valid handles for a
2156 findnotifyfirst - so any dptr_num is ok here.
2159 outsize = set_message(outbuf,0,0,True);
2161 DEBUG(3,("SMB_findnclose dptr_num = %d\n", dptr_num));
2167 /****************************************************************************
2168 reply to a SMBtranss2 - just ignore it!
2169 ****************************************************************************/
2170 int reply_transs2(connection_struct *conn,
2171 char *inbuf,char *outbuf,int length,int bufsize)
2173 DEBUG(4,("Ignoring transs2 of length %d\n",length));
2177 /****************************************************************************
2178 reply to a SMBtrans2
2179 ****************************************************************************/
2180 int reply_trans2(connection_struct *conn,
2181 char *inbuf,char *outbuf,int length,int bufsize)
2184 unsigned int total_params = SVAL(inbuf, smb_tpscnt);
2185 unsigned int total_data =SVAL(inbuf, smb_tdscnt);
2187 unsigned int max_param_reply = SVAL(inbuf, smb_mprcnt);
2188 unsigned int max_data_reply = SVAL(inbuf, smb_mdrcnt);
2189 unsigned int max_setup_fields = SVAL(inbuf, smb_msrcnt);
2190 BOOL close_tid = BITSETW(inbuf+smb_flags,0);
2191 BOOL no_final_response = BITSETW(inbuf+smb_flags,1);
2192 int32 timeout = IVALS(inbuf,smb_timeout);
2194 unsigned int suwcnt = SVAL(inbuf, smb_suwcnt);
2195 unsigned int tran_call = SVAL(inbuf, smb_setup0);
2196 char *params = NULL, *data = NULL;
2197 int num_params, num_params_sofar, num_data, num_data_sofar;
2199 if(global_oplock_break && (tran_call == TRANSACT2_OPEN)) {
2200 /* Queue this open message as we are the process of an
2203 DEBUG(2,("reply_trans2: queueing message trans2open due to being "));
2204 DEBUGADD(2,( "in oplock break state.\n"));
2206 push_oplock_pending_smb_message(inbuf, length);
2210 outsize = set_message(outbuf,0,0,True);
2212 /* All trans2 messages we handle have smb_sucnt == 1 - ensure this
2213 is so as a sanity check */
2215 DEBUG(2,("Invalid smb_sucnt in trans2 call\n"));
2216 return(ERROR(ERRSRV,ERRerror));
2219 /* Allocate the space for the maximum needed parameters and data */
2220 if (total_params > 0)
2221 params = (char *)malloc(total_params);
2223 data = (char *)malloc(total_data);
2225 if ((total_params && !params) || (total_data && !data)) {
2226 DEBUG(2,("Out of memory in reply_trans2\n"));
2231 return(ERROR(ERRDOS,ERRnomem));
2234 /* Copy the param and data bytes sent with this request into
2235 the params buffer */
2236 num_params = num_params_sofar = SVAL(inbuf,smb_pscnt);
2237 num_data = num_data_sofar = SVAL(inbuf, smb_dscnt);
2239 if (num_params > total_params || num_data > total_data)
2240 exit_server("invalid params in reply_trans2");
2243 memcpy( params, smb_base(inbuf) + SVAL(inbuf, smb_psoff), num_params);
2245 memcpy( data, smb_base(inbuf) + SVAL(inbuf, smb_dsoff), num_data);
2247 if(num_data_sofar < total_data || num_params_sofar < total_params) {
2248 /* We need to send an interim response then receive the rest
2249 of the parameter/data bytes */
2250 outsize = set_message(outbuf,0,0,True);
2251 send_smb(Client,outbuf);
2253 while (num_data_sofar < total_data ||
2254 num_params_sofar < total_params) {
2257 ret = receive_next_smb(inbuf,bufsize,SMB_SECONDARY_WAIT);
2260 (CVAL(inbuf, smb_com) != SMBtranss2)) || !ret) {
2261 outsize = set_message(outbuf,0,0,True);
2263 DEBUG(0,("reply_trans2: Invalid secondary trans2 packet\n"));
2265 DEBUG(0,("reply_trans2: %s in getting secondary trans2 response.\n",
2266 (smb_read_error == READ_ERROR) ? "error" : "timeout" ));
2271 return(ERROR(ERRSRV,ERRerror));
2274 /* Revise total_params and total_data in case
2275 they have changed downwards */
2276 total_params = SVAL(inbuf, smb_tpscnt);
2277 total_data = SVAL(inbuf, smb_tdscnt);
2278 num_params_sofar += (num_params = SVAL(inbuf,smb_spscnt));
2279 num_data_sofar += ( num_data = SVAL(inbuf, smb_sdscnt));
2280 if (num_params_sofar > total_params || num_data_sofar > total_data)
2281 exit_server("data overflow in trans2");
2283 memcpy( ¶ms[ SVAL(inbuf, smb_spsdisp)],
2284 smb_base(inbuf) + SVAL(inbuf, smb_spsoff), num_params);
2285 memcpy( &data[SVAL(inbuf, smb_sdsdisp)],
2286 smb_base(inbuf)+ SVAL(inbuf, smb_sdsoff), num_data);
2290 if (Protocol >= PROTOCOL_NT1) {
2291 uint16 flg2 = SVAL(outbuf,smb_flg2);
2292 SSVAL(outbuf,smb_flg2,flg2 | 0x40); /* IS_LONG_NAME */
2295 /* Now we must call the relevant TRANS2 function */
2297 case TRANSACT2_OPEN:
2298 outsize = call_trans2open(conn,
2299 inbuf, outbuf, bufsize,
2303 case TRANSACT2_FINDFIRST:
2304 outsize = call_trans2findfirst(conn, inbuf, outbuf,
2305 bufsize, ¶ms, &data);
2308 case TRANSACT2_FINDNEXT:
2309 outsize = call_trans2findnext(conn, inbuf, outbuf,
2314 case TRANSACT2_QFSINFO:
2315 outsize = call_trans2qfsinfo(conn, inbuf, outbuf,
2316 length, bufsize, ¶ms,
2320 case TRANSACT2_SETFSINFO:
2321 outsize = call_trans2setfsinfo(conn, inbuf, outbuf,
2326 case TRANSACT2_QPATHINFO:
2327 case TRANSACT2_QFILEINFO:
2328 outsize = call_trans2qfilepathinfo(conn, inbuf, outbuf,
2330 ¶ms, &data, total_data);
2332 case TRANSACT2_SETPATHINFO:
2333 case TRANSACT2_SETFILEINFO:
2334 outsize = call_trans2setfilepathinfo(conn, inbuf, outbuf,
2340 case TRANSACT2_FINDNOTIFYFIRST:
2341 outsize = call_trans2findnotifyfirst(conn, inbuf, outbuf,
2346 case TRANSACT2_FINDNOTIFYNEXT:
2347 outsize = call_trans2findnotifynext(conn, inbuf, outbuf,
2351 case TRANSACT2_MKDIR:
2352 outsize = call_trans2mkdir(conn, inbuf, outbuf, length,
2353 bufsize, ¶ms, &data);
2356 /* Error in request */
2357 DEBUG(2,("Unknown request %d in trans2 call\n", tran_call));
2362 return (ERROR(ERRSRV,ERRerror));
2365 /* As we do not know how many data packets will need to be
2366 returned here the various call_trans2xxxx calls
2367 must send their own. Thus a call_trans2xxx routine only
2368 returns a value other than -1 when it wants to send
2376 return outsize; /* If a correct response was needed the
2377 call_trans2xxx calls have already sent
2378 it. If outsize != -1 then it is returning */