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,&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;
324 int nt_extmode; /* Used for NT connections instead of mode */
325 BOOL needslash = ( conn->dirpath[strlen(conn->dirpath) -1] != '/');
328 *out_of_space = False;
329 *got_exact_match = False;
334 p = strrchr(path_mask,'/');
343 pstrcpy(mask, path_mask);
349 /* Needed if we run out of space */
350 prev_dirpos = TellDir(conn->dirptr);
351 dname = ReadDirName(conn->dirptr);
354 * Due to bugs in NT client redirectors we are not using
355 * resume keys any more - set them to zero.
356 * Check out the related comments in findfirst/findnext.
362 DEBUG(8,("get_lanman2_dir_entry:readdir on dirptr 0x%lx now at offset %d\n",
363 (long)conn->dirptr,TellDir(conn->dirptr)));
368 pstrcpy(fname,dname);
370 if(!(got_match = *got_exact_match = exact_match(fname, mask, case_sensitive)))
371 got_match = mask_match(fname, mask, case_sensitive, True);
373 if(!got_match && !is_8_3(fname, False)) {
376 * It turns out that NT matches wildcards against
377 * both long *and* short names. This may explain some
378 * of the wildcard wierdness from old DOS clients
379 * that some people have been seeing.... JRA.
383 pstrcpy( newname, fname);
384 name_map_mangle( newname, True, False, SNUM(conn));
385 if(!(got_match = *got_exact_match = exact_match(newname, mask, case_sensitive)))
386 got_match = mask_match(newname, mask, case_sensitive, True);
391 BOOL isdots = (strequal(fname,"..") || strequal(fname,"."));
392 if (dont_descend && !isdots)
395 pstrcpy(pathreal,conn->dirpath);
397 pstrcat(pathreal,"/");
398 pstrcat(pathreal,dname);
399 if (conn->vfs_ops.stat(dos_to_unix(pathreal,False),&sbuf) != 0)
401 DEBUG(5,("get_lanman2_dir_entry:Couldn't stat [%s] (%s)\n",pathreal,strerror(errno)));
405 mode = dos_mode(conn,pathreal,&sbuf);
407 if (!dir_check_ftype(conn,mode,&sbuf,dirtype)) {
408 DEBUG(5,("[%s] attribs didn't match %x\n",fname,dirtype));
413 mdate = sbuf.st_mtime;
414 adate = sbuf.st_atime;
415 cdate = get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(conn)));
419 DEBUG(5,("get_lanman2_dir_entry found %s fname=%s\n",pathreal,fname));
425 name_map_mangle(fname,False,True,SNUM(conn));
430 nt_extmode = mode ? mode : FILE_ATTRIBUTE_NORMAL;
435 if(requires_resume_key) {
439 put_dos_date2(p,l1_fdateCreation,cdate);
440 put_dos_date2(p,l1_fdateLastAccess,adate);
441 put_dos_date2(p,l1_fdateLastWrite,mdate);
442 SIVAL(p,l1_cbFile,(uint32)size);
443 SIVAL(p,l1_cbFileAlloc,SMB_ROUNDUP(size,1024));
444 SSVAL(p,l1_attrFile,mode);
445 SCVAL(p,l1_cchName,strlen(fname));
446 pstrcpy(p + l1_achName, fname);
447 nameptr = p + l1_achName;
448 p += l1_achName + strlen(fname) + 1;
453 if(requires_resume_key) {
457 put_dos_date2(p,l2_fdateCreation,cdate);
458 put_dos_date2(p,l2_fdateLastAccess,adate);
459 put_dos_date2(p,l2_fdateLastWrite,mdate);
460 SIVAL(p,l2_cbFile,(uint32)size);
461 SIVAL(p,l2_cbFileAlloc,SMB_ROUNDUP(size,1024));
462 SSVAL(p,l2_attrFile,mode);
463 SIVAL(p,l2_cbList,0); /* No extended attributes */
464 SCVAL(p,l2_cchName,strlen(fname));
465 pstrcpy(p + l2_achName, fname);
466 nameptr = p + l2_achName;
467 p += l2_achName + strlen(fname) + 1;
472 put_dos_date2(p,4,cdate);
473 put_dos_date2(p,8,adate);
474 put_dos_date2(p,12,mdate);
475 SIVAL(p,16,(uint32)size);
476 SIVAL(p,20,SMB_ROUNDUP(size,1024));
479 CVAL(p,30) = strlen(fname);
480 pstrcpy(p+31, fname);
482 p += 31 + strlen(fname) + 1;
486 if(requires_resume_key) {
490 SIVAL(p,0,33+strlen(fname)+1);
491 put_dos_date2(p,4,cdate);
492 put_dos_date2(p,8,adate);
493 put_dos_date2(p,12,mdate);
494 SIVAL(p,16,(uint32)size);
495 SIVAL(p,20,SMB_ROUNDUP(size,1024));
497 CVAL(p,32) = strlen(fname);
498 pstrcpy(p + 33, fname);
500 p += 33 + strlen(fname) + 1;
503 case SMB_FIND_FILE_BOTH_DIRECTORY_INFO:
504 was_8_3 = is_8_3(fname, True);
505 len = 94+strlen(fname);
506 len = (len + 3) & ~3;
507 SIVAL(p,0,len); p += 4;
508 SIVAL(p,0,reskey); p += 4;
509 put_long_date(p,cdate); p += 8;
510 put_long_date(p,adate); p += 8;
511 put_long_date(p,mdate); p += 8;
512 put_long_date(p,mdate); p += 8;
516 SIVAL(p,0,nt_extmode); p += 4;
517 SIVAL(p,0,strlen(fname)); p += 4;
518 SIVAL(p,0,0); p += 4;
521 if (!name_map_mangle(p+2,True,True,SNUM(conn)))
526 SSVAL(p,0,strlen(p+2));
529 pstrcpy(p,fname); p += strlen(p);
533 case SMB_FIND_FILE_DIRECTORY_INFO:
534 len = 64+strlen(fname);
535 len = (len + 3) & ~3;
536 SIVAL(p,0,len); p += 4;
537 SIVAL(p,0,reskey); p += 4;
538 put_long_date(p,cdate); p += 8;
539 put_long_date(p,adate); p += 8;
540 put_long_date(p,mdate); p += 8;
541 put_long_date(p,mdate); p += 8;
545 SIVAL(p,0,nt_extmode); p += 4;
546 SIVAL(p,0,strlen(fname)); p += 4;
552 case SMB_FIND_FILE_FULL_DIRECTORY_INFO:
553 len = 68+strlen(fname);
554 len = (len + 3) & ~3;
555 SIVAL(p,0,len); p += 4;
556 SIVAL(p,0,reskey); p += 4;
557 put_long_date(p,cdate); p += 8;
558 put_long_date(p,adate); p += 8;
559 put_long_date(p,mdate); p += 8;
560 put_long_date(p,mdate); p += 8;
564 SIVAL(p,0,nt_extmode); p += 4;
565 SIVAL(p,0,strlen(fname)); p += 4;
566 SIVAL(p,0,0); p += 4;
571 case SMB_FIND_FILE_NAMES_INFO:
572 len = 12+strlen(fname);
573 len = (len + 3) & ~3;
574 SIVAL(p,0,len); p += 4;
575 SIVAL(p,0,reskey); p += 4;
576 SIVAL(p,0,strlen(fname)); p += 4;
586 if (PTR_DIFF(p,pdata) > space_remaining) {
587 /* Move the dirptr back to prev_dirpos */
588 SeekDir(conn->dirptr, prev_dirpos);
589 *out_of_space = True;
590 DEBUG(9,("get_lanman2_dir_entry: out of space\n"));
591 return False; /* Not finished - just out of space */
594 /* Setup the last_filename pointer, as an offset from base_data */
595 *last_name_off = PTR_DIFF(nameptr,base_data);
596 /* Advance the data pointer to the next slot */
602 /****************************************************************************
603 Convert the directory masks formated for the wire.
604 ****************************************************************************/
606 void mask_convert( char *mask)
609 * We know mask is a pstring.
615 if(p[1] != '"' && p[1] != '.') {
616 pstrcpy( expnd, p+1 );
619 safe_strcpy( p+1, expnd, sizeof(pstring) - (p - mask) - 2);
623 if (*p == '>') *p = '?';
624 if (*p == '"') *p = '.';
629 /****************************************************************************
630 Reply to a TRANS2_FINDFIRST.
631 ****************************************************************************/
633 static int call_trans2findfirst(connection_struct *conn,
634 char *inbuf, char *outbuf, int bufsize,
635 char **pparams, char **ppdata)
637 /* We must be careful here that we don't return more than the
638 allowed number of data bytes. If this means returning fewer than
639 maxentries then so be it. We assume that the redirector has
640 enough room for the fixed number of parameter bytes it has
642 uint32 max_data_bytes = SVAL(inbuf, smb_mdrcnt);
643 char *params = *pparams;
644 char *pdata = *ppdata;
645 int dirtype = SVAL(params,0);
646 int maxentries = SVAL(params,2);
647 BOOL close_after_first = BITSETW(params+4,0);
648 BOOL close_if_end = BITSETW(params+4,1);
649 BOOL requires_resume_key = BITSETW(params+4,2);
650 int info_level = SVAL(params,6);
658 BOOL finished = False;
659 BOOL dont_descend = False;
660 BOOL out_of_space = False;
662 BOOL bad_path = False;
664 *directory = *mask = 0;
666 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",
667 dirtype, maxentries, close_after_first, close_if_end, requires_resume_key,
668 info_level, max_data_bytes));
676 case SMB_FIND_FILE_DIRECTORY_INFO:
677 case SMB_FIND_FILE_FULL_DIRECTORY_INFO:
678 case SMB_FIND_FILE_NAMES_INFO:
679 case SMB_FIND_FILE_BOTH_DIRECTORY_INFO:
682 return(ERROR(ERRDOS,ERRunknownlevel));
685 pstrcpy(directory, params + 12); /* Complete directory path with
686 wildcard mask appended */
688 RESOLVE_FINDFIRST_DFSPATH(directory, conn, inbuf, outbuf);
690 DEBUG(5,("path=%s\n",directory));
692 unix_convert(directory,conn,0,&bad_path,NULL);
693 if(!check_name(directory,conn)) {
694 if((errno == ENOENT) && bad_path)
696 unix_ERR_class = ERRDOS;
697 unix_ERR_code = ERRbadpath;
701 /* Ugly - NT specific hack - maybe not needed ? (JRA) */
702 if((errno == ENOTDIR) && (Protocol >= PROTOCOL_NT1) &&
703 (get_remote_arch() == RA_WINNT))
705 unix_ERR_class = ERRDOS;
706 unix_ERR_code = ERRbaddirectory;
710 return(UNIXERROR(ERRDOS,ERRbadpath));
713 p = strrchr(directory,'/');
715 pstrcpy(mask,directory);
716 pstrcpy(directory,"./");
722 DEBUG(5,("dir=%s, mask = %s\n",directory, mask));
724 pdata = *ppdata = Realloc(*ppdata, max_data_bytes + 1024);
726 return(ERROR(ERRDOS,ERRnomem));
727 memset((char *)pdata,'\0',max_data_bytes + 1024);
729 /* Realloc the params space */
730 params = *pparams = Realloc(*pparams, 10);
732 return(ERROR(ERRDOS,ERRnomem));
734 dptr_num = dptr_create(conn,directory, False, True ,SVAL(inbuf,smb_pid));
736 return(UNIXERROR(ERRDOS,ERRbadfile));
738 /* Convert the formatted mask. */
741 /* Save the wildcard match and attribs we are using on this directory -
742 needed as lanman2 assumes these are being saved between calls */
744 if(!(wcard = strdup(mask))) {
745 dptr_close(&dptr_num);
746 return(ERROR(ERRDOS,ERRnomem));
749 dptr_set_wcard(dptr_num, wcard);
750 dptr_set_attr(dptr_num, dirtype);
752 DEBUG(4,("dptr_num is %d, wcard = %s, attr = %d\n",dptr_num, wcard, dirtype));
754 /* We don't need to check for VOL here as this is returned by
755 a different TRANS2 call. */
757 DEBUG(8,("dirpath=<%s> dontdescend=<%s>\n",
758 conn->dirpath,lp_dontdescend(SNUM(conn))));
759 if (in_list(conn->dirpath,lp_dontdescend(SNUM(conn)),case_sensitive))
763 space_remaining = max_data_bytes;
764 out_of_space = False;
766 for (i=0;(i<maxentries) && !finished && !out_of_space;i++)
768 BOOL got_exact_match;
770 /* this is a heuristic to avoid seeking the dirptr except when
771 absolutely necessary. It allows for a filename of about 40 chars */
772 if (space_remaining < DIRLEN_GUESS && numentries > 0)
779 finished = !get_lanman2_dir_entry(conn,mask,dirtype,info_level,
780 requires_resume_key,dont_descend,
781 &p,pdata,space_remaining, &out_of_space, &got_exact_match,
785 if (finished && out_of_space)
788 if (!finished && !out_of_space)
792 * As an optimisation if we know we aren't looking
793 * for a wildcard name (ie. the name matches the wildcard exactly)
794 * then we can finish on any (first) match.
795 * This speeds up large directory searches. JRA.
801 space_remaining = max_data_bytes - PTR_DIFF(p,pdata);
804 /* Check if we can close the dirptr */
805 if(close_after_first || (finished && close_if_end))
807 DEBUG(5,("call_trans2findfirst - (2) closing dptr_num %d\n", dptr_num));
808 dptr_close(&dptr_num);
812 * If there are no matching entries we must return ERRDOS/ERRbadfile -
813 * from observation of NT.
818 dptr_close(&dptr_num);
819 return(ERROR(ERRDOS,ERRbadfile));
822 /* At this point pdata points to numentries directory entries. */
824 /* Set up the return parameter block */
825 SSVAL(params,0,dptr_num);
826 SSVAL(params,2,numentries);
827 SSVAL(params,4,finished);
828 SSVAL(params,6,0); /* Never an EA error */
829 SSVAL(params,8,last_name_off);
831 send_trans2_replies( outbuf, bufsize, params, 10, pdata, PTR_DIFF(p,pdata));
833 if ((! *directory) && dptr_path(dptr_num))
834 slprintf(directory,sizeof(directory)-1, "(%s)",dptr_path(dptr_num));
836 DEBUG( 4, ( "%s mask=%s directory=%s dirtype=%d numentries=%d\n",
837 smb_fn_name(CVAL(inbuf,smb_com)),
838 mask, directory, dirtype, numentries ) );
841 * Force a name mangle here to ensure that the
842 * mask as an 8.3 name is top of the mangled cache.
843 * The reasons for this are subtle. Don't remove
844 * this code unless you know what you are doing
845 * (see PR#13758). JRA.
848 if(!is_8_3( mask, False))
849 name_map_mangle(mask, True, True, SNUM(conn));
855 /****************************************************************************
856 reply to a TRANS2_FINDNEXT
857 ****************************************************************************/
858 static int call_trans2findnext(connection_struct *conn,
859 char *inbuf, char *outbuf,
860 int length, int bufsize,
861 char **pparams, char **ppdata)
863 /* We must be careful here that we don't return more than the
864 allowed number of data bytes. If this means returning fewer than
865 maxentries then so be it. We assume that the redirector has
866 enough room for the fixed number of parameter bytes it has
868 int max_data_bytes = SVAL(inbuf, smb_mdrcnt);
869 char *params = *pparams;
870 char *pdata = *ppdata;
871 int dptr_num = SVAL(params,0);
872 int maxentries = SVAL(params,2);
873 uint16 info_level = SVAL(params,4);
874 uint32 resume_key = IVAL(params,6);
875 BOOL close_after_request = BITSETW(params+10,0);
876 BOOL close_if_end = BITSETW(params+10,1);
877 BOOL requires_resume_key = BITSETW(params+10,2);
878 BOOL continue_bit = BITSETW(params+10,3);
885 int i, last_name_off=0;
886 BOOL finished = False;
887 BOOL dont_descend = False;
888 BOOL out_of_space = False;
891 *mask = *directory = *resume_name = 0;
893 pstrcpy( resume_name, params+12);
895 DEBUG(3,("call_trans2findnext: dirhandle = %d, max_data_bytes = %d, maxentries = %d, \
896 close_after_request=%d, close_if_end = %d requires_resume_key = %d \
897 resume_key = %d resume name = %s continue=%d level = %d\n",
898 dptr_num, max_data_bytes, maxentries, close_after_request, close_if_end,
899 requires_resume_key, resume_key, resume_name, continue_bit, info_level));
907 case SMB_FIND_FILE_DIRECTORY_INFO:
908 case SMB_FIND_FILE_FULL_DIRECTORY_INFO:
909 case SMB_FIND_FILE_NAMES_INFO:
910 case SMB_FIND_FILE_BOTH_DIRECTORY_INFO:
913 return(ERROR(ERRDOS,ERRunknownlevel));
916 pdata = *ppdata = Realloc( *ppdata, max_data_bytes + 1024);
918 return(ERROR(ERRDOS,ERRnomem));
919 memset((char *)pdata,'\0',max_data_bytes + 1024);
921 /* Realloc the params space */
922 params = *pparams = Realloc(*pparams, 6*SIZEOFWORD);
924 return(ERROR(ERRDOS,ERRnomem));
926 /* Check that the dptr is valid */
927 if(!(conn->dirptr = dptr_fetch_lanman2(dptr_num)))
928 return(ERROR(ERRDOS,ERRnofiles));
930 string_set(&conn->dirpath,dptr_path(dptr_num));
932 /* Get the wildcard mask from the dptr */
933 if((p = dptr_wcard(dptr_num))== NULL) {
934 DEBUG(2,("dptr_num %d has no wildcard\n", dptr_num));
935 return (ERROR(ERRDOS,ERRnofiles));
938 pstrcpy(directory,conn->dirpath);
940 /* Get the attr mask from the dptr */
941 dirtype = dptr_attr(dptr_num);
943 DEBUG(3,("dptr_num is %d, mask = %s, attr = %x, dirptr=(0x%lX,%d)\n",
944 dptr_num, mask, dirtype,
946 TellDir(conn->dirptr)));
948 /* We don't need to check for VOL here as this is returned by
949 a different TRANS2 call. */
951 DEBUG(8,("dirpath=<%s> dontdescend=<%s>\n",conn->dirpath,lp_dontdescend(SNUM(conn))));
952 if (in_list(conn->dirpath,lp_dontdescend(SNUM(conn)),case_sensitive))
956 space_remaining = max_data_bytes;
957 out_of_space = False;
960 * Seek to the correct position. We no longer use the resume key but
961 * depend on the last file name instead.
963 if(requires_resume_key && *resume_name && !continue_bit)
966 * Fix for NT redirector problem triggered by resume key indexes
967 * changing between directory scans. We now return a resume key of 0
968 * and instead look for the filename to continue from (also given
969 * to us by NT/95/smbfs/smbclient). If no other scans have been done between the
970 * findfirst/findnext (as is usual) then the directory pointer
971 * should already be at the correct place. Check this by scanning
972 * backwards looking for an exact (ie. case sensitive) filename match.
973 * If we get to the beginning of the directory and haven't found it then scan
974 * forwards again looking for a match. JRA.
977 int current_pos, start_pos;
979 void *dirptr = conn->dirptr;
980 start_pos = TellDir(dirptr);
981 for(current_pos = start_pos; current_pos >= 0; current_pos--)
983 DEBUG(7,("call_trans2findnext: seeking to pos %d\n", current_pos));
985 SeekDir(dirptr, current_pos);
986 dname = ReadDirName(dirptr);
989 * Remember, name_map_mangle is called by
990 * get_lanman2_dir_entry(), so the resume name
991 * could be mangled. Ensure we do the same
996 name_map_mangle( dname, False, True, SNUM(conn));
998 if(dname && strcsequal( resume_name, dname))
1000 SeekDir(dirptr, current_pos+1);
1001 DEBUG(7,("call_trans2findnext: got match at pos %d\n", current_pos+1 ));
1007 * Scan forward from start if not found going backwards.
1012 DEBUG(7,("call_trans2findnext: notfound: seeking to pos %d\n", start_pos));
1013 SeekDir(dirptr, start_pos);
1014 for(current_pos = start_pos; (dname = ReadDirName(dirptr)) != NULL; SeekDir(dirptr,++current_pos))
1017 * Remember, name_map_mangle is called by
1018 * get_lanman2_dir_entry(), so the resume name
1019 * could be mangled. Ensure we do the same
1024 name_map_mangle( dname, False, True, SNUM(conn));
1026 if(dname && strcsequal( resume_name, dname))
1028 SeekDir(dirptr, current_pos+1);
1029 DEBUG(7,("call_trans2findnext: got match at pos %d\n", current_pos+1 ));
1033 } /* end if current_pos */
1034 } /* end if requires_resume_key && !continue_bit */
1036 for (i=0;(i<(int)maxentries) && !finished && !out_of_space ;i++)
1038 BOOL got_exact_match;
1040 /* this is a heuristic to avoid seeking the dirptr except when
1041 absolutely necessary. It allows for a filename of about 40 chars */
1042 if (space_remaining < DIRLEN_GUESS && numentries > 0)
1044 out_of_space = True;
1049 finished = !get_lanman2_dir_entry(conn,mask,dirtype,info_level,
1050 requires_resume_key,dont_descend,
1051 &p,pdata,space_remaining, &out_of_space, &got_exact_match,
1055 if (finished && out_of_space)
1058 if (!finished && !out_of_space)
1062 * As an optimisation if we know we aren't looking
1063 * for a wildcard name (ie. the name matches the wildcard exactly)
1064 * then we can finish on any (first) match.
1065 * This speeds up large directory searches. JRA.
1071 space_remaining = max_data_bytes - PTR_DIFF(p,pdata);
1074 /* Check if we can close the dirptr */
1075 if(close_after_request || (finished && close_if_end))
1077 DEBUG(5,("call_trans2findnext: closing dptr_num = %d\n", dptr_num));
1078 dptr_close(&dptr_num); /* This frees up the saved mask */
1082 /* Set up the return parameter block */
1083 SSVAL(params,0,numentries);
1084 SSVAL(params,2,finished);
1085 SSVAL(params,4,0); /* Never an EA error */
1086 SSVAL(params,6,last_name_off);
1088 send_trans2_replies( outbuf, bufsize, params, 8, pdata, PTR_DIFF(p,pdata));
1090 if ((! *directory) && dptr_path(dptr_num))
1091 slprintf(directory,sizeof(directory)-1, "(%s)",dptr_path(dptr_num));
1093 DEBUG( 3, ( "%s mask=%s directory=%s dirtype=%d numentries=%d\n",
1094 smb_fn_name(CVAL(inbuf,smb_com)),
1095 mask, directory, dirtype, numentries ) );
1100 /****************************************************************************
1101 reply to a TRANS2_QFSINFO (query filesystem info)
1102 ****************************************************************************/
1104 static int call_trans2qfsinfo(connection_struct *conn,
1105 char *inbuf, char *outbuf,
1106 int length, int bufsize,
1107 char **pparams, char **ppdata)
1109 int max_data_bytes = SVAL(inbuf, smb_mdrcnt);
1110 char *pdata = *ppdata;
1111 char *params = *pparams;
1112 uint16 info_level = SVAL(params,0);
1115 char *vname = volume_label(SNUM(conn));
1116 int snum = SNUM(conn);
1117 char *fstype = lp_fstype(SNUM(conn));
1119 DEBUG(3,("call_trans2qfsinfo: level = %d\n", info_level));
1121 if(conn->vfs_ops.stat(".",&st)!=0) {
1122 DEBUG(2,("call_trans2qfsinfo: stat of . failed (%s)\n", strerror(errno)));
1123 return (ERROR(ERRSRV,ERRinvdevice));
1126 pdata = *ppdata = Realloc(*ppdata, max_data_bytes + 1024);
1127 memset((char *)pdata,'\0',max_data_bytes + 1024);
1133 SMB_BIG_UINT dfree,dsize,bsize;
1135 conn->vfs_ops.disk_free(".",False,&bsize,&dfree,&dsize);
1136 SIVAL(pdata,l1_idFileSystem,st.st_dev);
1137 SIVAL(pdata,l1_cSectorUnit,bsize/512);
1138 SIVAL(pdata,l1_cUnit,dsize);
1139 SIVAL(pdata,l1_cUnitAvail,dfree);
1140 SSVAL(pdata,l1_cbSector,512);
1141 DEBUG(5,("call_trans2qfsinfo : bsize=%u, id=%x, cSectorUnit=%u, cUnit=%u, cUnitAvail=%u, cbSector=%d\n",
1142 (unsigned int)bsize, (unsigned int)st.st_dev, ((unsigned int)bsize)/512, (unsigned int)dsize,
1143 (unsigned int)dfree, 512));
1148 /* Return volume name */
1149 int volname_len = MIN(strlen(vname),11);
1150 data_len = l2_vol_szVolLabel + volname_len + 1;
1152 * Add volume serial number - hash of a combination of
1153 * the called hostname and the service name.
1155 SIVAL(pdata,0,str_checksum(lp_servicename(snum)) ^ (str_checksum(local_machine)<<16) );
1156 SCVAL(pdata,l2_vol_cch,volname_len);
1157 StrnCpy(pdata+l2_vol_szVolLabel,vname,volname_len);
1158 DEBUG(5,("call_trans2qfsinfo : time = %x, namelen = %d, name = %s\n",
1159 (unsigned)st.st_ctime, volname_len,
1160 pdata+l2_vol_szVolLabel));
1163 case SMB_QUERY_FS_ATTRIBUTE_INFO:
1166 SIVAL(pdata,0,FILE_CASE_PRESERVED_NAMES|FILE_CASE_SENSITIVE_SEARCH|
1167 FILE_DEVICE_IS_MOUNTED|
1168 (lp_nt_acl_support() ? FILE_PERSISTENT_ACLS : 0)); /* FS ATTRIBUTES */
1169 #if 0 /* Old code. JRA. */
1170 SIVAL(pdata,0,0x4006); /* FS ATTRIBUTES == long filenames supported? */
1171 #endif /* Old code. */
1173 SIVAL(pdata,4,128); /* Max filename component length */
1174 fstype_len = dos_PutUniCode(pdata+12,unix_to_dos(fstype,False),sizeof(pstring), False);
1175 SIVAL(pdata,8,fstype_len);
1176 data_len = 12 + fstype_len;
1177 SSVAL(outbuf,smb_flg2,SVAL(outbuf,smb_flg2)|FLAGS2_UNICODE_STRINGS);
1180 case SMB_QUERY_FS_LABEL_INFO:
1181 data_len = 4 + strlen(vname);
1182 SIVAL(pdata,0,strlen(vname));
1183 pstrcpy(pdata+4,vname);
1185 case SMB_QUERY_FS_VOLUME_INFO:
1188 * Add volume serial number - hash of a combination of
1189 * the called hostname and the service name.
1191 SIVAL(pdata,8,str_checksum(lp_servicename(snum)) ^
1192 (str_checksum(local_machine)<<16));
1194 /* NT4 always serves this up as unicode but expects it to be
1195 * delivered as ascii! (tridge && JRA)
1197 if ((get_remote_arch() != RA_WIN2K) && (global_client_caps & CAP_NT_SMBS)) {
1198 data_len = 18 + strlen(vname);
1199 SIVAL(pdata,12,strlen(vname));
1200 pstrcpy(pdata+18,vname);
1202 data_len = 18 + 2*strlen(vname);
1203 SIVAL(pdata,12,strlen(vname)*2);
1204 dos_PutUniCode(pdata+18,unix_to_dos(vname,False),sizeof(pstring), False);
1205 SSVAL(outbuf,smb_flg2,SVAL(outbuf,smb_flg2)|FLAGS2_UNICODE_STRINGS);
1208 DEBUG(5,("call_trans2qfsinfo : SMB_QUERY_FS_VOLUME_INFO namelen = %d, vol = %s\n",
1209 (int)strlen(vname),vname));
1211 case SMB_QUERY_FS_SIZE_INFO:
1213 SMB_BIG_UINT dfree,dsize,bsize;
1215 conn->vfs_ops.disk_free(".",False,&bsize,&dfree,&dsize);
1216 SBIG_UINT(pdata,0,dsize);
1217 SBIG_UINT(pdata,8,dfree);
1218 SIVAL(pdata,16,bsize/512);
1219 SIVAL(pdata,20,512);
1222 case SMB_QUERY_FS_DEVICE_INFO:
1224 SIVAL(pdata,0,0); /* dev type */
1225 SIVAL(pdata,4,0); /* characteristics */
1227 case SMB_MAC_QUERY_FS_INFO:
1229 * Thursby MAC extension... ONLY on NTFS filesystems
1230 * once we do streams then we don't need this
1232 if (strequal(lp_fstype(SNUM(conn)),"NTFS")) {
1234 SIVAL(pdata,84,0x100); /* Don't support mac... */
1239 return(ERROR(ERRDOS,ERRunknownlevel));
1243 send_trans2_replies( outbuf, bufsize, params, 0, pdata, data_len);
1245 DEBUG( 4, ( "%s info_level = %d\n",
1246 smb_fn_name(CVAL(inbuf,smb_com)), info_level) );
1251 /****************************************************************************
1252 reply to a TRANS2_SETFSINFO (set filesystem info)
1253 ****************************************************************************/
1254 static int call_trans2setfsinfo(connection_struct *conn,
1255 char *inbuf, char *outbuf, int length,
1257 char **pparams, char **ppdata)
1259 /* Just say yes we did it - there is nothing that
1260 can be set here so it doesn't matter. */
1262 DEBUG(3,("call_trans2setfsinfo\n"));
1264 if (!CAN_WRITE(conn))
1265 return(ERROR(ERRSRV,ERRaccess));
1267 outsize = set_message(outbuf,10,0,True);
1272 /****************************************************************************
1273 Reply to a TRANS2_QFILEPATHINFO or TRANSACT2_QFILEINFO (query file info by
1274 file name or file id).
1275 ****************************************************************************/
1277 static int call_trans2qfilepathinfo(connection_struct *conn,
1278 char *inbuf, char *outbuf, int length,
1280 char **pparams,char **ppdata,
1283 int max_data_bytes = SVAL(inbuf, smb_mdrcnt);
1284 char *params = *pparams;
1285 char *pdata = *ppdata;
1286 uint16 tran_call = SVAL(inbuf, smb_setup0);
1290 unsigned int data_size;
1291 SMB_STRUCT_STAT sbuf;
1297 BOOL bad_path = False;
1298 BOOL delete_pending = False;
1300 if (tran_call == TRANSACT2_QFILEINFO) {
1301 files_struct *fsp = file_fsp(params,0);
1302 info_level = SVAL(params,2);
1304 DEBUG(3,("call_trans2qfilepathinfo: TRANSACT2_QFILEINFO: level = %d\n", info_level));
1306 if(fsp && fsp->open && (fsp->is_directory || fsp->stat_open)) {
1308 * This is actually a QFILEINFO on a directory
1309 * handle (returned from an NT SMB). NT5.0 seems
1310 * to do this call. JRA.
1312 fname = fsp->fsp_name;
1313 unix_convert(fname,conn,0,&bad_path,&sbuf);
1314 if (!check_name(fname,conn) ||
1315 (!VALID_STAT(sbuf) && conn->vfs_ops.stat(dos_to_unix(fname,False),&sbuf))) {
1316 DEBUG(3,("fileinfo of %s failed (%s)\n",fname,strerror(errno)));
1317 if((errno == ENOENT) && bad_path)
1319 unix_ERR_class = ERRDOS;
1320 unix_ERR_code = ERRbadpath;
1322 return(UNIXERROR(ERRDOS,ERRbadpath));
1325 delete_pending = fsp->directory_delete_on_close;
1329 * Original code - this is an open file.
1331 CHECK_FSP(fsp,conn);
1334 fname = fsp->fsp_name;
1335 if (fsp->conn->vfs_ops.fstat(fsp->fd,&sbuf) != 0) {
1336 DEBUG(3,("fstat of fnum %d failed (%s)\n",fsp->fnum, strerror(errno)));
1337 return(UNIXERROR(ERRDOS,ERRbadfid));
1339 if((pos = fsp->conn->vfs_ops.lseek(fsp->fd,0,SEEK_CUR)) == -1)
1340 return(UNIXERROR(ERRDOS,ERRnoaccess));
1342 delete_pending = fsp->delete_on_close;
1346 info_level = SVAL(params,0);
1348 DEBUG(3,("call_trans2qfilepathinfo: TRANSACT2_QPATHINFO: level = %d\n", info_level));
1351 pstrcpy(fname,¶ms[6]);
1353 RESOLVE_DFSPATH(fname, conn, inbuf, outbuf);
1355 unix_convert(fname,conn,0,&bad_path,&sbuf);
1356 if (!check_name(fname,conn) ||
1357 (!VALID_STAT(sbuf) && conn->vfs_ops.stat(dos_to_unix(fname,False),&sbuf))) {
1358 DEBUG(3,("fileinfo of %s failed (%s)\n",fname,strerror(errno)));
1359 if((errno == ENOENT) && bad_path)
1361 unix_ERR_class = ERRDOS;
1362 unix_ERR_code = ERRbadpath;
1364 return(UNIXERROR(ERRDOS,ERRbadpath));
1369 DEBUG(3,("call_trans2qfilepathinfo %s level=%d call=%d total_data=%d\n",
1370 fname,info_level,tran_call,total_data));
1372 p = strrchr(fname,'/');
1378 mode = dos_mode(conn,fname,&sbuf);
1379 size = sbuf.st_size;
1380 if (mode & aDIR) size = 0;
1382 /* from now on we only want the part after the / */
1385 params = *pparams = Realloc(*pparams,2);
1386 memset((char *)params,'\0',2);
1387 data_size = max_data_bytes + 1024;
1388 pdata = *ppdata = Realloc(*ppdata, data_size);
1390 if (total_data > 0 && IVAL(pdata,0) == total_data) {
1391 /* uggh, EAs for OS2 */
1392 DEBUG(4,("Rejecting EA request with total_data=%d\n",total_data));
1393 return(ERROR(ERRDOS,ERROR_EAS_NOT_SUPPORTED));
1396 memset((char *)pdata,'\0',data_size);
1400 case SMB_INFO_STANDARD:
1401 case SMB_INFO_QUERY_EA_SIZE:
1402 data_size = (info_level==1?22:26);
1403 put_dos_date2(pdata,l1_fdateCreation,get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(conn))));
1404 put_dos_date2(pdata,l1_fdateLastAccess,sbuf.st_atime);
1405 put_dos_date2(pdata,l1_fdateLastWrite,sbuf.st_mtime); /* write time */
1406 SIVAL(pdata,l1_cbFile,(uint32)size);
1407 SIVAL(pdata,l1_cbFileAlloc,SMB_ROUNDUP(size,1024));
1408 SSVAL(pdata,l1_attrFile,mode);
1409 SIVAL(pdata,l1_attrFile+2,4); /* this is what OS2 does */
1412 case SMB_INFO_QUERY_EAS_FROM_LIST:
1414 put_dos_date2(pdata,0,get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(conn))));
1415 put_dos_date2(pdata,4,sbuf.st_atime);
1416 put_dos_date2(pdata,8,sbuf.st_mtime);
1417 SIVAL(pdata,12,(uint32)size);
1418 SIVAL(pdata,16,SMB_ROUNDUP(size,1024));
1419 SIVAL(pdata,20,mode);
1422 case SMB_INFO_QUERY_ALL_EAS:
1424 SIVAL(pdata,0,data_size);
1428 return(ERROR(ERRDOS,ERRbadfunc)); /* os/2 needs this */
1430 case SMB_QUERY_FILE_BASIC_INFO:
1431 data_size = 36; /* w95 returns 40 bytes not 36 - why ?. */
1432 put_long_date(pdata,get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(conn))));
1433 put_long_date(pdata+8,sbuf.st_atime);
1434 put_long_date(pdata+16,sbuf.st_mtime); /* write time */
1435 put_long_date(pdata+24,sbuf.st_mtime); /* change time */
1436 SIVAL(pdata,32,mode);
1438 DEBUG(5,("SMB_QFBI - "));
1440 time_t create_time = get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(conn)));
1441 DEBUG(5,("create: %s ", ctime(&create_time)));
1443 DEBUG(5,("access: %s ", ctime(&sbuf.st_atime)));
1444 DEBUG(5,("write: %s ", ctime(&sbuf.st_mtime)));
1445 DEBUG(5,("change: %s ", ctime(&sbuf.st_mtime)));
1446 DEBUG(5,("mode: %x\n", mode));
1450 case SMB_QUERY_FILE_STANDARD_INFO:
1452 SOFF_T(pdata,0,size);
1453 SOFF_T(pdata,8,size);
1454 SIVAL(pdata,16,sbuf.st_nlink);
1456 CVAL(pdata,21) = (mode&aDIR)?1:0;
1459 case SMB_QUERY_FILE_EA_INFO:
1463 /* Get the 8.3 name - used if NT SMB was negotiated. */
1464 case SMB_QUERY_FILE_ALT_NAME_INFO:
1467 pstrcpy(short_name,p);
1468 /* Mangle if not already 8.3 */
1469 if(!is_8_3(short_name, True))
1471 if(!name_map_mangle(short_name,True,True,SNUM(conn)))
1474 strupper(short_name);
1475 l = strlen(short_name);
1476 dos_PutUniCode(pdata + 4, unix_to_dos(short_name,False),sizeof(pstring), False);
1477 data_size = 4 + (2*l);
1482 case SMB_QUERY_FILE_NAME_INFO:
1484 * The first part of this code is essential
1485 * to get security descriptors to work on mapped
1486 * drives. Don't ask how I discovered this unless
1487 * you like hearing about me suffering.... :-). JRA.
1489 if(strequal(".", fname) && (global_client_caps & CAP_UNICODE)) {
1491 SSVAL(outbuf,smb_flg2,SVAL(outbuf,smb_flg2)|FLAGS2_UNICODE_STRINGS);
1492 dos_PutUniCode(pdata + 4, unix_to_dos("\\",False),sizeof(pstring), False);
1494 pstrcpy(pdata+4,fname);
1500 case SMB_QUERY_FILE_ALLOCATION_INFO:
1501 case SMB_QUERY_FILE_END_OF_FILEINFO:
1503 SOFF_T(pdata,0,size);
1506 case SMB_QUERY_FILE_ALL_INFO:
1507 put_long_date(pdata,get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(conn))));
1508 put_long_date(pdata+8,sbuf.st_atime);
1509 put_long_date(pdata+16,sbuf.st_mtime); /* write time */
1510 put_long_date(pdata+24,sbuf.st_mtime); /* change time */
1511 SIVAL(pdata,32,mode);
1513 SOFF_T(pdata,0,size);
1514 SOFF_T(pdata,8,size);
1515 SIVAL(pdata,16,sbuf.st_nlink);
1516 CVAL(pdata,20) = delete_pending;
1517 CVAL(pdata,21) = (mode&aDIR)?1:0;
1519 SINO_T(pdata,0,(SMB_INO_T)sbuf.st_ino);
1520 pdata += 8; /* index number */
1521 pdata += 4; /* EA info */
1523 SIVAL(pdata,0,0xA9);
1525 SIVAL(pdata,0,0xd01BF);
1527 SOFF_T(pdata,0,pos); /* current offset */
1529 SIVAL(pdata,0,mode); /* is this the right sort of mode info? */
1531 pdata += 4; /* alignment */
1533 pstrcpy(pdata+4,fname);
1535 data_size = PTR_DIFF(pdata,(*ppdata));
1539 /* NT4 server just returns "invalid query" to this - if we try to answer
1540 it then NTws gets a BSOD! (tridge) */
1541 case SMB_QUERY_FILE_STREAM_INFO:
1544 SIVAL(pdata,4,size);
1545 SIVAL(pdata,12,size);
1547 pstrcpy(pdata+24,fname);
1552 return(ERROR(ERRDOS,ERRunknownlevel));
1555 send_trans2_replies( outbuf, bufsize, params, 2, *ppdata, data_size);
1560 /****************************************************************************
1561 reply to a TRANS2_SETFILEINFO (set file info by fileid)
1562 ****************************************************************************/
1563 static int call_trans2setfilepathinfo(connection_struct *conn,
1564 char *inbuf, char *outbuf, int length,
1565 int bufsize, char **pparams,
1566 char **ppdata, int total_data)
1568 char *params = *pparams;
1569 char *pdata = *ppdata;
1570 uint16 tran_call = SVAL(inbuf, smb_setup0);
1579 BOOL bad_path = False;
1580 files_struct *fsp = NULL;
1582 if (!CAN_WRITE(conn))
1583 return(ERROR(ERRSRV,ERRaccess));
1585 if (tran_call == TRANSACT2_SETFILEINFO) {
1586 fsp = file_fsp(params,0);
1587 info_level = SVAL(params,2);
1589 if(fsp && fsp->open && (fsp->is_directory || fsp->stat_open)) {
1591 * This is actually a SETFILEINFO on a directory
1592 * handle (returned from an NT SMB). NT5.0 seems
1593 * to do this call. JRA.
1595 fname = fsp->fsp_name;
1596 unix_convert(fname,conn,0,&bad_path,&st);
1597 if (!check_name(fname,conn) ||
1598 (!VALID_STAT(st) && conn->vfs_ops.stat(dos_to_unix(fname,False),&st))) {
1599 DEBUG(3,("fileinfo of %s failed (%s)\n",fname,strerror(errno)));
1600 if((errno == ENOENT) && bad_path)
1602 unix_ERR_class = ERRDOS;
1603 unix_ERR_code = ERRbadpath;
1605 return(UNIXERROR(ERRDOS,ERRbadpath));
1609 * Original code - this is an open file.
1611 CHECK_FSP(fsp,conn);
1614 fname = fsp->fsp_name;
1617 if (fsp->conn->vfs_ops.fstat(fd,&st) != 0) {
1618 DEBUG(3,("fstat of fnum %d failed (%s)\n",fsp->fnum, strerror(errno)));
1619 return(UNIXERROR(ERRDOS,ERRbadfid));
1624 info_level = SVAL(params,0);
1626 pstrcpy(fname,¶ms[6]);
1627 unix_convert(fname,conn,0,&bad_path,&st);
1628 if(!check_name(fname, conn))
1630 if((errno == ENOENT) && bad_path)
1632 unix_ERR_class = ERRDOS;
1633 unix_ERR_code = ERRbadpath;
1635 return(UNIXERROR(ERRDOS,ERRbadpath));
1638 if(!VALID_STAT(st) && conn->vfs_ops.stat(dos_to_unix(fname,False),&st)!=0) {
1639 DEBUG(3,("stat of %s failed (%s)\n", fname, strerror(errno)));
1640 if((errno == ENOENT) && bad_path)
1642 unix_ERR_class = ERRDOS;
1643 unix_ERR_code = ERRbadpath;
1645 return(UNIXERROR(ERRDOS,ERRbadpath));
1649 DEBUG(3,("call_trans2setfilepathinfo(%d) %s info_level=%d totdata=%d\n",
1650 tran_call,fname,info_level,total_data));
1652 /* Realloc the parameter and data sizes */
1653 params = *pparams = Realloc(*pparams,2);
1655 return(ERROR(ERRDOS,ERRnomem));
1660 tvs.modtime = st.st_mtime;
1661 tvs.actime = st.st_atime;
1662 mode = dos_mode(conn,fname,&st);
1664 if (total_data > 0 && IVAL(pdata,0) == total_data) {
1665 /* uggh, EAs for OS2 */
1666 DEBUG(4,("Rejecting EA request with total_data=%d\n",total_data));
1667 return(ERROR(ERRDOS,ERROR_EAS_NOT_SUPPORTED));
1672 case SMB_INFO_STANDARD:
1673 case SMB_INFO_QUERY_EA_SIZE:
1676 tvs.actime = make_unix_date2(pdata+l1_fdateLastAccess);
1679 tvs.modtime = make_unix_date2(pdata+l1_fdateLastWrite);
1681 mode = SVAL(pdata,l1_attrFile);
1682 size = IVAL(pdata,l1_cbFile);
1686 /* XXXX um, i don't think this is right.
1687 it's also not in the cifs6.txt spec.
1689 case SMB_INFO_QUERY_EAS_FROM_LIST:
1690 tvs.actime = make_unix_date2(pdata+8);
1691 tvs.modtime = make_unix_date2(pdata+12);
1692 size = IVAL(pdata,16);
1693 mode = IVAL(pdata,24);
1696 /* XXXX nor this. not in cifs6.txt, either. */
1697 case SMB_INFO_QUERY_ALL_EAS:
1698 tvs.actime = make_unix_date2(pdata+8);
1699 tvs.modtime = make_unix_date2(pdata+12);
1700 size = IVAL(pdata,16);
1701 mode = IVAL(pdata,24);
1704 case SMB_SET_FILE_BASIC_INFO:
1706 /* Patch to do this correctly from Paul Eggert <eggert@twinsun.com>. */
1708 time_t changed_time;
1710 /* Ignore create time at offset pdata. */
1713 tvs.actime = interpret_long_date(pdata+8);
1715 write_time = interpret_long_date(pdata+16);
1716 changed_time = interpret_long_date(pdata+24);
1718 tvs.modtime = MIN(write_time, changed_time);
1720 /* Prefer a defined time to an undefined one. */
1721 if (tvs.modtime == (time_t)0 || tvs.modtime == (time_t)-1)
1722 tvs.modtime = (write_time == (time_t)0 || write_time == (time_t)-1
1726 #if 0 /* Needs more testing... */
1727 /* Test from Luke to prevent Win95 from
1728 setting incorrect values here.
1730 if (tvs.actime < tvs.modtime)
1731 return(ERROR(ERRDOS,ERRnoaccess));
1732 #endif /* Needs more testing... */
1735 mode = IVAL(pdata,32);
1740 * NT seems to use this call with a size of zero
1741 * to mean truncate the file. JRA.
1744 case SMB_SET_FILE_ALLOCATION_INFO:
1746 SMB_OFF_T newsize = IVAL(pdata,0);
1747 #ifdef LARGE_SMB_OFF_T
1748 newsize |= (((SMB_OFF_T)IVAL(pdata,4)) << 32);
1749 #else /* LARGE_SMB_OFF_T */
1750 if (IVAL(pdata,4) != 0) /* more than 32 bits? */
1751 return(ERROR(ERRDOS,ERRunknownlevel));
1752 #endif /* LARGE_SMB_OFF_T */
1753 DEBUG(10,("call_trans2setfilepathinfo: Set file allocation info for file %s to %.0f\n", fname, (double)newsize ));
1759 case SMB_SET_FILE_END_OF_FILE_INFO:
1761 size = IVAL(pdata,0);
1762 #ifdef LARGE_SMB_OFF_T
1763 size |= (((SMB_OFF_T)IVAL(pdata,4)) << 32);
1764 #else /* LARGE_SMB_OFF_T */
1765 if (IVAL(pdata,4) != 0) /* more than 32 bits? */
1766 return(ERROR(ERRDOS,ERRunknownlevel));
1767 #endif /* LARGE_SMB_OFF_T */
1768 DEBUG(10,("call_trans2setfilepathinfo: Set end of file info for file %s to %.0f\n", fname, (double)size ));
1772 case SMB_SET_FILE_DISPOSITION_INFO: /* Set delete on close for open file. */
1774 if ((tran_call == TRANSACT2_SETFILEINFO) && (fsp != NULL))
1776 BOOL delete_on_close = (CVAL(pdata,0) ? True : False);
1778 if(fsp->is_directory)
1780 fsp->directory_delete_on_close = delete_on_close;
1781 DEBUG(10, ("call_trans2setfilepathinfo: %s delete on close flag for fnum = %d, directory %s\n",
1782 delete_on_close ? "Added" : "Removed", fsp->fnum, fsp->fsp_name ));
1785 else if(fsp->stat_open)
1787 DEBUG(10, ("call_trans2setfilepathinfo: %s delete on close flag for fnum = %d, stat open %s\n",
1788 delete_on_close ? "Added" : "Removed", fsp->fnum, fsp->fsp_name ));
1794 * We can only set the delete on close flag if
1795 * the share mode contained ALLOW_SHARE_DELETE
1798 if(lp_share_modes(SNUM(conn)))
1800 if(!GET_ALLOW_SHARE_DELETE(fsp->share_mode))
1801 return(ERROR(ERRDOS,ERRnoaccess));
1804 * If the flag has been set then
1805 * modify the share mode entry for all files we have open
1806 * on this device and inode to tell other smbds we have
1807 * changed the delete on close flag.
1810 if(delete_on_close && !GET_DELETE_ON_CLOSE_FLAG(fsp->share_mode))
1813 files_struct *iterate_fsp;
1814 SMB_DEV_T dev = fsp->dev;
1815 SMB_INO_T inode = fsp->inode;
1816 int num_share_modes;
1817 share_mode_entry *current_shares = NULL;
1819 if (lock_share_entry_fsp(fsp) == False)
1820 return(ERROR(ERRDOS,ERRnoaccess));
1823 * Before we allow this we need to ensure that all current opens
1824 * on the file have the GET_ALLOW_SHARE_DELETE flag set. If they
1825 * do not then we deny this (as we are essentially deleting the
1826 * file at this point.
1829 num_share_modes = get_share_modes(conn, dev, inode, ¤t_shares);
1830 for(i = 0; i < num_share_modes; i++)
1832 if(!GET_ALLOW_SHARE_DELETE(current_shares[i].share_mode))
1834 DEBUG(5,("call_trans2setfilepathinfo: refusing to set delete on close flag for fnum = %d, \
1835 file %s as a share exists that was not opened with FILE_DELETE access.\n",
1836 fsp->fnum, fsp->fsp_name ));
1841 unlock_share_entry_fsp(fsp);
1844 * current_shares was malloced by get_share_modes - free it here.
1847 free((char *)current_shares);
1850 * Even though share violation would be more appropriate here,
1851 * return ERRnoaccess as that's what NT does.
1854 return(ERROR(ERRDOS,ERRnoaccess));
1859 * current_shares was malloced by get_share_modes - free it here.
1862 free((char *)current_shares);
1864 DEBUG(10,("call_trans2setfilepathinfo: %s delete on close flag for fnum = %d, file %s\n",
1865 delete_on_close ? "Adding" : "Removing", fsp->fnum, fsp->fsp_name ));
1868 * Go through all files we have open on the same device and
1869 * inode (hanging off the same hash bucket) and set the DELETE_ON_CLOSE_FLAG.
1870 * Other smbd's that have this file open will have to fend for themselves. We
1871 * take care of this (rare) case in close_file(). See the comment there.
1874 for(iterate_fsp = file_find_di_first(dev, inode); iterate_fsp;
1875 iterate_fsp = file_find_di_next(iterate_fsp))
1877 int new_share_mode = (delete_on_close ?
1878 (iterate_fsp->share_mode | DELETE_ON_CLOSE_FLAG) :
1879 (iterate_fsp->share_mode & ~DELETE_ON_CLOSE_FLAG) );
1881 DEBUG(10,("call_trans2setfilepathinfo: Changing share mode for fnum %d, file %s \
1882 dev = %x, inode = %.0f from %x to %x\n",
1883 iterate_fsp->fnum, iterate_fsp->fsp_name, (unsigned int)dev,
1884 (double)inode, iterate_fsp->share_mode, new_share_mode ));
1886 if(modify_share_mode(iterate_fsp, new_share_mode, iterate_fsp->oplock_type)==False)
1887 DEBUG(0,("call_trans2setfilepathinfo: failed to change delete on close for fnum %d, \
1888 dev = %x, inode = %.0f\n", iterate_fsp->fnum, (unsigned int)dev, (double)inode));
1892 * Set the delete on close flag in the reference
1893 * counted struct. Delete when the last reference
1896 fsp->delete_on_close = delete_on_close;
1898 unlock_share_entry_fsp(fsp);
1900 DEBUG(10, ("call_trans2setfilepathinfo: %s delete on close flag for fnum = %d, file %s\n",
1901 delete_on_close ? "Added" : "Removed", fsp->fnum, fsp->fsp_name ));
1903 } /* end if(delete_on_close && !GET_DELETE_ON_CLOSE_FLAG(fsp->share_mode)) */
1904 } /* end if lp_share_modes() */
1905 } /* end if is_directory. */
1907 return(ERROR(ERRDOS,ERRunknownlevel));
1913 return(ERROR(ERRDOS,ERRunknownlevel));
1917 /* get some defaults (no modifications) if any info is zero or -1. */
1918 if (tvs.actime == (time_t)0 || tvs.actime == (time_t)-1)
1919 tvs.actime = st.st_atime;
1921 if (tvs.modtime == (time_t)0 || tvs.modtime == (time_t)-1)
1922 tvs.modtime = st.st_mtime;
1924 DEBUG(6,("actime: %s " , ctime(&tvs.actime)));
1925 DEBUG(6,("modtime: %s ", ctime(&tvs.modtime)));
1926 DEBUG(6,("size: %.0f ", (double)size));
1927 DEBUG(6,("mode: %x\n" , mode));
1929 if(!((info_level == SMB_SET_FILE_END_OF_FILE_INFO) ||
1930 (info_level == SMB_SET_FILE_ALLOCATION_INFO))) {
1932 * Only do this test if we are not explicitly
1933 * changing the size of a file.
1939 /* Try and set the times, size and mode of this file -
1940 if they are different from the current values
1942 if (st.st_mtime != tvs.modtime || st.st_atime != tvs.actime) {
1945 * This was a setfileinfo on an open file.
1946 * NT does this a lot. It's actually pointless
1947 * setting the time here, as it will be overwritten
1948 * on the next write, so we save the request
1949 * away and will set it on file code. JRA.
1952 if (tvs.modtime != (time_t)0 && tvs.modtime != (time_t)-1) {
1953 DEBUG(10,("call_trans2setfilepathinfo: setting pending modtime to %s\n",
1954 ctime(&tvs.modtime) ));
1955 fsp->pending_modtime = tvs.modtime;
1960 DEBUG(10,("call_trans2setfilepathinfo: setting utimes to modified values.\n"));
1962 if(file_utime(conn, fname, &tvs)!=0)
1963 return(UNIXERROR(ERRDOS,ERRnoaccess));
1967 /* check the mode isn't different, before changing it */
1968 if ((mode != 0) && (mode != dos_mode(conn, fname, &st))) {
1970 DEBUG(10,("call_trans2setfilepathinfo: file %s : setting dos mode %x\n",
1973 if(file_chmod(conn, fname, mode, NULL)) {
1974 DEBUG(2,("chmod of %s failed (%s)\n", fname, strerror(errno)));
1975 return(UNIXERROR(ERRDOS,ERRnoaccess));
1979 if(size != st.st_size) {
1981 DEBUG(10,("call_trans2setfilepathinfo: file %s : setting new size to %.0f\n",
1982 fname, (double)size ));
1985 fd = conn->vfs_ops.open(dos_to_unix(fname,False),O_RDWR,0);
1987 return(UNIXERROR(ERRDOS,ERRbadpath));
1988 set_filelen(fd, size); /* tpot vfs */
1989 conn->vfs_ops.close(fd);
1991 set_filelen(fd, size); /* tpot vfs */
1995 set_filelen_write_cache(fsp, size);
2000 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
2005 /****************************************************************************
2006 reply to a TRANS2_MKDIR (make directory with extended attributes).
2007 ****************************************************************************/
2008 static int call_trans2mkdir(connection_struct *conn,
2009 char *inbuf, char *outbuf, int length, int bufsize,
2010 char **pparams, char **ppdata)
2012 char *params = *pparams;
2015 BOOL bad_path = False;
2017 if (!CAN_WRITE(conn))
2018 return(ERROR(ERRSRV,ERRaccess));
2020 pstrcpy(directory, ¶ms[4]);
2022 DEBUG(3,("call_trans2mkdir : name = %s\n", directory));
2024 unix_convert(directory,conn,0,&bad_path,NULL);
2025 if (check_name(directory,conn))
2026 ret = conn->vfs_ops.mkdir(dos_to_unix(directory,False),
2027 unix_mode(conn,aDIR,directory));
2031 DEBUG(5,("call_trans2mkdir error (%s)\n", strerror(errno)));
2032 if((errno == ENOENT) && bad_path)
2034 unix_ERR_class = ERRDOS;
2035 unix_ERR_code = ERRbadpath;
2037 return(UNIXERROR(ERRDOS,ERRnoaccess));
2040 /* Realloc the parameter and data sizes */
2041 params = *pparams = Realloc(*pparams,2);
2043 return(ERROR(ERRDOS,ERRnomem));
2047 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
2052 /****************************************************************************
2053 reply to a TRANS2_FINDNOTIFYFIRST (start monitoring a directory for changes)
2054 We don't actually do this - we just send a null response.
2055 ****************************************************************************/
2056 static int call_trans2findnotifyfirst(connection_struct *conn,
2057 char *inbuf, char *outbuf,
2058 int length, int bufsize,
2059 char **pparams, char **ppdata)
2061 static uint16 fnf_handle = 257;
2062 char *params = *pparams;
2063 uint16 info_level = SVAL(params,4);
2065 DEBUG(3,("call_trans2findnotifyfirst - info_level %d\n", info_level));
2073 return(ERROR(ERRDOS,ERRunknownlevel));
2076 /* Realloc the parameter and data sizes */
2077 params = *pparams = Realloc(*pparams,6);
2079 return(ERROR(ERRDOS,ERRnomem));
2081 SSVAL(params,0,fnf_handle);
2082 SSVAL(params,2,0); /* No changes */
2083 SSVAL(params,4,0); /* No EA errors */
2090 send_trans2_replies(outbuf, bufsize, params, 6, *ppdata, 0);
2095 /****************************************************************************
2096 reply to a TRANS2_FINDNOTIFYNEXT (continue monitoring a directory for
2097 changes). Currently this does nothing.
2098 ****************************************************************************/
2099 static int call_trans2findnotifynext(connection_struct *conn,
2100 char *inbuf, char *outbuf,
2101 int length, int bufsize,
2102 char **pparams, char **ppdata)
2104 char *params = *pparams;
2106 DEBUG(3,("call_trans2findnotifynext\n"));
2108 /* Realloc the parameter and data sizes */
2109 params = *pparams = Realloc(*pparams,4);
2111 return(ERROR(ERRDOS,ERRnomem));
2113 SSVAL(params,0,0); /* No changes */
2114 SSVAL(params,2,0); /* No EA errors */
2116 send_trans2_replies(outbuf, bufsize, params, 4, *ppdata, 0);
2121 /****************************************************************************
2122 reply to a TRANS2_GET_DFS_REFERRAL - Shirish Kalele <kalele@veritas.com>
2123 ****************************************************************************/
2124 static int call_trans2getdfsreferral(connection_struct *conn, char* inbuf,
2125 char* outbuf, int length, int bufsize,
2126 char** pparams, char** ppdata)
2128 char *params = *pparams;
2129 enum remote_arch_types ra_type = get_remote_arch();
2130 BOOL NT_arch = ((ra_type == RA_WINNT) || (ra_type == RA_WIN2K));
2133 int max_referral_level = SVAL(params,0);
2136 DEBUG(10,("call_trans2getdfsreferral\n"));
2138 if(!lp_host_msdfs())
2139 return(ERROR(ERRDOS,ERRbadfunc));
2141 /* if pathname is in UNICODE, convert to DOS */
2142 /* NT always sends in UNICODE, may not set UNICODE flag */
2143 if(NT_arch || (SVAL(inbuf,smb_flg2) & FLAGS2_UNICODE_STRINGS))
2145 unistr_to_dos(pathname, ¶ms[2]);
2146 DEBUG(10,("UNICODE referral for %s\n",pathname));
2149 pstrcpy(pathname,¶ms[2]);
2151 if((reply_size = setup_dfs_referral(pathname,max_referral_level,ppdata)) < 0)
2152 return(ERROR(ERRDOS,ERRbadfile));
2154 SSVAL(outbuf,smb_flg2,SVAL(outbuf,smb_flg2) | FLAGS2_UNICODE_STRINGS |
2155 FLAGS2_DFS_PATHNAMES);
2156 send_trans2_replies(outbuf,bufsize,0,0,*ppdata,reply_size);
2162 /****************************************************************************
2163 reply to a SMBfindclose (stop trans2 directory search)
2164 ****************************************************************************/
2165 int reply_findclose(connection_struct *conn,
2166 char *inbuf,char *outbuf,int length,int bufsize)
2169 int dptr_num=SVALS(inbuf,smb_vwv0);
2171 DEBUG(3,("reply_findclose, dptr_num = %d\n", dptr_num));
2173 dptr_close(&dptr_num);
2175 outsize = set_message(outbuf,0,0,True);
2177 DEBUG(3,("SMBfindclose dptr_num = %d\n", dptr_num));
2182 /****************************************************************************
2183 reply to a SMBfindnclose (stop FINDNOTIFYFIRST directory search)
2184 ****************************************************************************/
2185 int reply_findnclose(connection_struct *conn,
2186 char *inbuf,char *outbuf,int length,int bufsize)
2191 dptr_num = SVAL(inbuf,smb_vwv0);
2193 DEBUG(3,("reply_findnclose, dptr_num = %d\n", dptr_num));
2195 /* We never give out valid handles for a
2196 findnotifyfirst - so any dptr_num is ok here.
2199 outsize = set_message(outbuf,0,0,True);
2201 DEBUG(3,("SMB_findnclose dptr_num = %d\n", dptr_num));
2207 /****************************************************************************
2208 reply to a SMBtranss2 - just ignore it!
2209 ****************************************************************************/
2210 int reply_transs2(connection_struct *conn,
2211 char *inbuf,char *outbuf,int length,int bufsize)
2213 DEBUG(4,("Ignoring transs2 of length %d\n",length));
2217 /****************************************************************************
2218 reply to a SMBtrans2
2219 ****************************************************************************/
2220 int reply_trans2(connection_struct *conn,
2221 char *inbuf,char *outbuf,int length,int bufsize)
2224 unsigned int total_params = SVAL(inbuf, smb_tpscnt);
2225 unsigned int total_data =SVAL(inbuf, smb_tdscnt);
2227 unsigned int max_param_reply = SVAL(inbuf, smb_mprcnt);
2228 unsigned int max_data_reply = SVAL(inbuf, smb_mdrcnt);
2229 unsigned int max_setup_fields = SVAL(inbuf, smb_msrcnt);
2230 BOOL close_tid = BITSETW(inbuf+smb_flags,0);
2231 BOOL no_final_response = BITSETW(inbuf+smb_flags,1);
2232 int32 timeout = IVALS(inbuf,smb_timeout);
2234 unsigned int suwcnt = SVAL(inbuf, smb_suwcnt);
2235 unsigned int tran_call = SVAL(inbuf, smb_setup0);
2236 char *params = NULL, *data = NULL;
2237 int num_params, num_params_sofar, num_data, num_data_sofar;
2239 if(global_oplock_break && (tran_call == TRANSACT2_OPEN)) {
2240 /* Queue this open message as we are the process of an
2243 DEBUG(2,("reply_trans2: queueing message trans2open due to being "));
2244 DEBUGADD(2,( "in oplock break state.\n"));
2246 push_oplock_pending_smb_message(inbuf, length);
2250 outsize = set_message(outbuf,0,0,True);
2252 /* All trans2 messages we handle have smb_sucnt == 1 - ensure this
2253 is so as a sanity check */
2255 DEBUG(2,("Invalid smb_sucnt in trans2 call\n"));
2256 return(ERROR(ERRSRV,ERRerror));
2259 /* Allocate the space for the maximum needed parameters and data */
2260 if (total_params > 0)
2261 params = (char *)malloc(total_params);
2263 data = (char *)malloc(total_data);
2265 if ((total_params && !params) || (total_data && !data)) {
2266 DEBUG(2,("Out of memory in reply_trans2\n"));
2271 return(ERROR(ERRDOS,ERRnomem));
2274 /* Copy the param and data bytes sent with this request into
2275 the params buffer */
2276 num_params = num_params_sofar = SVAL(inbuf,smb_pscnt);
2277 num_data = num_data_sofar = SVAL(inbuf, smb_dscnt);
2279 if (num_params > total_params || num_data > total_data)
2280 exit_server("invalid params in reply_trans2");
2283 memcpy( params, smb_base(inbuf) + SVAL(inbuf, smb_psoff), num_params);
2285 memcpy( data, smb_base(inbuf) + SVAL(inbuf, smb_dsoff), num_data);
2287 if(num_data_sofar < total_data || num_params_sofar < total_params) {
2288 /* We need to send an interim response then receive the rest
2289 of the parameter/data bytes */
2290 outsize = set_message(outbuf,0,0,True);
2291 send_smb(Client,outbuf);
2293 while (num_data_sofar < total_data ||
2294 num_params_sofar < total_params) {
2297 ret = receive_next_smb(inbuf,bufsize,SMB_SECONDARY_WAIT);
2300 (CVAL(inbuf, smb_com) != SMBtranss2)) || !ret) {
2301 outsize = set_message(outbuf,0,0,True);
2303 DEBUG(0,("reply_trans2: Invalid secondary trans2 packet\n"));
2305 DEBUG(0,("reply_trans2: %s in getting secondary trans2 response.\n",
2306 (smb_read_error == READ_ERROR) ? "error" : "timeout" ));
2311 return(ERROR(ERRSRV,ERRerror));
2314 /* Revise total_params and total_data in case
2315 they have changed downwards */
2316 total_params = SVAL(inbuf, smb_tpscnt);
2317 total_data = SVAL(inbuf, smb_tdscnt);
2318 num_params_sofar += (num_params = SVAL(inbuf,smb_spscnt));
2319 num_data_sofar += ( num_data = SVAL(inbuf, smb_sdscnt));
2320 if (num_params_sofar > total_params || num_data_sofar > total_data)
2321 exit_server("data overflow in trans2");
2323 memcpy( ¶ms[ SVAL(inbuf, smb_spsdisp)],
2324 smb_base(inbuf) + SVAL(inbuf, smb_spsoff), num_params);
2325 memcpy( &data[SVAL(inbuf, smb_sdsdisp)],
2326 smb_base(inbuf)+ SVAL(inbuf, smb_sdsoff), num_data);
2330 if (Protocol >= PROTOCOL_NT1) {
2331 uint16 flg2 = SVAL(outbuf,smb_flg2);
2332 SSVAL(outbuf,smb_flg2,flg2 | 0x40); /* IS_LONG_NAME */
2335 /* Now we must call the relevant TRANS2 function */
2337 case TRANSACT2_OPEN:
2338 outsize = call_trans2open(conn,
2339 inbuf, outbuf, bufsize,
2343 case TRANSACT2_FINDFIRST:
2344 outsize = call_trans2findfirst(conn, inbuf, outbuf,
2345 bufsize, ¶ms, &data);
2348 case TRANSACT2_FINDNEXT:
2349 outsize = call_trans2findnext(conn, inbuf, outbuf,
2354 case TRANSACT2_QFSINFO:
2355 outsize = call_trans2qfsinfo(conn, inbuf, outbuf,
2356 length, bufsize, ¶ms,
2360 case TRANSACT2_SETFSINFO:
2361 outsize = call_trans2setfsinfo(conn, inbuf, outbuf,
2366 case TRANSACT2_QPATHINFO:
2367 case TRANSACT2_QFILEINFO:
2368 outsize = call_trans2qfilepathinfo(conn, inbuf, outbuf,
2370 ¶ms, &data, total_data);
2372 case TRANSACT2_SETPATHINFO:
2373 case TRANSACT2_SETFILEINFO:
2374 outsize = call_trans2setfilepathinfo(conn, inbuf, outbuf,
2380 case TRANSACT2_FINDNOTIFYFIRST:
2381 outsize = call_trans2findnotifyfirst(conn, inbuf, outbuf,
2386 case TRANSACT2_FINDNOTIFYNEXT:
2387 outsize = call_trans2findnotifynext(conn, inbuf, outbuf,
2391 case TRANSACT2_MKDIR:
2392 outsize = call_trans2mkdir(conn, inbuf, outbuf, length,
2393 bufsize, ¶ms, &data);
2396 case TRANSACT2_GET_DFS_REFERRAL:
2397 outsize = call_trans2getdfsreferral(conn,inbuf,outbuf,length,
2398 bufsize, ¶ms, &data);
2401 /* Error in request */
2402 DEBUG(2,("Unknown request %d in trans2 call\n", tran_call));
2407 return (ERROR(ERRSRV,ERRerror));
2410 /* As we do not know how many data packets will need to be
2411 returned here the various call_trans2xxxx calls
2412 must send their own. Thus a call_trans2xxx routine only
2413 returns a value other than -1 when it wants to send
2421 return outsize; /* If a correct response was needed the
2422 call_trans2xxx calls have already sent
2423 it. If outsize != -1 then it is returning */