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);
122 /* smb_proff is the offset from the start of the SMB header to the
123 parameter bytes, however the first 4 bytes of outbuf are
124 the Netbios over TCP header. Thus use smb_base() to subtract
125 them from the calculation */
127 SSVAL(outbuf,smb_proff,((smb_buf(outbuf)+alignment_offset) - smb_base(outbuf)));
129 if(params_sent_thistime == 0)
130 SSVAL(outbuf,smb_prdisp,0);
132 /* Absolute displacement of param bytes sent in this packet */
133 SSVAL(outbuf,smb_prdisp,pp - params);
135 SSVAL(outbuf,smb_drcnt, data_sent_thistime);
136 if(data_sent_thistime == 0)
138 SSVAL(outbuf,smb_droff,0);
139 SSVAL(outbuf,smb_drdisp, 0);
143 /* The offset of the data bytes is the offset of the
144 parameter bytes plus the number of parameters being sent this time */
145 SSVAL(outbuf,smb_droff,((smb_buf(outbuf)+alignment_offset) -
146 smb_base(outbuf)) + params_sent_thistime + data_alignment_offset);
147 SSVAL(outbuf,smb_drdisp, pd - pdata);
150 /* Copy the param bytes into the packet */
151 if(params_sent_thistime)
152 memcpy((smb_buf(outbuf)+alignment_offset),pp,params_sent_thistime);
153 /* Copy in the data bytes */
154 if(data_sent_thistime)
155 memcpy(smb_buf(outbuf)+alignment_offset+params_sent_thistime+
156 data_alignment_offset,pd,data_sent_thistime);
158 DEBUG(9,("t2_rep: params_sent_thistime = %d, data_sent_thistime = %d, useable_space = %d\n",
159 params_sent_thistime, data_sent_thistime, useable_space));
160 DEBUG(9,("t2_rep: params_to_send = %d, data_to_send = %d, paramsize = %d, datasize = %d\n",
161 params_to_send, data_to_send, paramsize, datasize));
163 /* Send the packet */
164 send_smb(Client,outbuf);
166 pp += params_sent_thistime;
167 pd += data_sent_thistime;
169 params_to_send -= params_sent_thistime;
170 data_to_send -= data_sent_thistime;
173 if(params_to_send < 0 || data_to_send < 0)
175 DEBUG(0,("send_trans2_replies failed sanity check pts = %d, dts = %d\n!!!",
176 params_to_send, data_to_send));
185 /****************************************************************************
186 reply to a TRANSACT2_OPEN
187 ****************************************************************************/
188 static int call_trans2open(connection_struct *conn, char *inbuf, char *outbuf,
190 char **pparams, char **ppdata)
192 char *params = *pparams;
193 int16 open_mode = SVAL(params, 2);
194 int16 open_attr = SVAL(params,6);
195 BOOL oplock_request = (((SVAL(params,0)|(1<<1))>>1) | ((SVAL(params,0)|(1<<2))>>1));
197 BOOL return_additional_info = BITSETW(params,0);
198 int16 open_sattr = SVAL(params, 4);
199 time_t open_time = make_unix_date3(params+8);
201 int16 open_ofun = SVAL(params,12);
202 int32 open_size = IVAL(params,14);
203 char *pname = ¶ms[28];
204 int16 namelen = strlen(pname)+1;
209 int fmode=0,mtime=0,rmode;
211 SMB_STRUCT_STAT sbuf;
213 BOOL bad_path = False;
216 StrnCpy(fname,pname,namelen);
218 DEBUG(3,("trans2open %s mode=%d attr=%d ofun=%d size=%d\n",
219 fname,open_mode, open_attr, open_ofun, open_size));
221 /* XXXX we need to handle passed times, sattr and flags */
223 unix_convert(fname,conn,0,&bad_path,NULL);
227 return(ERROR(ERRSRV,ERRnofids));
229 if (!check_name(fname,conn))
231 if((errno == ENOENT) && bad_path)
233 unix_ERR_class = ERRDOS;
234 unix_ERR_code = ERRbadpath;
237 return(UNIXERROR(ERRDOS,ERRnoaccess));
240 unixmode = unix_mode(conn,open_attr | aARCH, fname);
242 open_file_shared(fsp,conn,fname,open_mode,open_ofun,unixmode,
243 oplock_request, &rmode,&smb_action);
247 if((errno == ENOENT) && bad_path)
249 unix_ERR_class = ERRDOS;
250 unix_ERR_code = ERRbadpath;
253 return(UNIXERROR(ERRDOS,ERRnoaccess));
256 if (fsp->conn->vfs_ops.fstat(fsp->fd_ptr->fd,&sbuf) != 0) {
257 close_file(fsp,False);
258 return(UNIXERROR(ERRDOS,ERRnoaccess));
262 fmode = dos_mode(conn,fname,&sbuf);
263 mtime = sbuf.st_mtime;
266 close_file(fsp,False);
267 return(ERROR(ERRDOS,ERRnoaccess));
270 /* Realloc the size of parameters and data we will return */
271 params = *pparams = Realloc(*pparams, 28);
273 return(ERROR(ERRDOS,ERRnomem));
275 memset((char *)params,'\0',28);
276 SSVAL(params,0,fsp->fnum);
277 SSVAL(params,2,fmode);
278 put_dos_date2(params,4, mtime);
279 SIVAL(params,8, (uint32)size);
280 SSVAL(params,12,rmode);
282 if (oplock_request && lp_fake_oplocks(SNUM(conn))) {
283 smb_action |= EXTENDED_OPLOCK_GRANTED;
286 SSVAL(params,18,smb_action);
288 * WARNING - this may need to be changed if SMB_INO_T <> 4 bytes.
290 SIVAL(params,20,inode);
292 /* Send the required number of replies */
293 send_trans2_replies(outbuf, bufsize, params, 28, *ppdata, 0);
298 /****************************************************************************
299 get a level dependent lanman2 dir entry.
300 ****************************************************************************/
301 static BOOL get_lanman2_dir_entry(connection_struct *conn,
302 char *path_mask,int dirtype,int info_level,
303 int requires_resume_key,
304 BOOL dont_descend,char **ppdata,
305 char *base_data, int space_remaining,
306 BOOL *out_of_space, BOOL *got_exact_match,
311 SMB_STRUCT_STAT sbuf;
315 char *p, *pdata = *ppdata;
321 time_t mdate=0, adate=0, cdate=0;
323 BOOL isrootdir = (strequal(conn->dirpath,"./") ||
324 strequal(conn->dirpath,".") ||
325 strequal(conn->dirpath,"/"));
327 int nt_extmode; /* Used for NT connections instead of mode */
328 BOOL needslash = ( conn->dirpath[strlen(conn->dirpath) -1] != '/');
331 *out_of_space = False;
332 *got_exact_match = False;
337 p = strrchr(path_mask,'/');
346 pstrcpy(mask, path_mask);
352 /* Needed if we run out of space */
353 prev_dirpos = TellDir(conn->dirptr);
354 dname = ReadDirName(conn->dirptr);
357 * Due to bugs in NT client redirectors we are not using
358 * resume keys any more - set them to zero.
359 * Check out the related comments in findfirst/findnext.
365 DEBUG(8,("get_lanman2_dir_entry:readdir on dirptr 0x%lx now at offset %d\n",
366 (long)conn->dirptr,TellDir(conn->dirptr)));
371 pstrcpy(fname,dname);
373 if(!(got_match = *got_exact_match = exact_match(fname, mask, case_sensitive)))
374 got_match = mask_match(fname, mask, case_sensitive, True);
376 if(!got_match && !is_8_3(fname, False)) {
379 * It turns out that NT matches wildcards against
380 * both long *and* short names. This may explain some
381 * of the wildcard wierdness from old DOS clients
382 * that some people have been seeing.... JRA.
386 pstrcpy( newname, fname);
387 name_map_mangle( newname, True, False, SNUM(conn));
388 if(!(got_match = *got_exact_match = exact_match(newname, mask, case_sensitive)))
389 got_match = mask_match(newname, mask, case_sensitive, True);
394 BOOL isdots = (strequal(fname,"..") || strequal(fname,"."));
395 if (dont_descend && !isdots)
398 if (isrootdir && isdots)
401 pstrcpy(pathreal,conn->dirpath);
403 pstrcat(pathreal,"/");
404 pstrcat(pathreal,dname);
405 if (conn->vfs_ops.stat(dos_to_unix(pathreal,False),&sbuf) != 0)
407 DEBUG(5,("get_lanman2_dir_entry:Couldn't stat [%s] (%s)\n",pathreal,strerror(errno)));
411 mode = dos_mode(conn,pathreal,&sbuf);
413 if (!dir_check_ftype(conn,mode,&sbuf,dirtype)) {
414 DEBUG(5,("[%s] attribs didn't match %x\n",fname,dirtype));
419 mdate = sbuf.st_mtime;
420 adate = sbuf.st_atime;
421 cdate = get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(conn)));
425 DEBUG(5,("get_lanman2_dir_entry found %s fname=%s\n",pathreal,fname));
431 name_map_mangle(fname,False,True,SNUM(conn));
436 nt_extmode = mode ? mode : FILE_ATTRIBUTE_NORMAL;
441 if(requires_resume_key) {
445 put_dos_date2(p,l1_fdateCreation,cdate);
446 put_dos_date2(p,l1_fdateLastAccess,adate);
447 put_dos_date2(p,l1_fdateLastWrite,mdate);
448 SIVAL(p,l1_cbFile,(uint32)size);
449 SIVAL(p,l1_cbFileAlloc,SMB_ROUNDUP(size,1024));
450 SSVAL(p,l1_attrFile,mode);
451 SCVAL(p,l1_cchName,strlen(fname));
452 pstrcpy(p + l1_achName, fname);
453 nameptr = p + l1_achName;
454 p += l1_achName + strlen(fname) + 1;
459 if(requires_resume_key) {
463 put_dos_date2(p,l2_fdateCreation,cdate);
464 put_dos_date2(p,l2_fdateLastAccess,adate);
465 put_dos_date2(p,l2_fdateLastWrite,mdate);
466 SIVAL(p,l2_cbFile,(uint32)size);
467 SIVAL(p,l2_cbFileAlloc,SMB_ROUNDUP(size,1024));
468 SSVAL(p,l2_attrFile,mode);
469 SIVAL(p,l2_cbList,0); /* No extended attributes */
470 SCVAL(p,l2_cchName,strlen(fname));
471 pstrcpy(p + l2_achName, fname);
472 nameptr = p + l2_achName;
473 p += l2_achName + strlen(fname) + 1;
478 put_dos_date2(p,4,cdate);
479 put_dos_date2(p,8,adate);
480 put_dos_date2(p,12,mdate);
481 SIVAL(p,16,(uint32)size);
482 SIVAL(p,20,SMB_ROUNDUP(size,1024));
485 CVAL(p,30) = strlen(fname);
486 pstrcpy(p+31, fname);
488 p += 31 + strlen(fname) + 1;
492 if(requires_resume_key) {
496 SIVAL(p,0,33+strlen(fname)+1);
497 put_dos_date2(p,4,cdate);
498 put_dos_date2(p,8,adate);
499 put_dos_date2(p,12,mdate);
500 SIVAL(p,16,(uint32)size);
501 SIVAL(p,20,SMB_ROUNDUP(size,1024));
503 CVAL(p,32) = strlen(fname);
504 pstrcpy(p + 33, fname);
506 p += 33 + strlen(fname) + 1;
509 case SMB_FIND_FILE_BOTH_DIRECTORY_INFO:
510 was_8_3 = is_8_3(fname, True);
511 len = 94+strlen(fname);
512 len = (len + 3) & ~3;
513 SIVAL(p,0,len); p += 4;
514 SIVAL(p,0,reskey); p += 4;
515 put_long_date(p,cdate); p += 8;
516 put_long_date(p,adate); p += 8;
517 put_long_date(p,mdate); p += 8;
518 put_long_date(p,mdate); p += 8;
522 SIVAL(p,0,nt_extmode); p += 4;
523 SIVAL(p,0,strlen(fname)); p += 4;
524 SIVAL(p,0,0); p += 4;
527 if (!name_map_mangle(p+2,True,True,SNUM(conn)))
532 SSVAL(p,0,strlen(p+2));
535 pstrcpy(p,fname); p += strlen(p);
539 case SMB_FIND_FILE_DIRECTORY_INFO:
540 len = 64+strlen(fname);
541 len = (len + 3) & ~3;
542 SIVAL(p,0,len); p += 4;
543 SIVAL(p,0,reskey); p += 4;
544 put_long_date(p,cdate); p += 8;
545 put_long_date(p,adate); p += 8;
546 put_long_date(p,mdate); p += 8;
547 put_long_date(p,mdate); p += 8;
551 SIVAL(p,0,nt_extmode); p += 4;
552 SIVAL(p,0,strlen(fname)); p += 4;
558 case SMB_FIND_FILE_FULL_DIRECTORY_INFO:
559 len = 68+strlen(fname);
560 len = (len + 3) & ~3;
561 SIVAL(p,0,len); p += 4;
562 SIVAL(p,0,reskey); p += 4;
563 put_long_date(p,cdate); p += 8;
564 put_long_date(p,adate); p += 8;
565 put_long_date(p,mdate); p += 8;
566 put_long_date(p,mdate); p += 8;
570 SIVAL(p,0,nt_extmode); p += 4;
571 SIVAL(p,0,strlen(fname)); p += 4;
572 SIVAL(p,0,0); p += 4;
577 case SMB_FIND_FILE_NAMES_INFO:
578 len = 12+strlen(fname);
579 len = (len + 3) & ~3;
580 SIVAL(p,0,len); p += 4;
581 SIVAL(p,0,reskey); p += 4;
582 SIVAL(p,0,strlen(fname)); p += 4;
592 if (PTR_DIFF(p,pdata) > space_remaining) {
593 /* Move the dirptr back to prev_dirpos */
594 SeekDir(conn->dirptr, prev_dirpos);
595 *out_of_space = True;
596 DEBUG(9,("get_lanman2_dir_entry: out of space\n"));
597 return False; /* Not finished - just out of space */
600 /* Setup the last_filename pointer, as an offset from base_data */
601 *last_name_off = PTR_DIFF(nameptr,base_data);
602 /* Advance the data pointer to the next slot */
608 /****************************************************************************
609 Convert the directory masks formated for the wire.
610 ****************************************************************************/
612 void mask_convert( char *mask)
615 * We know mask is a pstring.
621 if(p[1] != '"' && p[1] != '.') {
622 pstrcpy( expnd, p+1 );
625 safe_strcpy( p+1, expnd, sizeof(pstring) - (p - mask) - 2);
629 if (*p == '>') *p = '?';
630 if (*p == '"') *p = '.';
635 /****************************************************************************
636 Reply to a TRANS2_FINDFIRST.
637 ****************************************************************************/
639 static int call_trans2findfirst(connection_struct *conn,
640 char *inbuf, char *outbuf, int bufsize,
641 char **pparams, char **ppdata)
643 /* We must be careful here that we don't return more than the
644 allowed number of data bytes. If this means returning fewer than
645 maxentries then so be it. We assume that the redirector has
646 enough room for the fixed number of parameter bytes it has
648 uint32 max_data_bytes = SVAL(inbuf, smb_mdrcnt);
649 char *params = *pparams;
650 char *pdata = *ppdata;
651 int dirtype = SVAL(params,0);
652 int maxentries = SVAL(params,2);
653 BOOL close_after_first = BITSETW(params+4,0);
654 BOOL close_if_end = BITSETW(params+4,1);
655 BOOL requires_resume_key = BITSETW(params+4,2);
656 int info_level = SVAL(params,6);
664 BOOL finished = False;
665 BOOL dont_descend = False;
666 BOOL out_of_space = False;
668 BOOL bad_path = False;
670 *directory = *mask = 0;
672 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",
673 dirtype, maxentries, close_after_first, close_if_end, requires_resume_key,
674 info_level, max_data_bytes));
682 case SMB_FIND_FILE_DIRECTORY_INFO:
683 case SMB_FIND_FILE_FULL_DIRECTORY_INFO:
684 case SMB_FIND_FILE_NAMES_INFO:
685 case SMB_FIND_FILE_BOTH_DIRECTORY_INFO:
688 return(ERROR(ERRDOS,ERRunknownlevel));
691 pstrcpy(directory, params + 12); /* Complete directory path with
692 wildcard mask appended */
694 RESOLVE_FINDFIRST_DFSPATH(directory, conn, inbuf, outbuf);
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 FILE_DEVICE_IS_MOUNTED|
1174 (lp_nt_acl_support() ? FILE_PERSISTENT_ACLS : 0)); /* FS ATTRIBUTES */
1175 #if 0 /* Old code. JRA. */
1176 SIVAL(pdata,0,0x4006); /* FS ATTRIBUTES == long filenames supported? */
1177 #endif /* Old code. */
1179 SIVAL(pdata,4,128); /* Max filename component length */
1180 fstype_len = dos_PutUniCode(pdata+12,unix_to_dos(fstype,False),sizeof(pstring), False);
1181 SIVAL(pdata,8,fstype_len);
1182 data_len = 12 + fstype_len;
1183 SSVAL(outbuf,smb_flg2,SVAL(outbuf,smb_flg2)|FLAGS2_UNICODE_STRINGS);
1186 case SMB_QUERY_FS_LABEL_INFO:
1187 data_len = 4 + strlen(vname);
1188 SIVAL(pdata,0,strlen(vname));
1189 pstrcpy(pdata+4,vname);
1191 case SMB_QUERY_FS_VOLUME_INFO:
1194 * Add volume serial number - hash of a combination of
1195 * the called hostname and the service name.
1197 SIVAL(pdata,8,str_checksum(lp_servicename(snum)) ^
1198 (str_checksum(local_machine)<<16));
1200 /* NT4 always serves this up as unicode but expects it to be
1201 * delivered as ascii! (tridge && JRA)
1203 if ((get_remote_arch() != RA_WIN2K) && (global_client_caps & CAP_NT_SMBS)) {
1204 data_len = 18 + strlen(vname);
1205 SIVAL(pdata,12,strlen(vname));
1206 pstrcpy(pdata+18,vname);
1208 data_len = 18 + 2*strlen(vname);
1209 SIVAL(pdata,12,strlen(vname)*2);
1210 dos_PutUniCode(pdata+18,unix_to_dos(vname,False),sizeof(pstring), False);
1211 SSVAL(outbuf,smb_flg2,SVAL(outbuf,smb_flg2)|FLAGS2_UNICODE_STRINGS);
1214 DEBUG(5,("call_trans2qfsinfo : SMB_QUERY_FS_VOLUME_INFO namelen = %d, vol = %s\n",
1215 (int)strlen(vname),vname));
1217 case SMB_QUERY_FS_SIZE_INFO:
1219 SMB_BIG_UINT dfree,dsize,bsize;
1221 conn->vfs_ops.disk_free(".",False,&bsize,&dfree,&dsize);
1222 SBIG_UINT(pdata,0,dsize);
1223 SBIG_UINT(pdata,8,dfree);
1224 SIVAL(pdata,16,bsize/512);
1225 SIVAL(pdata,20,512);
1228 case SMB_QUERY_FS_DEVICE_INFO:
1230 SIVAL(pdata,0,0); /* dev type */
1231 SIVAL(pdata,4,0); /* characteristics */
1233 case SMB_MAC_QUERY_FS_INFO:
1235 * Thursby MAC extension... ONLY on NTFS filesystems
1236 * once we do streams then we don't need this
1238 if (strequal(lp_fstype(SNUM(conn)),"NTFS")) {
1240 SIVAL(pdata,84,0x100); /* Don't support mac... */
1245 return(ERROR(ERRDOS,ERRunknownlevel));
1249 send_trans2_replies( outbuf, bufsize, params, 0, pdata, data_len);
1251 DEBUG( 4, ( "%s info_level = %d\n",
1252 smb_fn_name(CVAL(inbuf,smb_com)), info_level) );
1257 /****************************************************************************
1258 reply to a TRANS2_SETFSINFO (set filesystem info)
1259 ****************************************************************************/
1260 static int call_trans2setfsinfo(connection_struct *conn,
1261 char *inbuf, char *outbuf, int length,
1263 char **pparams, char **ppdata)
1265 /* Just say yes we did it - there is nothing that
1266 can be set here so it doesn't matter. */
1268 DEBUG(3,("call_trans2setfsinfo\n"));
1270 if (!CAN_WRITE(conn))
1271 return(ERROR(ERRSRV,ERRaccess));
1273 outsize = set_message(outbuf,10,0,True);
1278 /****************************************************************************
1279 Reply to a TRANS2_QFILEPATHINFO or TRANSACT2_QFILEINFO (query file info by
1280 file name or file id).
1281 ****************************************************************************/
1283 static int call_trans2qfilepathinfo(connection_struct *conn,
1284 char *inbuf, char *outbuf, int length,
1286 char **pparams,char **ppdata,
1289 int max_data_bytes = SVAL(inbuf, smb_mdrcnt);
1290 char *params = *pparams;
1291 char *pdata = *ppdata;
1292 uint16 tran_call = SVAL(inbuf, smb_setup0);
1296 unsigned int data_size;
1297 SMB_STRUCT_STAT sbuf;
1303 BOOL bad_path = False;
1304 BOOL delete_pending = False;
1306 if (tran_call == TRANSACT2_QFILEINFO) {
1307 files_struct *fsp = file_fsp(params,0);
1308 info_level = SVAL(params,2);
1310 DEBUG(3,("call_trans2qfilepathinfo: TRANSACT2_QFILEINFO: level = %d\n", info_level));
1312 if(fsp && fsp->open && (fsp->is_directory || fsp->stat_open)) {
1314 * This is actually a QFILEINFO on a directory
1315 * handle (returned from an NT SMB). NT5.0 seems
1316 * to do this call. JRA.
1318 fname = fsp->fsp_name;
1319 unix_convert(fname,conn,0,&bad_path,&sbuf);
1320 if (!check_name(fname,conn) ||
1321 (!VALID_STAT(sbuf) && conn->vfs_ops.stat(dos_to_unix(fname,False),&sbuf))) {
1322 DEBUG(3,("fileinfo of %s failed (%s)\n",fname,strerror(errno)));
1323 if((errno == ENOENT) && bad_path)
1325 unix_ERR_class = ERRDOS;
1326 unix_ERR_code = ERRbadpath;
1328 return(UNIXERROR(ERRDOS,ERRbadpath));
1331 delete_pending = fsp->directory_delete_on_close;
1335 * Original code - this is an open file.
1337 CHECK_FSP(fsp,conn);
1340 fname = fsp->fsp_name;
1341 if (fsp->conn->vfs_ops.fstat(fsp->fd_ptr->fd,&sbuf) != 0) {
1342 DEBUG(3,("fstat of fnum %d failed (%s)\n",fsp->fnum, strerror(errno)));
1343 return(UNIXERROR(ERRDOS,ERRbadfid));
1345 if((pos = fsp->conn->vfs_ops.lseek(fsp->fd_ptr->fd,0,SEEK_CUR)) == -1)
1346 return(UNIXERROR(ERRDOS,ERRnoaccess));
1348 delete_pending = fsp->fd_ptr->delete_on_close;
1352 info_level = SVAL(params,0);
1354 DEBUG(3,("call_trans2qfilepathinfo: TRANSACT2_QPATHINFO: level = %d\n", info_level));
1357 pstrcpy(fname,¶ms[6]);
1359 RESOLVE_DFSPATH(fname, conn, inbuf, outbuf);
1361 unix_convert(fname,conn,0,&bad_path,&sbuf);
1362 if (!check_name(fname,conn) ||
1363 (!VALID_STAT(sbuf) && conn->vfs_ops.stat(dos_to_unix(fname,False),&sbuf))) {
1364 DEBUG(3,("fileinfo of %s failed (%s)\n",fname,strerror(errno)));
1365 if((errno == ENOENT) && bad_path)
1367 unix_ERR_class = ERRDOS;
1368 unix_ERR_code = ERRbadpath;
1370 return(UNIXERROR(ERRDOS,ERRbadpath));
1375 DEBUG(3,("call_trans2qfilepathinfo %s level=%d call=%d total_data=%d\n",
1376 fname,info_level,tran_call,total_data));
1378 p = strrchr(fname,'/');
1384 mode = dos_mode(conn,fname,&sbuf);
1385 size = sbuf.st_size;
1386 if (mode & aDIR) size = 0;
1388 /* from now on we only want the part after the / */
1391 params = *pparams = Realloc(*pparams,2);
1392 memset((char *)params,'\0',2);
1393 data_size = max_data_bytes + 1024;
1394 pdata = *ppdata = Realloc(*ppdata, data_size);
1396 if (total_data > 0 && IVAL(pdata,0) == total_data) {
1397 /* uggh, EAs for OS2 */
1398 DEBUG(4,("Rejecting EA request with total_data=%d\n",total_data));
1399 return(ERROR(ERRDOS,ERROR_EAS_NOT_SUPPORTED));
1402 memset((char *)pdata,'\0',data_size);
1406 case SMB_INFO_STANDARD:
1407 case SMB_INFO_QUERY_EA_SIZE:
1408 data_size = (info_level==1?22:26);
1409 put_dos_date2(pdata,l1_fdateCreation,get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(conn))));
1410 put_dos_date2(pdata,l1_fdateLastAccess,sbuf.st_atime);
1411 put_dos_date2(pdata,l1_fdateLastWrite,sbuf.st_mtime); /* write time */
1412 SIVAL(pdata,l1_cbFile,(uint32)size);
1413 SIVAL(pdata,l1_cbFileAlloc,SMB_ROUNDUP(size,1024));
1414 SSVAL(pdata,l1_attrFile,mode);
1415 SIVAL(pdata,l1_attrFile+2,4); /* this is what OS2 does */
1418 case SMB_INFO_QUERY_EAS_FROM_LIST:
1420 put_dos_date2(pdata,0,get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(conn))));
1421 put_dos_date2(pdata,4,sbuf.st_atime);
1422 put_dos_date2(pdata,8,sbuf.st_mtime);
1423 SIVAL(pdata,12,(uint32)size);
1424 SIVAL(pdata,16,SMB_ROUNDUP(size,1024));
1425 SIVAL(pdata,20,mode);
1428 case SMB_INFO_QUERY_ALL_EAS:
1430 SIVAL(pdata,0,data_size);
1434 return(ERROR(ERRDOS,ERRbadfunc)); /* os/2 needs this */
1436 case SMB_QUERY_FILE_BASIC_INFO:
1437 data_size = 36; /* w95 returns 40 bytes not 36 - why ?. */
1438 put_long_date(pdata,get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(conn))));
1439 put_long_date(pdata+8,sbuf.st_atime);
1440 put_long_date(pdata+16,sbuf.st_mtime); /* write time */
1441 put_long_date(pdata+24,sbuf.st_mtime); /* change time */
1442 SIVAL(pdata,32,mode);
1444 DEBUG(5,("SMB_QFBI - "));
1446 time_t create_time = get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(conn)));
1447 DEBUG(5,("create: %s ", ctime(&create_time)));
1449 DEBUG(5,("access: %s ", ctime(&sbuf.st_atime)));
1450 DEBUG(5,("write: %s ", ctime(&sbuf.st_mtime)));
1451 DEBUG(5,("change: %s ", ctime(&sbuf.st_mtime)));
1452 DEBUG(5,("mode: %x\n", mode));
1456 case SMB_QUERY_FILE_STANDARD_INFO:
1458 SOFF_T(pdata,0,size);
1459 SOFF_T(pdata,8,size);
1460 SIVAL(pdata,16,sbuf.st_nlink);
1462 CVAL(pdata,21) = (mode&aDIR)?1:0;
1465 case SMB_QUERY_FILE_EA_INFO:
1469 /* Get the 8.3 name - used if NT SMB was negotiated. */
1470 case SMB_QUERY_FILE_ALT_NAME_INFO:
1473 pstrcpy(short_name,p);
1474 /* Mangle if not already 8.3 */
1475 if(!is_8_3(short_name, True))
1477 if(!name_map_mangle(short_name,True,True,SNUM(conn)))
1480 strupper(short_name);
1481 l = strlen(short_name);
1482 dos_PutUniCode(pdata + 4, unix_to_dos(short_name,False),sizeof(pstring), False);
1483 data_size = 4 + (2*l);
1488 case SMB_QUERY_FILE_NAME_INFO:
1490 * The first part of this code is essential
1491 * to get security descriptors to work on mapped
1492 * drives. Don't ask how I discovered this unless
1493 * you like hearing about me suffering.... :-). JRA.
1495 if(strequal(".", fname) && (global_client_caps & CAP_UNICODE)) {
1497 SSVAL(outbuf,smb_flg2,SVAL(outbuf,smb_flg2)|FLAGS2_UNICODE_STRINGS);
1498 dos_PutUniCode(pdata + 4, unix_to_dos("\\",False),sizeof(pstring), False);
1500 pstrcpy(pdata+4,fname);
1506 case SMB_QUERY_FILE_ALLOCATION_INFO:
1507 case SMB_QUERY_FILE_END_OF_FILEINFO:
1509 SOFF_T(pdata,0,size);
1512 case SMB_QUERY_FILE_ALL_INFO:
1513 put_long_date(pdata,get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(conn))));
1514 put_long_date(pdata+8,sbuf.st_atime);
1515 put_long_date(pdata+16,sbuf.st_mtime); /* write time */
1516 put_long_date(pdata+24,sbuf.st_mtime); /* change time */
1517 SIVAL(pdata,32,mode);
1519 SOFF_T(pdata,0,size);
1520 SOFF_T(pdata,8,size);
1521 SIVAL(pdata,16,sbuf.st_nlink);
1522 CVAL(pdata,20) = delete_pending;
1523 CVAL(pdata,21) = (mode&aDIR)?1:0;
1525 SINO_T(pdata,0,(SMB_INO_T)sbuf.st_ino);
1526 pdata += 8; /* index number */
1527 pdata += 4; /* EA info */
1529 SIVAL(pdata,0,0xA9);
1531 SIVAL(pdata,0,0xd01BF);
1533 SOFF_T(pdata,0,pos); /* current offset */
1535 SIVAL(pdata,0,mode); /* is this the right sort of mode info? */
1537 pdata += 4; /* alignment */
1539 pstrcpy(pdata+4,fname);
1541 data_size = PTR_DIFF(pdata,(*ppdata));
1545 /* NT4 server just returns "invalid query" to this - if we try to answer
1546 it then NTws gets a BSOD! (tridge) */
1547 case SMB_QUERY_FILE_STREAM_INFO:
1550 SIVAL(pdata,4,size);
1551 SIVAL(pdata,12,size);
1553 pstrcpy(pdata+24,fname);
1558 return(ERROR(ERRDOS,ERRunknownlevel));
1561 send_trans2_replies( outbuf, bufsize, params, 2, *ppdata, data_size);
1566 /****************************************************************************
1567 reply to a TRANS2_SETFILEINFO (set file info by fileid)
1568 ****************************************************************************/
1569 static int call_trans2setfilepathinfo(connection_struct *conn,
1570 char *inbuf, char *outbuf, int length,
1571 int bufsize, char **pparams,
1572 char **ppdata, int total_data)
1574 char *params = *pparams;
1575 char *pdata = *ppdata;
1576 uint16 tran_call = SVAL(inbuf, smb_setup0);
1585 BOOL bad_path = False;
1586 files_struct *fsp = NULL;
1588 if (!CAN_WRITE(conn))
1589 return(ERROR(ERRSRV,ERRaccess));
1591 if (tran_call == TRANSACT2_SETFILEINFO) {
1592 fsp = file_fsp(params,0);
1593 info_level = SVAL(params,2);
1595 if(fsp && fsp->open && (fsp->is_directory || fsp->stat_open)) {
1597 * This is actually a SETFILEINFO on a directory
1598 * handle (returned from an NT SMB). NT5.0 seems
1599 * to do this call. JRA.
1601 fname = fsp->fsp_name;
1602 unix_convert(fname,conn,0,&bad_path,&st);
1603 if (!check_name(fname,conn) ||
1604 (!VALID_STAT(st) && conn->vfs_ops.stat(dos_to_unix(fname,False),&st))) {
1605 DEBUG(3,("fileinfo of %s failed (%s)\n",fname,strerror(errno)));
1606 if((errno == ENOENT) && bad_path)
1608 unix_ERR_class = ERRDOS;
1609 unix_ERR_code = ERRbadpath;
1611 return(UNIXERROR(ERRDOS,ERRbadpath));
1615 * Original code - this is an open file.
1617 CHECK_FSP(fsp,conn);
1620 fname = fsp->fsp_name;
1621 fd = fsp->fd_ptr->fd;
1623 if (fsp->conn->vfs_ops.fstat(fd,&st) != 0) {
1624 DEBUG(3,("fstat of fnum %d failed (%s)\n",fsp->fnum, strerror(errno)));
1625 return(UNIXERROR(ERRDOS,ERRbadfid));
1630 info_level = SVAL(params,0);
1632 pstrcpy(fname,¶ms[6]);
1633 unix_convert(fname,conn,0,&bad_path,&st);
1634 if(!check_name(fname, conn))
1636 if((errno == ENOENT) && bad_path)
1638 unix_ERR_class = ERRDOS;
1639 unix_ERR_code = ERRbadpath;
1641 return(UNIXERROR(ERRDOS,ERRbadpath));
1644 if(!VALID_STAT(st) && conn->vfs_ops.stat(dos_to_unix(fname,False),&st)!=0) {
1645 DEBUG(3,("stat of %s failed (%s)\n", fname, strerror(errno)));
1646 if((errno == ENOENT) && bad_path)
1648 unix_ERR_class = ERRDOS;
1649 unix_ERR_code = ERRbadpath;
1651 return(UNIXERROR(ERRDOS,ERRbadpath));
1655 DEBUG(3,("call_trans2setfilepathinfo(%d) %s info_level=%d totdata=%d\n",
1656 tran_call,fname,info_level,total_data));
1658 /* Realloc the parameter and data sizes */
1659 params = *pparams = Realloc(*pparams,2);
1661 return(ERROR(ERRDOS,ERRnomem));
1666 tvs.modtime = st.st_mtime;
1667 tvs.actime = st.st_atime;
1668 mode = dos_mode(conn,fname,&st);
1670 if (total_data > 0 && IVAL(pdata,0) == total_data) {
1671 /* uggh, EAs for OS2 */
1672 DEBUG(4,("Rejecting EA request with total_data=%d\n",total_data));
1673 return(ERROR(ERRDOS,ERROR_EAS_NOT_SUPPORTED));
1678 case SMB_INFO_STANDARD:
1679 case SMB_INFO_QUERY_EA_SIZE:
1682 tvs.actime = make_unix_date2(pdata+l1_fdateLastAccess);
1685 tvs.modtime = make_unix_date2(pdata+l1_fdateLastWrite);
1687 mode = SVAL(pdata,l1_attrFile);
1688 size = IVAL(pdata,l1_cbFile);
1692 /* XXXX um, i don't think this is right.
1693 it's also not in the cifs6.txt spec.
1695 case SMB_INFO_QUERY_EAS_FROM_LIST:
1696 tvs.actime = make_unix_date2(pdata+8);
1697 tvs.modtime = make_unix_date2(pdata+12);
1698 size = IVAL(pdata,16);
1699 mode = IVAL(pdata,24);
1702 /* XXXX nor this. not in cifs6.txt, either. */
1703 case SMB_INFO_QUERY_ALL_EAS:
1704 tvs.actime = make_unix_date2(pdata+8);
1705 tvs.modtime = make_unix_date2(pdata+12);
1706 size = IVAL(pdata,16);
1707 mode = IVAL(pdata,24);
1710 case SMB_SET_FILE_BASIC_INFO:
1712 /* Patch to do this correctly from Paul Eggert <eggert@twinsun.com>. */
1714 time_t changed_time;
1716 /* Ignore create time at offset pdata. */
1719 tvs.actime = interpret_long_date(pdata+8);
1721 write_time = interpret_long_date(pdata+16);
1722 changed_time = interpret_long_date(pdata+24);
1724 tvs.modtime = MIN(write_time, changed_time);
1726 /* Prefer a defined time to an undefined one. */
1727 if (tvs.modtime == (time_t)0 || tvs.modtime == (time_t)-1)
1728 tvs.modtime = (write_time == (time_t)0 || write_time == (time_t)-1
1732 #if 0 /* Needs more testing... */
1733 /* Test from Luke to prevent Win95 from
1734 setting incorrect values here.
1736 if (tvs.actime < tvs.modtime)
1737 return(ERROR(ERRDOS,ERRnoaccess));
1738 #endif /* Needs more testing... */
1741 mode = IVAL(pdata,32);
1746 * NT seems to use this call with a size of zero
1747 * to mean truncate the file. JRA.
1750 case SMB_SET_FILE_ALLOCATION_INFO:
1752 SMB_OFF_T newsize = IVAL(pdata,0);
1753 #ifdef LARGE_SMB_OFF_T
1754 newsize |= (((SMB_OFF_T)IVAL(pdata,4)) << 32);
1755 #else /* LARGE_SMB_OFF_T */
1756 if (IVAL(pdata,4) != 0) /* more than 32 bits? */
1757 return(ERROR(ERRDOS,ERRunknownlevel));
1758 #endif /* LARGE_SMB_OFF_T */
1759 DEBUG(10,("call_trans2setfilepathinfo: Set file allocation info for file %s to %.0f\n", fname, (double)newsize ));
1765 case SMB_SET_FILE_END_OF_FILE_INFO:
1767 size = IVAL(pdata,0);
1768 #ifdef LARGE_SMB_OFF_T
1769 size |= (((SMB_OFF_T)IVAL(pdata,4)) << 32);
1770 #else /* LARGE_SMB_OFF_T */
1771 if (IVAL(pdata,4) != 0) /* more than 32 bits? */
1772 return(ERROR(ERRDOS,ERRunknownlevel));
1773 #endif /* LARGE_SMB_OFF_T */
1774 DEBUG(10,("call_trans2setfilepathinfo: Set end of file info for file %s to %.0f\n", fname, (double)size ));
1778 case SMB_SET_FILE_DISPOSITION_INFO: /* Set delete on close for open file. */
1780 if ((tran_call == TRANSACT2_SETFILEINFO) && (fsp != NULL))
1782 BOOL delete_on_close = (CVAL(pdata,0) ? True : False);
1784 if(fsp->is_directory)
1786 fsp->directory_delete_on_close = delete_on_close;
1787 DEBUG(10, ("call_trans2setfilepathinfo: %s delete on close flag for fnum = %d, directory %s\n",
1788 delete_on_close ? "Added" : "Removed", fsp->fnum, fsp->fsp_name ));
1791 else if(fsp->stat_open)
1793 DEBUG(10, ("call_trans2setfilepathinfo: %s delete on close flag for fnum = %d, stat open %s\n",
1794 delete_on_close ? "Added" : "Removed", fsp->fnum, fsp->fsp_name ));
1800 * We can only set the delete on close flag if
1801 * the share mode contained ALLOW_SHARE_DELETE
1804 if(lp_share_modes(SNUM(conn)))
1806 if(!GET_ALLOW_SHARE_DELETE(fsp->share_mode))
1807 return(ERROR(ERRDOS,ERRnoaccess));
1810 * If the flag has been set then
1811 * modify the share mode entry for all files we have open
1812 * on this device and inode to tell other smbds we have
1813 * changed the delete on close flag.
1816 if(delete_on_close && !GET_DELETE_ON_CLOSE_FLAG(fsp->share_mode))
1819 files_struct *iterate_fsp;
1820 SMB_DEV_T dev = fsp->fd_ptr->dev;
1821 SMB_INO_T inode = fsp->fd_ptr->inode;
1822 int num_share_modes;
1823 share_mode_entry *current_shares = NULL;
1825 if(lock_share_entry(fsp->conn, dev, inode) == False)
1826 return(ERROR(ERRDOS,ERRnoaccess));
1829 * Before we allow this we need to ensure that all current opens
1830 * on the file have the GET_ALLOW_SHARE_DELETE flag set. If they
1831 * do not then we deny this (as we are essentially deleting the
1832 * file at this point.
1835 num_share_modes = get_share_modes(conn, dev, inode, ¤t_shares);
1836 for(i = 0; i < num_share_modes; i++)
1838 if(!GET_ALLOW_SHARE_DELETE(current_shares[i].share_mode))
1840 DEBUG(5,("call_trans2setfilepathinfo: refusing to set delete on close flag for fnum = %d, \
1841 file %s as a share exists that was not opened with FILE_DELETE access.\n",
1842 fsp->fnum, fsp->fsp_name ));
1847 unlock_share_entry(fsp->conn, dev, inode);
1850 * current_shares was malloced by get_share_modes - free it here.
1853 free((char *)current_shares);
1856 * Even though share violation would be more appropriate here,
1857 * return ERRnoaccess as that's what NT does.
1860 return(ERROR(ERRDOS,ERRnoaccess));
1865 * current_shares was malloced by get_share_modes - free it here.
1868 free((char *)current_shares);
1870 DEBUG(10,("call_trans2setfilepathinfo: %s delete on close flag for fnum = %d, file %s\n",
1871 delete_on_close ? "Adding" : "Removing", fsp->fnum, fsp->fsp_name ));
1874 * Go through all files we have open on the same device and
1875 * inode (hanging off the same hash bucket) and set the DELETE_ON_CLOSE_FLAG.
1876 * Other smbd's that have this file open will have to fend for themselves. We
1877 * take care of this (rare) case in close_file(). See the comment there.
1880 for(iterate_fsp = file_find_di_first(dev, inode); iterate_fsp;
1881 iterate_fsp = file_find_di_next(iterate_fsp))
1883 int new_share_mode = (delete_on_close ?
1884 (iterate_fsp->share_mode | DELETE_ON_CLOSE_FLAG) :
1885 (iterate_fsp->share_mode & ~DELETE_ON_CLOSE_FLAG) );
1887 DEBUG(10,("call_trans2setfilepathinfo: Changing share mode for fnum %d, file %s \
1888 dev = %x, inode = %.0f from %x to %x\n",
1889 iterate_fsp->fnum, iterate_fsp->fsp_name, (unsigned int)dev,
1890 (double)inode, iterate_fsp->share_mode, new_share_mode ));
1892 if(modify_share_mode(iterate_fsp, new_share_mode, iterate_fsp->oplock_type)==False)
1893 DEBUG(0,("call_trans2setfilepathinfo: failed to change delete on close for fnum %d, \
1894 dev = %x, inode = %.0f\n", iterate_fsp->fnum, (unsigned int)dev, (double)inode));
1898 * Set the delete on close flag in the reference
1899 * counted struct. Delete when the last reference
1902 fsp->fd_ptr->delete_on_close = delete_on_close;
1904 unlock_share_entry(fsp->conn, dev, inode);
1906 DEBUG(10, ("call_trans2setfilepathinfo: %s delete on close flag for fnum = %d, file %s\n",
1907 delete_on_close ? "Added" : "Removed", fsp->fnum, fsp->fsp_name ));
1909 } /* end if(delete_on_close && !GET_DELETE_ON_CLOSE_FLAG(fsp->share_mode)) */
1910 } /* end if lp_share_modes() */
1911 } /* end if is_directory. */
1913 return(ERROR(ERRDOS,ERRunknownlevel));
1919 return(ERROR(ERRDOS,ERRunknownlevel));
1923 /* get some defaults (no modifications) if any info is zero or -1. */
1924 if (tvs.actime == (time_t)0 || tvs.actime == (time_t)-1)
1925 tvs.actime = st.st_atime;
1927 if (tvs.modtime == (time_t)0 || tvs.modtime == (time_t)-1)
1928 tvs.modtime = st.st_mtime;
1930 DEBUG(6,("actime: %s " , ctime(&tvs.actime)));
1931 DEBUG(6,("modtime: %s ", ctime(&tvs.modtime)));
1932 DEBUG(6,("size: %.0f ", (double)size));
1933 DEBUG(6,("mode: %x\n" , mode));
1935 if(!((info_level == SMB_SET_FILE_END_OF_FILE_INFO) ||
1936 (info_level == SMB_SET_FILE_ALLOCATION_INFO))) {
1938 * Only do this test if we are not explicitly
1939 * changing the size of a file.
1945 /* Try and set the times, size and mode of this file -
1946 if they are different from the current values
1948 if (st.st_mtime != tvs.modtime || st.st_atime != tvs.actime) {
1951 * This was a setfileinfo on an open file.
1952 * NT does this a lot. It's actually pointless
1953 * setting the time here, as it will be overwritten
1954 * on the next write, so we save the request
1955 * away and will set it on file code. JRA.
1958 if (tvs.modtime != (time_t)0 && tvs.modtime != (time_t)-1) {
1959 DEBUG(10,("call_trans2setfilepathinfo: setting pending modtime to %s\n",
1960 ctime(&tvs.modtime) ));
1961 fsp->pending_modtime = tvs.modtime;
1966 DEBUG(10,("call_trans2setfilepathinfo: setting utimes to modified values.\n"));
1968 if(file_utime(conn, fname, &tvs)!=0)
1969 return(UNIXERROR(ERRDOS,ERRnoaccess));
1973 /* check the mode isn't different, before changing it */
1974 if ((mode != 0) && (mode != dos_mode(conn, fname, &st))) {
1976 DEBUG(10,("call_trans2setfilepathinfo: file %s : setting dos mode %x\n",
1979 if(file_chmod(conn, fname, mode, NULL)) {
1980 DEBUG(2,("chmod of %s failed (%s)\n", fname, strerror(errno)));
1981 return(UNIXERROR(ERRDOS,ERRnoaccess));
1985 if(size != st.st_size) {
1987 DEBUG(10,("call_trans2setfilepathinfo: file %s : setting new size to %.0f\n",
1988 fname, (double)size ));
1991 fd = conn->vfs_ops.open(dos_to_unix(fname,False),O_RDWR,0);
1993 return(UNIXERROR(ERRDOS,ERRbadpath));
1994 set_filelen(fd, size); /* tpot vfs */
1995 conn->vfs_ops.close(fd);
1997 set_filelen(fd, size); /* tpot vfs */
2001 set_filelen_write_cache(fsp, size);
2006 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
2011 /****************************************************************************
2012 reply to a TRANS2_MKDIR (make directory with extended attributes).
2013 ****************************************************************************/
2014 static int call_trans2mkdir(connection_struct *conn,
2015 char *inbuf, char *outbuf, int length, int bufsize,
2016 char **pparams, char **ppdata)
2018 char *params = *pparams;
2021 BOOL bad_path = False;
2023 if (!CAN_WRITE(conn))
2024 return(ERROR(ERRSRV,ERRaccess));
2026 pstrcpy(directory, ¶ms[4]);
2028 DEBUG(3,("call_trans2mkdir : name = %s\n", directory));
2030 unix_convert(directory,conn,0,&bad_path,NULL);
2031 if (check_name(directory,conn))
2032 ret = conn->vfs_ops.mkdir(dos_to_unix(directory,False),
2033 unix_mode(conn,aDIR,directory));
2037 DEBUG(5,("call_trans2mkdir error (%s)\n", strerror(errno)));
2038 if((errno == ENOENT) && bad_path)
2040 unix_ERR_class = ERRDOS;
2041 unix_ERR_code = ERRbadpath;
2043 return(UNIXERROR(ERRDOS,ERRnoaccess));
2046 /* Realloc the parameter and data sizes */
2047 params = *pparams = Realloc(*pparams,2);
2049 return(ERROR(ERRDOS,ERRnomem));
2053 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
2058 /****************************************************************************
2059 reply to a TRANS2_FINDNOTIFYFIRST (start monitoring a directory for changes)
2060 We don't actually do this - we just send a null response.
2061 ****************************************************************************/
2062 static int call_trans2findnotifyfirst(connection_struct *conn,
2063 char *inbuf, char *outbuf,
2064 int length, int bufsize,
2065 char **pparams, char **ppdata)
2067 static uint16 fnf_handle = 257;
2068 char *params = *pparams;
2069 uint16 info_level = SVAL(params,4);
2071 DEBUG(3,("call_trans2findnotifyfirst - info_level %d\n", info_level));
2079 return(ERROR(ERRDOS,ERRunknownlevel));
2082 /* Realloc the parameter and data sizes */
2083 params = *pparams = Realloc(*pparams,6);
2085 return(ERROR(ERRDOS,ERRnomem));
2087 SSVAL(params,0,fnf_handle);
2088 SSVAL(params,2,0); /* No changes */
2089 SSVAL(params,4,0); /* No EA errors */
2096 send_trans2_replies(outbuf, bufsize, params, 6, *ppdata, 0);
2101 /****************************************************************************
2102 reply to a TRANS2_FINDNOTIFYNEXT (continue monitoring a directory for
2103 changes). Currently this does nothing.
2104 ****************************************************************************/
2105 static int call_trans2findnotifynext(connection_struct *conn,
2106 char *inbuf, char *outbuf,
2107 int length, int bufsize,
2108 char **pparams, char **ppdata)
2110 char *params = *pparams;
2112 DEBUG(3,("call_trans2findnotifynext\n"));
2114 /* Realloc the parameter and data sizes */
2115 params = *pparams = Realloc(*pparams,4);
2117 return(ERROR(ERRDOS,ERRnomem));
2119 SSVAL(params,0,0); /* No changes */
2120 SSVAL(params,2,0); /* No EA errors */
2122 send_trans2_replies(outbuf, bufsize, params, 4, *ppdata, 0);
2127 /****************************************************************************
2128 reply to a TRANS2_GET_DFS_REFERRAL - Shirish Kalele <kalele@veritas.com>
2129 ****************************************************************************/
2130 static int call_trans2getdfsreferral(connection_struct *conn, char* inbuf,
2131 char* outbuf, int length, int bufsize,
2132 char** pparams, char** ppdata)
2134 char *params = *pparams;
2135 enum remote_arch_types ra_type = get_remote_arch();
2136 BOOL NT_arch = ((ra_type == RA_WINNT) || (ra_type == RA_WIN2K));
2139 int max_referral_level = SVAL(params,0);
2142 DEBUG(10,("call_trans2getdfsreferral\n"));
2144 if(!lp_host_msdfs())
2145 return(ERROR(ERRDOS,ERRbadfunc));
2147 /* if pathname is in UNICODE, convert to DOS */
2148 /* NT always sends in UNICODE, may not set UNICODE flag */
2149 if(NT_arch || (SVAL(inbuf,smb_flg2) & FLAGS2_UNICODE_STRINGS))
2151 unistr_to_dos(pathname, ¶ms[2]);
2152 DEBUG(10,("UNICODE referral for %s\n",pathname));
2155 pstrcpy(pathname,¶ms[2]);
2157 if((reply_size = setup_dfs_referral(pathname,max_referral_level,ppdata)) < 0)
2158 return(ERROR(ERRDOS,ERRbadfile));
2160 SSVAL(outbuf,smb_flg2,SVAL(outbuf,smb_flg2) | FLAGS2_UNICODE_STRINGS |
2161 FLAGS2_DFS_PATHNAMES);
2162 send_trans2_replies(outbuf,bufsize,0,0,*ppdata,reply_size);
2168 /****************************************************************************
2169 reply to a SMBfindclose (stop trans2 directory search)
2170 ****************************************************************************/
2171 int reply_findclose(connection_struct *conn,
2172 char *inbuf,char *outbuf,int length,int bufsize)
2175 int dptr_num=SVALS(inbuf,smb_vwv0);
2177 DEBUG(3,("reply_findclose, dptr_num = %d\n", dptr_num));
2179 dptr_close(&dptr_num);
2181 outsize = set_message(outbuf,0,0,True);
2183 DEBUG(3,("SMBfindclose dptr_num = %d\n", dptr_num));
2188 /****************************************************************************
2189 reply to a SMBfindnclose (stop FINDNOTIFYFIRST directory search)
2190 ****************************************************************************/
2191 int reply_findnclose(connection_struct *conn,
2192 char *inbuf,char *outbuf,int length,int bufsize)
2197 dptr_num = SVAL(inbuf,smb_vwv0);
2199 DEBUG(3,("reply_findnclose, dptr_num = %d\n", dptr_num));
2201 /* We never give out valid handles for a
2202 findnotifyfirst - so any dptr_num is ok here.
2205 outsize = set_message(outbuf,0,0,True);
2207 DEBUG(3,("SMB_findnclose dptr_num = %d\n", dptr_num));
2213 /****************************************************************************
2214 reply to a SMBtranss2 - just ignore it!
2215 ****************************************************************************/
2216 int reply_transs2(connection_struct *conn,
2217 char *inbuf,char *outbuf,int length,int bufsize)
2219 DEBUG(4,("Ignoring transs2 of length %d\n",length));
2223 /****************************************************************************
2224 reply to a SMBtrans2
2225 ****************************************************************************/
2226 int reply_trans2(connection_struct *conn,
2227 char *inbuf,char *outbuf,int length,int bufsize)
2230 unsigned int total_params = SVAL(inbuf, smb_tpscnt);
2231 unsigned int total_data =SVAL(inbuf, smb_tdscnt);
2233 unsigned int max_param_reply = SVAL(inbuf, smb_mprcnt);
2234 unsigned int max_data_reply = SVAL(inbuf, smb_mdrcnt);
2235 unsigned int max_setup_fields = SVAL(inbuf, smb_msrcnt);
2236 BOOL close_tid = BITSETW(inbuf+smb_flags,0);
2237 BOOL no_final_response = BITSETW(inbuf+smb_flags,1);
2238 int32 timeout = IVALS(inbuf,smb_timeout);
2240 unsigned int suwcnt = SVAL(inbuf, smb_suwcnt);
2241 unsigned int tran_call = SVAL(inbuf, smb_setup0);
2242 char *params = NULL, *data = NULL;
2243 int num_params, num_params_sofar, num_data, num_data_sofar;
2245 if(global_oplock_break && (tran_call == TRANSACT2_OPEN)) {
2246 /* Queue this open message as we are the process of an
2249 DEBUG(2,("reply_trans2: queueing message trans2open due to being "));
2250 DEBUGADD(2,( "in oplock break state.\n"));
2252 push_oplock_pending_smb_message(inbuf, length);
2256 outsize = set_message(outbuf,0,0,True);
2258 /* All trans2 messages we handle have smb_sucnt == 1 - ensure this
2259 is so as a sanity check */
2261 DEBUG(2,("Invalid smb_sucnt in trans2 call\n"));
2262 return(ERROR(ERRSRV,ERRerror));
2265 /* Allocate the space for the maximum needed parameters and data */
2266 if (total_params > 0)
2267 params = (char *)malloc(total_params);
2269 data = (char *)malloc(total_data);
2271 if ((total_params && !params) || (total_data && !data)) {
2272 DEBUG(2,("Out of memory in reply_trans2\n"));
2277 return(ERROR(ERRDOS,ERRnomem));
2280 /* Copy the param and data bytes sent with this request into
2281 the params buffer */
2282 num_params = num_params_sofar = SVAL(inbuf,smb_pscnt);
2283 num_data = num_data_sofar = SVAL(inbuf, smb_dscnt);
2285 if (num_params > total_params || num_data > total_data)
2286 exit_server("invalid params in reply_trans2");
2289 memcpy( params, smb_base(inbuf) + SVAL(inbuf, smb_psoff), num_params);
2291 memcpy( data, smb_base(inbuf) + SVAL(inbuf, smb_dsoff), num_data);
2293 if(num_data_sofar < total_data || num_params_sofar < total_params) {
2294 /* We need to send an interim response then receive the rest
2295 of the parameter/data bytes */
2296 outsize = set_message(outbuf,0,0,True);
2297 send_smb(Client,outbuf);
2299 while (num_data_sofar < total_data ||
2300 num_params_sofar < total_params) {
2303 ret = receive_next_smb(inbuf,bufsize,SMB_SECONDARY_WAIT);
2306 (CVAL(inbuf, smb_com) != SMBtranss2)) || !ret) {
2307 outsize = set_message(outbuf,0,0,True);
2309 DEBUG(0,("reply_trans2: Invalid secondary trans2 packet\n"));
2311 DEBUG(0,("reply_trans2: %s in getting secondary trans2 response.\n",
2312 (smb_read_error == READ_ERROR) ? "error" : "timeout" ));
2317 return(ERROR(ERRSRV,ERRerror));
2320 /* Revise total_params and total_data in case
2321 they have changed downwards */
2322 total_params = SVAL(inbuf, smb_tpscnt);
2323 total_data = SVAL(inbuf, smb_tdscnt);
2324 num_params_sofar += (num_params = SVAL(inbuf,smb_spscnt));
2325 num_data_sofar += ( num_data = SVAL(inbuf, smb_sdscnt));
2326 if (num_params_sofar > total_params || num_data_sofar > total_data)
2327 exit_server("data overflow in trans2");
2329 memcpy( ¶ms[ SVAL(inbuf, smb_spsdisp)],
2330 smb_base(inbuf) + SVAL(inbuf, smb_spsoff), num_params);
2331 memcpy( &data[SVAL(inbuf, smb_sdsdisp)],
2332 smb_base(inbuf)+ SVAL(inbuf, smb_sdsoff), num_data);
2336 if (Protocol >= PROTOCOL_NT1) {
2337 uint16 flg2 = SVAL(outbuf,smb_flg2);
2338 SSVAL(outbuf,smb_flg2,flg2 | 0x40); /* IS_LONG_NAME */
2341 /* Now we must call the relevant TRANS2 function */
2343 case TRANSACT2_OPEN:
2344 outsize = call_trans2open(conn,
2345 inbuf, outbuf, bufsize,
2349 case TRANSACT2_FINDFIRST:
2350 outsize = call_trans2findfirst(conn, inbuf, outbuf,
2351 bufsize, ¶ms, &data);
2354 case TRANSACT2_FINDNEXT:
2355 outsize = call_trans2findnext(conn, inbuf, outbuf,
2360 case TRANSACT2_QFSINFO:
2361 outsize = call_trans2qfsinfo(conn, inbuf, outbuf,
2362 length, bufsize, ¶ms,
2366 case TRANSACT2_SETFSINFO:
2367 outsize = call_trans2setfsinfo(conn, inbuf, outbuf,
2372 case TRANSACT2_QPATHINFO:
2373 case TRANSACT2_QFILEINFO:
2374 outsize = call_trans2qfilepathinfo(conn, inbuf, outbuf,
2376 ¶ms, &data, total_data);
2378 case TRANSACT2_SETPATHINFO:
2379 case TRANSACT2_SETFILEINFO:
2380 outsize = call_trans2setfilepathinfo(conn, inbuf, outbuf,
2386 case TRANSACT2_FINDNOTIFYFIRST:
2387 outsize = call_trans2findnotifyfirst(conn, inbuf, outbuf,
2392 case TRANSACT2_FINDNOTIFYNEXT:
2393 outsize = call_trans2findnotifynext(conn, inbuf, outbuf,
2397 case TRANSACT2_MKDIR:
2398 outsize = call_trans2mkdir(conn, inbuf, outbuf, length,
2399 bufsize, ¶ms, &data);
2402 case TRANSACT2_GET_DFS_REFERRAL:
2403 outsize = call_trans2getdfsreferral(conn,inbuf,outbuf,length,
2404 bufsize, ¶ms, &data);
2407 /* Error in request */
2408 DEBUG(2,("Unknown request %d in trans2 call\n", tran_call));
2413 return (ERROR(ERRSRV,ERRerror));
2416 /* As we do not know how many data packets will need to be
2417 returned here the various call_trans2xxxx calls
2418 must send their own. Thus a call_trans2xxx routine only
2419 returns a value other than -1 when it wants to send
2427 return outsize; /* If a correct response was needed the
2428 call_trans2xxx calls have already sent
2429 it. If outsize != -1 then it is returning */