2 Unix SMB/Netbios implementation.
4 SMB transaction2 handling
5 Copyright (C) Jeremy Allison 1994-1998
7 Extensively modified by Andrew Tridgell, 1995
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26 extern int DEBUGLEVEL;
28 extern BOOL case_sensitive;
29 extern int smb_read_error;
30 extern fstring local_machine;
31 extern int global_oplock_break;
32 extern uint32 global_client_caps;
34 /****************************************************************************
35 Send the required number of replies back.
36 We assume all fields other than the data fields are
37 set correctly for the type of call.
38 HACK ! Always assumes smb_setup field is zero.
39 ****************************************************************************/
40 static int send_trans2_replies(char *outbuf, int bufsize, char *params,
41 int paramsize, char *pdata, int datasize)
43 /* As we are using a protocol > LANMAN1 then the max_send
44 variable must have been set in the sessetupX call.
45 This takes precedence over the max_xmit field in the
46 global struct. These different max_xmit variables should
47 be merged as this is now too confusing */
50 int data_to_send = datasize;
51 int params_to_send = paramsize;
55 int params_sent_thistime, data_sent_thistime, total_sent_thistime;
56 int alignment_offset = 3;
57 int data_alignment_offset = 0;
59 /* Initially set the wcnt area to be 10 - this is true for all
61 set_message(outbuf,10,0,True);
63 /* If there genuinely are no parameters or data to send just send
65 if(params_to_send == 0 && data_to_send == 0)
67 send_smb(smbd_server_fd(),outbuf);
71 /* When sending params and data ensure that both are nicely aligned */
72 /* Only do this alignment when there is also data to send - else
73 can cause NT redirector problems. */
74 if (((params_to_send % 4) != 0) && (data_to_send != 0))
75 data_alignment_offset = 4 - (params_to_send % 4);
77 /* Space is bufsize minus Netbios over TCP header minus SMB header */
78 /* The alignment_offset is to align the param bytes on an even byte
79 boundary. NT 4.0 Beta needs this to work correctly. */
80 useable_space = bufsize - ((smb_buf(outbuf)+
81 alignment_offset+data_alignment_offset) -
84 /* useable_space can never be more than max_send minus the
86 useable_space = MIN(useable_space,
87 max_send - (alignment_offset+data_alignment_offset));
90 while (params_to_send || data_to_send)
92 /* Calculate whether we will totally or partially fill this packet */
93 total_sent_thistime = params_to_send + data_to_send +
94 alignment_offset + data_alignment_offset;
95 /* We can never send more than useable_space */
97 * Note that 'useable_space' does not include the alignment offsets,
98 * but we must include the alignment offsets in the calculation of
99 * the length of the data we send over the wire, as the alignment offsets
100 * are sent here. Fix from Marc_Jacobsen@hp.com.
102 total_sent_thistime = MIN(total_sent_thistime, useable_space+
103 alignment_offset + data_alignment_offset);
105 set_message(outbuf, 10, total_sent_thistime, True);
107 /* Set total params and data to be sent */
108 SSVAL(outbuf,smb_tprcnt,paramsize);
109 SSVAL(outbuf,smb_tdrcnt,datasize);
111 /* Calculate how many parameters and data we can fit into
112 this packet. Parameters get precedence */
114 params_sent_thistime = MIN(params_to_send,useable_space);
115 data_sent_thistime = useable_space - params_sent_thistime;
116 data_sent_thistime = MIN(data_sent_thistime,data_to_send);
118 SSVAL(outbuf,smb_prcnt, params_sent_thistime);
120 /* smb_proff is the offset from the start of the SMB header to the
121 parameter bytes, however the first 4 bytes of outbuf are
122 the Netbios over TCP header. Thus use smb_base() to subtract
123 them from the calculation */
125 SSVAL(outbuf,smb_proff,((smb_buf(outbuf)+alignment_offset) - smb_base(outbuf)));
127 if(params_sent_thistime == 0)
128 SSVAL(outbuf,smb_prdisp,0);
130 /* Absolute displacement of param bytes sent in this packet */
131 SSVAL(outbuf,smb_prdisp,pp - params);
133 SSVAL(outbuf,smb_drcnt, data_sent_thistime);
134 if(data_sent_thistime == 0)
136 SSVAL(outbuf,smb_droff,0);
137 SSVAL(outbuf,smb_drdisp, 0);
141 /* The offset of the data bytes is the offset of the
142 parameter bytes plus the number of parameters being sent this time */
143 SSVAL(outbuf,smb_droff,((smb_buf(outbuf)+alignment_offset) -
144 smb_base(outbuf)) + params_sent_thistime + data_alignment_offset);
145 SSVAL(outbuf,smb_drdisp, pd - pdata);
148 /* Copy the param bytes into the packet */
149 if(params_sent_thistime)
150 memcpy((smb_buf(outbuf)+alignment_offset),pp,params_sent_thistime);
151 /* Copy in the data bytes */
152 if(data_sent_thistime)
153 memcpy(smb_buf(outbuf)+alignment_offset+params_sent_thistime+
154 data_alignment_offset,pd,data_sent_thistime);
156 DEBUG(9,("t2_rep: params_sent_thistime = %d, data_sent_thistime = %d, useable_space = %d\n",
157 params_sent_thistime, data_sent_thistime, useable_space));
158 DEBUG(9,("t2_rep: params_to_send = %d, data_to_send = %d, paramsize = %d, datasize = %d\n",
159 params_to_send, data_to_send, paramsize, datasize));
161 /* Send the packet */
162 send_smb(smbd_server_fd(),outbuf);
164 pp += params_sent_thistime;
165 pd += data_sent_thistime;
167 params_to_send -= params_sent_thistime;
168 data_to_send -= data_sent_thistime;
171 if(params_to_send < 0 || data_to_send < 0)
173 DEBUG(0,("send_trans2_replies failed sanity check pts = %d, dts = %d\n!!!",
174 params_to_send, data_to_send));
183 /****************************************************************************
184 reply to a TRANSACT2_OPEN
185 ****************************************************************************/
186 static int call_trans2open(connection_struct *conn, char *inbuf, char *outbuf,
188 char **pparams, char **ppdata)
190 char *params = *pparams;
191 int16 open_mode = SVAL(params, 2);
192 int16 open_attr = SVAL(params,6);
193 BOOL oplock_request = (((SVAL(params,0)|(1<<1))>>1) | ((SVAL(params,0)|(1<<2))>>1));
195 BOOL return_additional_info = BITSETW(params,0);
196 int16 open_sattr = SVAL(params, 4);
197 time_t open_time = make_unix_date3(params+8);
199 int16 open_ofun = SVAL(params,12);
200 int32 open_size = IVAL(params,14);
201 char *pname = ¶ms[28];
202 int16 namelen = strlen(pname)+1;
207 int fmode=0,mtime=0,rmode;
209 SMB_STRUCT_STAT sbuf;
211 BOOL bad_path = False;
214 StrnCpy(fname,pname,namelen);
216 DEBUG(3,("trans2open %s mode=%d attr=%d ofun=%d size=%d\n",
217 fname,open_mode, open_attr, open_ofun, open_size));
219 /* XXXX we need to handle passed times, sattr and flags */
221 unix_convert(fname,conn,0,&bad_path,NULL);
223 if (!check_name(fname,conn))
225 if((errno == ENOENT) && bad_path)
227 unix_ERR_class = ERRDOS;
228 unix_ERR_code = ERRbadpath;
230 return(UNIXERROR(ERRDOS,ERRnoaccess));
233 unixmode = unix_mode(conn,open_attr | aARCH, fname);
235 fsp = open_file_shared(conn,fname,open_mode,open_ofun,unixmode,
236 oplock_request, &rmode,&smb_action);
240 if((errno == ENOENT) && bad_path)
242 unix_ERR_class = ERRDOS;
243 unix_ERR_code = ERRbadpath;
245 return(UNIXERROR(ERRDOS,ERRnoaccess));
248 if (fsp->conn->vfs_ops.fstat(fsp->fd,&sbuf) != 0) {
249 close_file(fsp,False);
250 return(UNIXERROR(ERRDOS,ERRnoaccess));
254 fmode = dos_mode(conn,fname,&sbuf);
255 mtime = sbuf.st_mtime;
258 close_file(fsp,False);
259 return(ERROR(ERRDOS,ERRnoaccess));
262 /* Realloc the size of parameters and data we will return */
263 params = *pparams = Realloc(*pparams, 28);
265 return(ERROR(ERRDOS,ERRnomem));
267 memset((char *)params,'\0',28);
268 SSVAL(params,0,fsp->fnum);
269 SSVAL(params,2,fmode);
270 put_dos_date2(params,4, mtime);
271 SIVAL(params,8, (uint32)size);
272 SSVAL(params,12,rmode);
274 if (oplock_request && lp_fake_oplocks(SNUM(conn))) {
275 smb_action |= EXTENDED_OPLOCK_GRANTED;
278 SSVAL(params,18,smb_action);
280 * WARNING - this may need to be changed if SMB_INO_T <> 4 bytes.
282 SIVAL(params,20,inode);
284 /* Send the required number of replies */
285 send_trans2_replies(outbuf, bufsize, params, 28, *ppdata, 0);
290 /****************************************************************************
291 get a level dependent lanman2 dir entry.
292 ****************************************************************************/
293 static BOOL get_lanman2_dir_entry(connection_struct *conn,
294 char *path_mask,int dirtype,int info_level,
295 int requires_resume_key,
296 BOOL dont_descend,char **ppdata,
297 char *base_data, int space_remaining,
298 BOOL *out_of_space, BOOL *got_exact_match,
303 SMB_STRUCT_STAT sbuf;
307 char *p, *pdata = *ppdata;
313 time_t mdate=0, adate=0, cdate=0;
316 int nt_extmode; /* Used for NT connections instead of mode */
317 BOOL needslash = ( conn->dirpath[strlen(conn->dirpath) -1] != '/');
320 *out_of_space = False;
321 *got_exact_match = False;
326 p = strrchr(path_mask,'/');
335 pstrcpy(mask, path_mask);
341 /* Needed if we run out of space */
342 prev_dirpos = TellDir(conn->dirptr);
343 dname = ReadDirName(conn->dirptr);
346 * Due to bugs in NT client redirectors we are not using
347 * resume keys any more - set them to zero.
348 * Check out the related comments in findfirst/findnext.
354 DEBUG(8,("get_lanman2_dir_entry:readdir on dirptr 0x%lx now at offset %d\n",
355 (long)conn->dirptr,TellDir(conn->dirptr)));
360 pstrcpy(fname,dname);
362 if(!(got_match = *got_exact_match = exact_match(fname, mask, case_sensitive)))
363 got_match = mask_match(fname, mask, case_sensitive, True);
365 if(!got_match && !is_8_3(fname, False)) {
368 * It turns out that NT matches wildcards against
369 * both long *and* short names. This may explain some
370 * of the wildcard wierdness from old DOS clients
371 * that some people have been seeing.... JRA.
375 pstrcpy( newname, fname);
376 name_map_mangle( newname, True, False, SNUM(conn));
377 if(!(got_match = *got_exact_match = exact_match(newname, mask, case_sensitive)))
378 got_match = mask_match(newname, mask, case_sensitive, True);
383 BOOL isdots = (strequal(fname,"..") || strequal(fname,"."));
384 if (dont_descend && !isdots)
387 pstrcpy(pathreal,conn->dirpath);
389 pstrcat(pathreal,"/");
390 pstrcat(pathreal,dname);
391 if (conn->vfs_ops.stat(dos_to_unix(pathreal,False),&sbuf) != 0)
393 DEBUG(5,("get_lanman2_dir_entry:Couldn't stat [%s] (%s)\n",pathreal,strerror(errno)));
397 mode = dos_mode(conn,pathreal,&sbuf);
399 if (!dir_check_ftype(conn,mode,&sbuf,dirtype)) {
400 DEBUG(5,("[%s] attribs didn't match %x\n",fname,dirtype));
405 mdate = sbuf.st_mtime;
406 adate = sbuf.st_atime;
407 cdate = get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(conn)));
411 DEBUG(5,("get_lanman2_dir_entry found %s fname=%s\n",pathreal,fname));
417 name_map_mangle(fname,False,True,SNUM(conn));
422 nt_extmode = mode ? mode : FILE_ATTRIBUTE_NORMAL;
427 if(requires_resume_key) {
431 put_dos_date2(p,l1_fdateCreation,cdate);
432 put_dos_date2(p,l1_fdateLastAccess,adate);
433 put_dos_date2(p,l1_fdateLastWrite,mdate);
434 SIVAL(p,l1_cbFile,(uint32)size);
435 SIVAL(p,l1_cbFileAlloc,SMB_ROUNDUP(size,1024));
436 SSVAL(p,l1_attrFile,mode);
437 SCVAL(p,l1_cchName,strlen(fname));
438 pstrcpy(p + l1_achName, fname);
439 nameptr = p + l1_achName;
440 p += l1_achName + strlen(fname) + 1;
445 if(requires_resume_key) {
449 put_dos_date2(p,l2_fdateCreation,cdate);
450 put_dos_date2(p,l2_fdateLastAccess,adate);
451 put_dos_date2(p,l2_fdateLastWrite,mdate);
452 SIVAL(p,l2_cbFile,(uint32)size);
453 SIVAL(p,l2_cbFileAlloc,SMB_ROUNDUP(size,1024));
454 SSVAL(p,l2_attrFile,mode);
455 SIVAL(p,l2_cbList,0); /* No extended attributes */
456 SCVAL(p,l2_cchName,strlen(fname));
457 pstrcpy(p + l2_achName, fname);
458 nameptr = p + l2_achName;
459 p += l2_achName + strlen(fname) + 1;
464 put_dos_date2(p,4,cdate);
465 put_dos_date2(p,8,adate);
466 put_dos_date2(p,12,mdate);
467 SIVAL(p,16,(uint32)size);
468 SIVAL(p,20,SMB_ROUNDUP(size,1024));
471 CVAL(p,30) = strlen(fname);
472 pstrcpy(p+31, fname);
474 p += 31 + strlen(fname) + 1;
478 if(requires_resume_key) {
482 SIVAL(p,0,33+strlen(fname)+1);
483 put_dos_date2(p,4,cdate);
484 put_dos_date2(p,8,adate);
485 put_dos_date2(p,12,mdate);
486 SIVAL(p,16,(uint32)size);
487 SIVAL(p,20,SMB_ROUNDUP(size,1024));
489 CVAL(p,32) = strlen(fname);
490 pstrcpy(p + 33, fname);
492 p += 33 + strlen(fname) + 1;
495 case SMB_FIND_FILE_BOTH_DIRECTORY_INFO:
496 was_8_3 = is_8_3(fname, True);
497 len = 94+strlen(fname);
498 len = (len + 3) & ~3;
499 SIVAL(p,0,len); p += 4;
500 SIVAL(p,0,reskey); p += 4;
501 put_long_date(p,cdate); p += 8;
502 put_long_date(p,adate); p += 8;
503 put_long_date(p,mdate); p += 8;
504 put_long_date(p,mdate); p += 8;
508 SIVAL(p,0,nt_extmode); p += 4;
509 SIVAL(p,0,strlen(fname)); p += 4;
510 SIVAL(p,0,0); p += 4;
513 if (!name_map_mangle(p+2,True,True,SNUM(conn)))
518 SSVAL(p,0,strlen(p+2));
521 pstrcpy(p,fname); p += strlen(p);
525 case SMB_FIND_FILE_DIRECTORY_INFO:
526 len = 64+strlen(fname);
527 len = (len + 3) & ~3;
528 SIVAL(p,0,len); p += 4;
529 SIVAL(p,0,reskey); p += 4;
530 put_long_date(p,cdate); p += 8;
531 put_long_date(p,adate); p += 8;
532 put_long_date(p,mdate); p += 8;
533 put_long_date(p,mdate); p += 8;
537 SIVAL(p,0,nt_extmode); p += 4;
538 SIVAL(p,0,strlen(fname)); p += 4;
544 case SMB_FIND_FILE_FULL_DIRECTORY_INFO:
545 len = 68+strlen(fname);
546 len = (len + 3) & ~3;
547 SIVAL(p,0,len); p += 4;
548 SIVAL(p,0,reskey); p += 4;
549 put_long_date(p,cdate); p += 8;
550 put_long_date(p,adate); p += 8;
551 put_long_date(p,mdate); p += 8;
552 put_long_date(p,mdate); p += 8;
556 SIVAL(p,0,nt_extmode); p += 4;
557 SIVAL(p,0,strlen(fname)); p += 4;
558 SIVAL(p,0,0); p += 4;
563 case SMB_FIND_FILE_NAMES_INFO:
564 len = 12+strlen(fname);
565 len = (len + 3) & ~3;
566 SIVAL(p,0,len); p += 4;
567 SIVAL(p,0,reskey); p += 4;
568 SIVAL(p,0,strlen(fname)); p += 4;
578 if (PTR_DIFF(p,pdata) > space_remaining) {
579 /* Move the dirptr back to prev_dirpos */
580 SeekDir(conn->dirptr, prev_dirpos);
581 *out_of_space = True;
582 DEBUG(9,("get_lanman2_dir_entry: out of space\n"));
583 return False; /* Not finished - just out of space */
586 /* Setup the last_filename pointer, as an offset from base_data */
587 *last_name_off = PTR_DIFF(nameptr,base_data);
588 /* Advance the data pointer to the next slot */
594 /****************************************************************************
595 Convert the directory masks formated for the wire.
596 ****************************************************************************/
598 void mask_convert( char *mask)
601 * We know mask is a pstring.
607 if(p[1] != '"' && p[1] != '.') {
608 pstrcpy( expnd, p+1 );
611 safe_strcpy( p+1, expnd, sizeof(pstring) - (p - mask) - 2);
615 if (*p == '>') *p = '?';
616 if (*p == '"') *p = '.';
621 /****************************************************************************
622 Reply to a TRANS2_FINDFIRST.
623 ****************************************************************************/
625 static int call_trans2findfirst(connection_struct *conn,
626 char *inbuf, char *outbuf, int bufsize,
627 char **pparams, char **ppdata)
629 /* We must be careful here that we don't return more than the
630 allowed number of data bytes. If this means returning fewer than
631 maxentries then so be it. We assume that the redirector has
632 enough room for the fixed number of parameter bytes it has
634 uint32 max_data_bytes = SVAL(inbuf, smb_mdrcnt);
635 char *params = *pparams;
636 char *pdata = *ppdata;
637 int dirtype = SVAL(params,0);
638 int maxentries = SVAL(params,2);
639 BOOL close_after_first = BITSETW(params+4,0);
640 BOOL close_if_end = BITSETW(params+4,1);
641 BOOL requires_resume_key = BITSETW(params+4,2);
642 int info_level = SVAL(params,6);
650 BOOL finished = False;
651 BOOL dont_descend = False;
652 BOOL out_of_space = False;
654 BOOL bad_path = False;
656 *directory = *mask = 0;
658 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",
659 dirtype, maxentries, close_after_first, close_if_end, requires_resume_key,
660 info_level, max_data_bytes));
668 case SMB_FIND_FILE_DIRECTORY_INFO:
669 case SMB_FIND_FILE_FULL_DIRECTORY_INFO:
670 case SMB_FIND_FILE_NAMES_INFO:
671 case SMB_FIND_FILE_BOTH_DIRECTORY_INFO:
674 return(ERROR(ERRDOS,ERRunknownlevel));
677 pstrcpy(directory, params + 12); /* Complete directory path with
678 wildcard mask appended */
680 RESOLVE_FINDFIRST_DFSPATH(directory, conn, inbuf, outbuf);
682 DEBUG(5,("path=%s\n",directory));
684 unix_convert(directory,conn,0,&bad_path,NULL);
685 if(!check_name(directory,conn)) {
686 if((errno == ENOENT) && bad_path)
688 unix_ERR_class = ERRDOS;
689 unix_ERR_code = ERRbadpath;
693 /* Ugly - NT specific hack - maybe not needed ? (JRA) */
694 if((errno == ENOTDIR) && (Protocol >= PROTOCOL_NT1) &&
695 (get_remote_arch() == RA_WINNT))
697 unix_ERR_class = ERRDOS;
698 unix_ERR_code = ERRbaddirectory;
702 return(UNIXERROR(ERRDOS,ERRbadpath));
705 p = strrchr(directory,'/');
707 pstrcpy(mask,directory);
708 pstrcpy(directory,"./");
714 DEBUG(5,("dir=%s, mask = %s\n",directory, mask));
716 pdata = *ppdata = Realloc(*ppdata, max_data_bytes + 1024);
718 return(ERROR(ERRDOS,ERRnomem));
719 memset((char *)pdata,'\0',max_data_bytes + 1024);
721 /* Realloc the params space */
722 params = *pparams = Realloc(*pparams, 10);
724 return(ERROR(ERRDOS,ERRnomem));
726 dptr_num = dptr_create(conn,directory, False, True ,SVAL(inbuf,smb_pid));
728 return(UNIXERROR(ERRDOS,ERRbadfile));
730 /* Convert the formatted mask. */
733 /* Save the wildcard match and attribs we are using on this directory -
734 needed as lanman2 assumes these are being saved between calls */
736 if(!(wcard = strdup(mask))) {
737 dptr_close(&dptr_num);
738 return(ERROR(ERRDOS,ERRnomem));
741 dptr_set_wcard(dptr_num, wcard);
742 dptr_set_attr(dptr_num, dirtype);
744 DEBUG(4,("dptr_num is %d, wcard = %s, attr = %d\n",dptr_num, wcard, dirtype));
746 /* We don't need to check for VOL here as this is returned by
747 a different TRANS2 call. */
749 DEBUG(8,("dirpath=<%s> dontdescend=<%s>\n",
750 conn->dirpath,lp_dontdescend(SNUM(conn))));
751 if (in_list(conn->dirpath,lp_dontdescend(SNUM(conn)),case_sensitive))
755 space_remaining = max_data_bytes;
756 out_of_space = False;
758 for (i=0;(i<maxentries) && !finished && !out_of_space;i++)
760 BOOL got_exact_match = False;
762 /* this is a heuristic to avoid seeking the dirptr except when
763 absolutely necessary. It allows for a filename of about 40 chars */
764 if (space_remaining < DIRLEN_GUESS && numentries > 0)
771 finished = !get_lanman2_dir_entry(conn,mask,dirtype,info_level,
772 requires_resume_key,dont_descend,
773 &p,pdata,space_remaining, &out_of_space, &got_exact_match,
777 if (finished && out_of_space)
780 if (!finished && !out_of_space)
784 * As an optimisation if we know we aren't looking
785 * for a wildcard name (ie. the name matches the wildcard exactly)
786 * then we can finish on any (first) match.
787 * This speeds up large directory searches. JRA.
793 space_remaining = max_data_bytes - PTR_DIFF(p,pdata);
796 /* Check if we can close the dirptr */
797 if(close_after_first || (finished && close_if_end))
799 DEBUG(5,("call_trans2findfirst - (2) closing dptr_num %d\n", dptr_num));
800 dptr_close(&dptr_num);
804 * If there are no matching entries we must return ERRDOS/ERRbadfile -
805 * from observation of NT.
810 dptr_close(&dptr_num);
811 return(ERROR(ERRDOS,ERRbadfile));
814 /* At this point pdata points to numentries directory entries. */
816 /* Set up the return parameter block */
817 SSVAL(params,0,dptr_num);
818 SSVAL(params,2,numentries);
819 SSVAL(params,4,finished);
820 SSVAL(params,6,0); /* Never an EA error */
821 SSVAL(params,8,last_name_off);
823 send_trans2_replies( outbuf, bufsize, params, 10, pdata, PTR_DIFF(p,pdata));
825 if ((! *directory) && dptr_path(dptr_num))
826 slprintf(directory,sizeof(directory)-1, "(%s)",dptr_path(dptr_num));
828 DEBUG( 4, ( "%s mask=%s directory=%s dirtype=%d numentries=%d\n",
829 smb_fn_name(CVAL(inbuf,smb_com)),
830 mask, directory, dirtype, numentries ) );
833 * Force a name mangle here to ensure that the
834 * mask as an 8.3 name is top of the mangled cache.
835 * The reasons for this are subtle. Don't remove
836 * this code unless you know what you are doing
837 * (see PR#13758). JRA.
840 if(!is_8_3( mask, False))
841 name_map_mangle(mask, True, True, SNUM(conn));
847 /****************************************************************************
848 reply to a TRANS2_FINDNEXT
849 ****************************************************************************/
850 static int call_trans2findnext(connection_struct *conn,
851 char *inbuf, char *outbuf,
852 int length, int bufsize,
853 char **pparams, char **ppdata)
855 /* We must be careful here that we don't return more than the
856 allowed number of data bytes. If this means returning fewer than
857 maxentries then so be it. We assume that the redirector has
858 enough room for the fixed number of parameter bytes it has
860 int max_data_bytes = SVAL(inbuf, smb_mdrcnt);
861 char *params = *pparams;
862 char *pdata = *ppdata;
863 int dptr_num = SVAL(params,0);
864 int maxentries = SVAL(params,2);
865 uint16 info_level = SVAL(params,4);
866 uint32 resume_key = IVAL(params,6);
867 BOOL close_after_request = BITSETW(params+10,0);
868 BOOL close_if_end = BITSETW(params+10,1);
869 BOOL requires_resume_key = BITSETW(params+10,2);
870 BOOL continue_bit = BITSETW(params+10,3);
877 int i, last_name_off=0;
878 BOOL finished = False;
879 BOOL dont_descend = False;
880 BOOL out_of_space = False;
883 *mask = *directory = *resume_name = 0;
885 pstrcpy( resume_name, params+12);
887 DEBUG(3,("call_trans2findnext: dirhandle = %d, max_data_bytes = %d, maxentries = %d, \
888 close_after_request=%d, close_if_end = %d requires_resume_key = %d \
889 resume_key = %d resume name = %s continue=%d level = %d\n",
890 dptr_num, max_data_bytes, maxentries, close_after_request, close_if_end,
891 requires_resume_key, resume_key, resume_name, continue_bit, info_level));
899 case SMB_FIND_FILE_DIRECTORY_INFO:
900 case SMB_FIND_FILE_FULL_DIRECTORY_INFO:
901 case SMB_FIND_FILE_NAMES_INFO:
902 case SMB_FIND_FILE_BOTH_DIRECTORY_INFO:
905 return(ERROR(ERRDOS,ERRunknownlevel));
908 pdata = *ppdata = Realloc( *ppdata, max_data_bytes + 1024);
910 return(ERROR(ERRDOS,ERRnomem));
911 memset((char *)pdata,'\0',max_data_bytes + 1024);
913 /* Realloc the params space */
914 params = *pparams = Realloc(*pparams, 6*SIZEOFWORD);
916 return(ERROR(ERRDOS,ERRnomem));
918 /* Check that the dptr is valid */
919 if(!(conn->dirptr = dptr_fetch_lanman2(dptr_num)))
920 return(ERROR(ERRDOS,ERRnofiles));
922 string_set(&conn->dirpath,dptr_path(dptr_num));
924 /* Get the wildcard mask from the dptr */
925 if((p = dptr_wcard(dptr_num))== NULL) {
926 DEBUG(2,("dptr_num %d has no wildcard\n", dptr_num));
927 return (ERROR(ERRDOS,ERRnofiles));
930 pstrcpy(directory,conn->dirpath);
932 /* Get the attr mask from the dptr */
933 dirtype = dptr_attr(dptr_num);
935 DEBUG(3,("dptr_num is %d, mask = %s, attr = %x, dirptr=(0x%lX,%d)\n",
936 dptr_num, mask, dirtype,
938 TellDir(conn->dirptr)));
940 /* We don't need to check for VOL here as this is returned by
941 a different TRANS2 call. */
943 DEBUG(8,("dirpath=<%s> dontdescend=<%s>\n",conn->dirpath,lp_dontdescend(SNUM(conn))));
944 if (in_list(conn->dirpath,lp_dontdescend(SNUM(conn)),case_sensitive))
948 space_remaining = max_data_bytes;
949 out_of_space = False;
952 * Seek to the correct position. We no longer use the resume key but
953 * depend on the last file name instead.
955 if(requires_resume_key && *resume_name && !continue_bit)
958 * Fix for NT redirector problem triggered by resume key indexes
959 * changing between directory scans. We now return a resume key of 0
960 * and instead look for the filename to continue from (also given
961 * to us by NT/95/smbfs/smbclient). If no other scans have been done between the
962 * findfirst/findnext (as is usual) then the directory pointer
963 * should already be at the correct place. Check this by scanning
964 * backwards looking for an exact (ie. case sensitive) filename match.
965 * If we get to the beginning of the directory and haven't found it then scan
966 * forwards again looking for a match. JRA.
969 int current_pos, start_pos;
971 void *dirptr = conn->dirptr;
972 start_pos = TellDir(dirptr);
973 for(current_pos = start_pos; current_pos >= 0; current_pos--)
975 DEBUG(7,("call_trans2findnext: seeking to pos %d\n", current_pos));
977 SeekDir(dirptr, current_pos);
978 dname = ReadDirName(dirptr);
981 * Remember, name_map_mangle is called by
982 * get_lanman2_dir_entry(), so the resume name
983 * could be mangled. Ensure we do the same
988 name_map_mangle( dname, False, True, SNUM(conn));
990 if(dname && strcsequal( resume_name, dname))
992 SeekDir(dirptr, current_pos+1);
993 DEBUG(7,("call_trans2findnext: got match at pos %d\n", current_pos+1 ));
999 * Scan forward from start if not found going backwards.
1004 DEBUG(7,("call_trans2findnext: notfound: seeking to pos %d\n", start_pos));
1005 SeekDir(dirptr, start_pos);
1006 for(current_pos = start_pos; (dname = ReadDirName(dirptr)) != NULL; SeekDir(dirptr,++current_pos))
1009 * Remember, name_map_mangle is called by
1010 * get_lanman2_dir_entry(), so the resume name
1011 * could be mangled. Ensure we do the same
1016 name_map_mangle( dname, False, True, SNUM(conn));
1018 if(dname && strcsequal( resume_name, dname))
1020 SeekDir(dirptr, current_pos+1);
1021 DEBUG(7,("call_trans2findnext: got match at pos %d\n", current_pos+1 ));
1025 } /* end if current_pos */
1026 } /* end if requires_resume_key && !continue_bit */
1028 for (i=0;(i<(int)maxentries) && !finished && !out_of_space ;i++)
1030 BOOL got_exact_match = False;
1032 /* this is a heuristic to avoid seeking the dirptr except when
1033 absolutely necessary. It allows for a filename of about 40 chars */
1034 if (space_remaining < DIRLEN_GUESS && numentries > 0)
1036 out_of_space = True;
1041 finished = !get_lanman2_dir_entry(conn,mask,dirtype,info_level,
1042 requires_resume_key,dont_descend,
1043 &p,pdata,space_remaining, &out_of_space, &got_exact_match,
1047 if (finished && out_of_space)
1050 if (!finished && !out_of_space)
1054 * As an optimisation if we know we aren't looking
1055 * for a wildcard name (ie. the name matches the wildcard exactly)
1056 * then we can finish on any (first) match.
1057 * This speeds up large directory searches. JRA.
1063 space_remaining = max_data_bytes - PTR_DIFF(p,pdata);
1066 /* Check if we can close the dirptr */
1067 if(close_after_request || (finished && close_if_end))
1069 DEBUG(5,("call_trans2findnext: closing dptr_num = %d\n", dptr_num));
1070 dptr_close(&dptr_num); /* This frees up the saved mask */
1074 /* Set up the return parameter block */
1075 SSVAL(params,0,numentries);
1076 SSVAL(params,2,finished);
1077 SSVAL(params,4,0); /* Never an EA error */
1078 SSVAL(params,6,last_name_off);
1080 send_trans2_replies( outbuf, bufsize, params, 8, pdata, PTR_DIFF(p,pdata));
1082 if ((! *directory) && dptr_path(dptr_num))
1083 slprintf(directory,sizeof(directory)-1, "(%s)",dptr_path(dptr_num));
1085 DEBUG( 3, ( "%s mask=%s directory=%s dirtype=%d numentries=%d\n",
1086 smb_fn_name(CVAL(inbuf,smb_com)),
1087 mask, directory, dirtype, numentries ) );
1092 /****************************************************************************
1093 reply to a TRANS2_QFSINFO (query filesystem info)
1094 ****************************************************************************/
1096 static int call_trans2qfsinfo(connection_struct *conn,
1097 char *inbuf, char *outbuf,
1098 int length, int bufsize,
1099 char **pparams, char **ppdata)
1101 int max_data_bytes = SVAL(inbuf, smb_mdrcnt);
1102 char *pdata = *ppdata;
1103 char *params = *pparams;
1104 uint16 info_level = SVAL(params,0);
1107 char *vname = volume_label(SNUM(conn));
1108 int snum = SNUM(conn);
1109 char *fstype = lp_fstype(SNUM(conn));
1111 DEBUG(3,("call_trans2qfsinfo: level = %d\n", info_level));
1113 if(conn->vfs_ops.stat(".",&st)!=0) {
1114 DEBUG(2,("call_trans2qfsinfo: stat of . failed (%s)\n", strerror(errno)));
1115 return (ERROR(ERRSRV,ERRinvdevice));
1118 pdata = *ppdata = Realloc(*ppdata, max_data_bytes + 1024);
1119 memset((char *)pdata,'\0',max_data_bytes + 1024);
1125 SMB_BIG_UINT dfree,dsize,bsize;
1127 conn->vfs_ops.disk_free(".",False,&bsize,&dfree,&dsize);
1128 SIVAL(pdata,l1_idFileSystem,st.st_dev);
1129 SIVAL(pdata,l1_cSectorUnit,bsize/512);
1130 SIVAL(pdata,l1_cUnit,dsize);
1131 SIVAL(pdata,l1_cUnitAvail,dfree);
1132 SSVAL(pdata,l1_cbSector,512);
1133 DEBUG(5,("call_trans2qfsinfo : bsize=%u, id=%x, cSectorUnit=%u, cUnit=%u, cUnitAvail=%u, cbSector=%d\n",
1134 (unsigned int)bsize, (unsigned int)st.st_dev, ((unsigned int)bsize)/512, (unsigned int)dsize,
1135 (unsigned int)dfree, 512));
1140 /* Return volume name */
1141 int volname_len = MIN(strlen(vname),11);
1142 data_len = l2_vol_szVolLabel + volname_len + 1;
1144 * Add volume serial number - hash of a combination of
1145 * the called hostname and the service name.
1147 SIVAL(pdata,0,str_checksum(lp_servicename(snum)) ^ (str_checksum(local_machine)<<16) );
1148 SCVAL(pdata,l2_vol_cch,volname_len);
1149 StrnCpy(pdata+l2_vol_szVolLabel,vname,volname_len);
1150 DEBUG(5,("call_trans2qfsinfo : time = %x, namelen = %d, name = %s\n",
1151 (unsigned)st.st_ctime, volname_len,
1152 pdata+l2_vol_szVolLabel));
1155 case SMB_QUERY_FS_ATTRIBUTE_INFO:
1158 SIVAL(pdata,0,FILE_CASE_PRESERVED_NAMES|FILE_CASE_SENSITIVE_SEARCH|
1159 FILE_DEVICE_IS_MOUNTED|
1160 (lp_nt_acl_support() ? FILE_PERSISTENT_ACLS : 0)); /* FS ATTRIBUTES */
1161 #if 0 /* Old code. JRA. */
1162 SIVAL(pdata,0,0x4006); /* FS ATTRIBUTES == long filenames supported? */
1163 #endif /* Old code. */
1165 SIVAL(pdata,4,128); /* Max filename component length */
1166 fstype_len = dos_PutUniCode(pdata+12,unix_to_dos(fstype,False),sizeof(pstring), False);
1167 SIVAL(pdata,8,fstype_len);
1168 data_len = 12 + fstype_len;
1169 SSVAL(outbuf,smb_flg2,SVAL(outbuf,smb_flg2)|FLAGS2_UNICODE_STRINGS);
1172 case SMB_QUERY_FS_LABEL_INFO:
1173 data_len = 4 + strlen(vname);
1174 SIVAL(pdata,0,strlen(vname));
1175 pstrcpy(pdata+4,vname);
1177 case SMB_QUERY_FS_VOLUME_INFO:
1180 * Add volume serial number - hash of a combination of
1181 * the called hostname and the service name.
1183 SIVAL(pdata,8,str_checksum(lp_servicename(snum)) ^
1184 (str_checksum(local_machine)<<16));
1186 /* NT4 always serves this up as unicode but expects it to be
1187 * delivered as ascii! (tridge && JRA)
1189 if ((get_remote_arch() != RA_WIN2K) && (global_client_caps & CAP_NT_SMBS)) {
1190 data_len = 18 + strlen(vname);
1191 SIVAL(pdata,12,strlen(vname));
1192 pstrcpy(pdata+18,vname);
1194 data_len = 18 + 2*strlen(vname);
1195 SIVAL(pdata,12,strlen(vname)*2);
1196 dos_PutUniCode(pdata+18,unix_to_dos(vname,False),sizeof(pstring), False);
1197 SSVAL(outbuf,smb_flg2,SVAL(outbuf,smb_flg2)|FLAGS2_UNICODE_STRINGS);
1200 DEBUG(5,("call_trans2qfsinfo : SMB_QUERY_FS_VOLUME_INFO namelen = %d, vol = %s\n",
1201 (int)strlen(vname),vname));
1203 case SMB_QUERY_FS_SIZE_INFO:
1205 SMB_BIG_UINT dfree,dsize,bsize;
1207 conn->vfs_ops.disk_free(".",False,&bsize,&dfree,&dsize);
1208 SBIG_UINT(pdata,0,dsize);
1209 SBIG_UINT(pdata,8,dfree);
1210 SIVAL(pdata,16,bsize/512);
1211 SIVAL(pdata,20,512);
1214 case SMB_QUERY_FS_DEVICE_INFO:
1216 SIVAL(pdata,0,0); /* dev type */
1217 SIVAL(pdata,4,0); /* characteristics */
1219 case SMB_MAC_QUERY_FS_INFO:
1221 * Thursby MAC extension... ONLY on NTFS filesystems
1222 * once we do streams then we don't need this
1224 if (strequal(lp_fstype(SNUM(conn)),"NTFS")) {
1226 SIVAL(pdata,84,0x100); /* Don't support mac... */
1231 return(ERROR(ERRDOS,ERRunknownlevel));
1235 send_trans2_replies( outbuf, bufsize, params, 0, pdata, data_len);
1237 DEBUG( 4, ( "%s info_level = %d\n",
1238 smb_fn_name(CVAL(inbuf,smb_com)), info_level) );
1243 /****************************************************************************
1244 reply to a TRANS2_SETFSINFO (set filesystem info)
1245 ****************************************************************************/
1246 static int call_trans2setfsinfo(connection_struct *conn,
1247 char *inbuf, char *outbuf, int length,
1249 char **pparams, char **ppdata)
1251 /* Just say yes we did it - there is nothing that
1252 can be set here so it doesn't matter. */
1254 DEBUG(3,("call_trans2setfsinfo\n"));
1256 if (!CAN_WRITE(conn))
1257 return(ERROR(ERRSRV,ERRaccess));
1259 outsize = set_message(outbuf,10,0,True);
1264 /****************************************************************************
1265 Reply to a TRANS2_QFILEPATHINFO or TRANSACT2_QFILEINFO (query file info by
1266 file name or file id).
1267 ****************************************************************************/
1269 static int call_trans2qfilepathinfo(connection_struct *conn,
1270 char *inbuf, char *outbuf, int length,
1272 char **pparams,char **ppdata,
1275 int max_data_bytes = SVAL(inbuf, smb_mdrcnt);
1276 char *params = *pparams;
1277 char *pdata = *ppdata;
1278 uint16 tran_call = SVAL(inbuf, smb_setup0);
1282 unsigned int data_size;
1283 SMB_STRUCT_STAT sbuf;
1289 BOOL bad_path = False;
1290 BOOL delete_pending = False;
1292 if (tran_call == TRANSACT2_QFILEINFO) {
1293 files_struct *fsp = file_fsp(params,0);
1294 info_level = SVAL(params,2);
1296 DEBUG(3,("call_trans2qfilepathinfo: TRANSACT2_QFILEINFO: level = %d\n", info_level));
1298 if(fsp && (fsp->is_directory || fsp->stat_open)) {
1300 * This is actually a QFILEINFO on a directory
1301 * handle (returned from an NT SMB). NT5.0 seems
1302 * to do this call. JRA.
1304 fname = fsp->fsp_name;
1305 unix_convert(fname,conn,0,&bad_path,&sbuf);
1306 if (!check_name(fname,conn) ||
1307 (!VALID_STAT(sbuf) && conn->vfs_ops.stat(dos_to_unix(fname,False),&sbuf))) {
1308 DEBUG(3,("fileinfo of %s failed (%s)\n",fname,strerror(errno)));
1309 if((errno == ENOENT) && bad_path)
1311 unix_ERR_class = ERRDOS;
1312 unix_ERR_code = ERRbadpath;
1314 return(UNIXERROR(ERRDOS,ERRbadpath));
1317 delete_pending = fsp->directory_delete_on_close;
1321 * Original code - this is an open file.
1323 CHECK_FSP(fsp,conn);
1326 fname = fsp->fsp_name;
1327 if (fsp->conn->vfs_ops.fstat(fsp->fd,&sbuf) != 0) {
1328 DEBUG(3,("fstat of fnum %d failed (%s)\n",fsp->fnum, strerror(errno)));
1329 return(UNIXERROR(ERRDOS,ERRbadfid));
1331 if((pos = fsp->conn->vfs_ops.lseek(fsp->fd,0,SEEK_CUR)) == -1)
1332 return(UNIXERROR(ERRDOS,ERRnoaccess));
1334 delete_pending = fsp->delete_on_close;
1338 info_level = SVAL(params,0);
1340 DEBUG(3,("call_trans2qfilepathinfo: TRANSACT2_QPATHINFO: level = %d\n", info_level));
1343 pstrcpy(fname,¶ms[6]);
1345 RESOLVE_DFSPATH(fname, conn, inbuf, outbuf);
1347 unix_convert(fname,conn,0,&bad_path,&sbuf);
1348 if (!check_name(fname,conn) ||
1349 (!VALID_STAT(sbuf) && conn->vfs_ops.stat(dos_to_unix(fname,False),&sbuf))) {
1350 DEBUG(3,("fileinfo of %s failed (%s)\n",fname,strerror(errno)));
1351 if((errno == ENOENT) && bad_path)
1353 unix_ERR_class = ERRDOS;
1354 unix_ERR_code = ERRbadpath;
1356 return(UNIXERROR(ERRDOS,ERRbadpath));
1361 DEBUG(3,("call_trans2qfilepathinfo %s level=%d call=%d total_data=%d\n",
1362 fname,info_level,tran_call,total_data));
1364 p = strrchr(fname,'/');
1370 mode = dos_mode(conn,fname,&sbuf);
1371 size = sbuf.st_size;
1372 if (mode & aDIR) size = 0;
1374 /* from now on we only want the part after the / */
1377 params = *pparams = Realloc(*pparams,2);
1378 memset((char *)params,'\0',2);
1379 data_size = max_data_bytes + 1024;
1380 pdata = *ppdata = Realloc(*ppdata, data_size);
1382 if (total_data > 0 && IVAL(pdata,0) == total_data) {
1383 /* uggh, EAs for OS2 */
1384 DEBUG(4,("Rejecting EA request with total_data=%d\n",total_data));
1385 return(ERROR(ERRDOS,ERROR_EAS_NOT_SUPPORTED));
1388 memset((char *)pdata,'\0',data_size);
1392 case SMB_INFO_STANDARD:
1393 case SMB_INFO_QUERY_EA_SIZE:
1394 data_size = (info_level==1?22:26);
1395 put_dos_date2(pdata,l1_fdateCreation,get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(conn))));
1396 put_dos_date2(pdata,l1_fdateLastAccess,sbuf.st_atime);
1397 put_dos_date2(pdata,l1_fdateLastWrite,sbuf.st_mtime); /* write time */
1398 SIVAL(pdata,l1_cbFile,(uint32)size);
1399 SIVAL(pdata,l1_cbFileAlloc,SMB_ROUNDUP(size,1024));
1400 SSVAL(pdata,l1_attrFile,mode);
1401 SIVAL(pdata,l1_attrFile+2,4); /* this is what OS2 does */
1404 case SMB_INFO_QUERY_EAS_FROM_LIST:
1406 put_dos_date2(pdata,0,get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(conn))));
1407 put_dos_date2(pdata,4,sbuf.st_atime);
1408 put_dos_date2(pdata,8,sbuf.st_mtime);
1409 SIVAL(pdata,12,(uint32)size);
1410 SIVAL(pdata,16,SMB_ROUNDUP(size,1024));
1411 SIVAL(pdata,20,mode);
1414 case SMB_INFO_QUERY_ALL_EAS:
1416 SIVAL(pdata,0,data_size);
1420 return(ERROR(ERRDOS,ERRbadfunc)); /* os/2 needs this */
1422 case SMB_QUERY_FILE_BASIC_INFO:
1423 data_size = 36; /* w95 returns 40 bytes not 36 - why ?. */
1424 put_long_date(pdata,get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(conn))));
1425 put_long_date(pdata+8,sbuf.st_atime);
1426 put_long_date(pdata+16,sbuf.st_mtime); /* write time */
1427 put_long_date(pdata+24,sbuf.st_mtime); /* change time */
1428 SIVAL(pdata,32,mode);
1430 DEBUG(5,("SMB_QFBI - "));
1432 time_t create_time = get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(conn)));
1433 DEBUG(5,("create: %s ", ctime(&create_time)));
1435 DEBUG(5,("access: %s ", ctime(&sbuf.st_atime)));
1436 DEBUG(5,("write: %s ", ctime(&sbuf.st_mtime)));
1437 DEBUG(5,("change: %s ", ctime(&sbuf.st_mtime)));
1438 DEBUG(5,("mode: %x\n", mode));
1442 case SMB_QUERY_FILE_STANDARD_INFO:
1444 SOFF_T(pdata,0,size);
1445 SOFF_T(pdata,8,size);
1446 SIVAL(pdata,16,sbuf.st_nlink);
1448 CVAL(pdata,21) = (mode&aDIR)?1:0;
1451 case SMB_QUERY_FILE_EA_INFO:
1455 /* Get the 8.3 name - used if NT SMB was negotiated. */
1456 case SMB_QUERY_FILE_ALT_NAME_INFO:
1459 pstrcpy(short_name,p);
1460 /* Mangle if not already 8.3 */
1461 if(!is_8_3(short_name, True))
1463 if(!name_map_mangle(short_name,True,True,SNUM(conn)))
1466 strupper(short_name);
1467 l = strlen(short_name);
1468 dos_PutUniCode(pdata + 4, unix_to_dos(short_name,False),sizeof(pstring), False);
1469 data_size = 4 + (2*l);
1474 case SMB_QUERY_FILE_NAME_INFO:
1476 * The first part of this code is essential
1477 * to get security descriptors to work on mapped
1478 * drives. Don't ask how I discovered this unless
1479 * you like hearing about me suffering.... :-). JRA.
1481 if(strequal(".", fname) && (global_client_caps & CAP_UNICODE)) {
1483 SSVAL(outbuf,smb_flg2,SVAL(outbuf,smb_flg2)|FLAGS2_UNICODE_STRINGS);
1484 dos_PutUniCode(pdata + 4, unix_to_dos("\\",False),sizeof(pstring), False);
1486 pstrcpy(pdata+4,fname);
1492 case SMB_QUERY_FILE_ALLOCATION_INFO:
1493 case SMB_QUERY_FILE_END_OF_FILEINFO:
1495 SOFF_T(pdata,0,size);
1498 case SMB_QUERY_FILE_ALL_INFO:
1499 put_long_date(pdata,get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(conn))));
1500 put_long_date(pdata+8,sbuf.st_atime);
1501 put_long_date(pdata+16,sbuf.st_mtime); /* write time */
1502 put_long_date(pdata+24,sbuf.st_mtime); /* change time */
1503 SIVAL(pdata,32,mode);
1505 SOFF_T(pdata,0,size);
1506 SOFF_T(pdata,8,size);
1507 SIVAL(pdata,16,sbuf.st_nlink);
1508 CVAL(pdata,20) = delete_pending;
1509 CVAL(pdata,21) = (mode&aDIR)?1:0;
1511 SINO_T(pdata,0,(SMB_INO_T)sbuf.st_ino);
1512 pdata += 8; /* index number */
1513 pdata += 4; /* EA info */
1515 SIVAL(pdata,0,0xA9);
1517 SIVAL(pdata,0,0xd01BF);
1519 SOFF_T(pdata,0,pos); /* current offset */
1521 SIVAL(pdata,0,mode); /* is this the right sort of mode info? */
1523 pdata += 4; /* alignment */
1525 pstrcpy(pdata+4,fname);
1527 data_size = PTR_DIFF(pdata,(*ppdata));
1531 /* NT4 server just returns "invalid query" to this - if we try to answer
1532 it then NTws gets a BSOD! (tridge) */
1533 case SMB_QUERY_FILE_STREAM_INFO:
1536 SIVAL(pdata,4,size);
1537 SIVAL(pdata,12,size);
1539 pstrcpy(pdata+24,fname);
1544 return(ERROR(ERRDOS,ERRunknownlevel));
1547 send_trans2_replies( outbuf, bufsize, params, 2, *ppdata, data_size);
1552 /****************************************************************************
1553 reply to a TRANS2_SETFILEINFO (set file info by fileid)
1554 ****************************************************************************/
1555 static int call_trans2setfilepathinfo(connection_struct *conn,
1556 char *inbuf, char *outbuf, int length,
1557 int bufsize, char **pparams,
1558 char **ppdata, int total_data)
1560 char *params = *pparams;
1561 char *pdata = *ppdata;
1562 uint16 tran_call = SVAL(inbuf, smb_setup0);
1571 BOOL bad_path = False;
1572 files_struct *fsp = NULL;
1574 if (!CAN_WRITE(conn))
1575 return(ERROR(ERRSRV,ERRaccess));
1577 if (tran_call == TRANSACT2_SETFILEINFO) {
1578 fsp = file_fsp(params,0);
1579 info_level = SVAL(params,2);
1581 if(fsp && (fsp->is_directory || fsp->stat_open)) {
1583 * This is actually a SETFILEINFO on a directory
1584 * handle (returned from an NT SMB). NT5.0 seems
1585 * to do this call. JRA.
1587 fname = fsp->fsp_name;
1588 unix_convert(fname,conn,0,&bad_path,&st);
1589 if (!check_name(fname,conn) ||
1590 (!VALID_STAT(st) && conn->vfs_ops.stat(dos_to_unix(fname,False),&st))) {
1591 DEBUG(3,("fileinfo of %s failed (%s)\n",fname,strerror(errno)));
1592 if((errno == ENOENT) && bad_path)
1594 unix_ERR_class = ERRDOS;
1595 unix_ERR_code = ERRbadpath;
1597 return(UNIXERROR(ERRDOS,ERRbadpath));
1601 * Original code - this is an open file.
1603 CHECK_FSP(fsp,conn);
1606 fname = fsp->fsp_name;
1609 if (fsp->conn->vfs_ops.fstat(fd,&st) != 0) {
1610 DEBUG(3,("fstat of fnum %d failed (%s)\n",fsp->fnum, strerror(errno)));
1611 return(UNIXERROR(ERRDOS,ERRbadfid));
1616 info_level = SVAL(params,0);
1618 pstrcpy(fname,¶ms[6]);
1619 unix_convert(fname,conn,0,&bad_path,&st);
1620 if(!check_name(fname, conn))
1622 if((errno == ENOENT) && bad_path)
1624 unix_ERR_class = ERRDOS;
1625 unix_ERR_code = ERRbadpath;
1627 return(UNIXERROR(ERRDOS,ERRbadpath));
1630 if(!VALID_STAT(st) && conn->vfs_ops.stat(dos_to_unix(fname,False),&st)!=0) {
1631 DEBUG(3,("stat of %s failed (%s)\n", fname, strerror(errno)));
1632 if((errno == ENOENT) && bad_path)
1634 unix_ERR_class = ERRDOS;
1635 unix_ERR_code = ERRbadpath;
1637 return(UNIXERROR(ERRDOS,ERRbadpath));
1641 DEBUG(3,("call_trans2setfilepathinfo(%d) %s info_level=%d totdata=%d\n",
1642 tran_call,fname,info_level,total_data));
1644 /* Realloc the parameter and data sizes */
1645 params = *pparams = Realloc(*pparams,2);
1647 return(ERROR(ERRDOS,ERRnomem));
1652 tvs.modtime = st.st_mtime;
1653 tvs.actime = st.st_atime;
1654 mode = dos_mode(conn,fname,&st);
1656 if (total_data > 0 && IVAL(pdata,0) == total_data) {
1657 /* uggh, EAs for OS2 */
1658 DEBUG(4,("Rejecting EA request with total_data=%d\n",total_data));
1659 return(ERROR(ERRDOS,ERROR_EAS_NOT_SUPPORTED));
1664 case SMB_INFO_STANDARD:
1665 case SMB_INFO_QUERY_EA_SIZE:
1668 tvs.actime = make_unix_date2(pdata+l1_fdateLastAccess);
1671 tvs.modtime = make_unix_date2(pdata+l1_fdateLastWrite);
1673 mode = SVAL(pdata,l1_attrFile);
1674 size = IVAL(pdata,l1_cbFile);
1678 /* XXXX um, i don't think this is right.
1679 it's also not in the cifs6.txt spec.
1681 case SMB_INFO_QUERY_EAS_FROM_LIST:
1682 tvs.actime = make_unix_date2(pdata+8);
1683 tvs.modtime = make_unix_date2(pdata+12);
1684 size = IVAL(pdata,16);
1685 mode = IVAL(pdata,24);
1688 /* XXXX nor this. not in cifs6.txt, either. */
1689 case SMB_INFO_QUERY_ALL_EAS:
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 case SMB_SET_FILE_BASIC_INFO:
1698 /* Patch to do this correctly from Paul Eggert <eggert@twinsun.com>. */
1700 time_t changed_time;
1702 /* Ignore create time at offset pdata. */
1705 tvs.actime = interpret_long_date(pdata+8);
1707 write_time = interpret_long_date(pdata+16);
1708 changed_time = interpret_long_date(pdata+24);
1710 tvs.modtime = MIN(write_time, changed_time);
1712 /* Prefer a defined time to an undefined one. */
1713 if (tvs.modtime == (time_t)0 || tvs.modtime == (time_t)-1)
1714 tvs.modtime = (write_time == (time_t)0 || write_time == (time_t)-1
1718 #if 0 /* Needs more testing... */
1719 /* Test from Luke to prevent Win95 from
1720 setting incorrect values here.
1722 if (tvs.actime < tvs.modtime)
1723 return(ERROR(ERRDOS,ERRnoaccess));
1724 #endif /* Needs more testing... */
1727 mode = IVAL(pdata,32);
1732 * NT seems to use this call with a size of zero
1733 * to mean truncate the file. JRA.
1736 case SMB_SET_FILE_ALLOCATION_INFO:
1738 SMB_OFF_T newsize = IVAL(pdata,0);
1739 #ifdef LARGE_SMB_OFF_T
1740 newsize |= (((SMB_OFF_T)IVAL(pdata,4)) << 32);
1741 #else /* LARGE_SMB_OFF_T */
1742 if (IVAL(pdata,4) != 0) /* more than 32 bits? */
1743 return(ERROR(ERRDOS,ERRunknownlevel));
1744 #endif /* LARGE_SMB_OFF_T */
1745 DEBUG(10,("call_trans2setfilepathinfo: Set file allocation info for file %s to %.0f\n", fname, (double)newsize ));
1751 case SMB_SET_FILE_END_OF_FILE_INFO:
1753 size = IVAL(pdata,0);
1754 #ifdef LARGE_SMB_OFF_T
1755 size |= (((SMB_OFF_T)IVAL(pdata,4)) << 32);
1756 #else /* LARGE_SMB_OFF_T */
1757 if (IVAL(pdata,4) != 0) /* more than 32 bits? */
1758 return(ERROR(ERRDOS,ERRunknownlevel));
1759 #endif /* LARGE_SMB_OFF_T */
1760 DEBUG(10,("call_trans2setfilepathinfo: Set end of file info for file %s to %.0f\n", fname, (double)size ));
1764 case SMB_SET_FILE_DISPOSITION_INFO: /* Set delete on close for open file. */
1766 if ((tran_call == TRANSACT2_SETFILEINFO) && (fsp != NULL))
1768 BOOL delete_on_close = (CVAL(pdata,0) ? True : False);
1770 if(fsp->is_directory)
1772 fsp->directory_delete_on_close = delete_on_close;
1773 DEBUG(10, ("call_trans2setfilepathinfo: %s delete on close flag for fnum = %d, directory %s\n",
1774 delete_on_close ? "Added" : "Removed", fsp->fnum, fsp->fsp_name ));
1777 else if(fsp->stat_open)
1779 DEBUG(10, ("call_trans2setfilepathinfo: %s delete on close flag for fnum = %d, stat open %s\n",
1780 delete_on_close ? "Added" : "Removed", fsp->fnum, fsp->fsp_name ));
1786 * We can only set the delete on close flag if
1787 * the share mode contained ALLOW_SHARE_DELETE
1790 if(!GET_ALLOW_SHARE_DELETE(fsp->share_mode))
1791 return(ERROR(ERRDOS,ERRnoaccess));
1794 * If the flag has been set then
1795 * modify the share mode entry for all files we have open
1796 * on this device and inode to tell other smbds we have
1797 * changed the delete on close flag.
1800 if(delete_on_close && !GET_DELETE_ON_CLOSE_FLAG(fsp->share_mode))
1803 files_struct *iterate_fsp;
1804 SMB_DEV_T dev = fsp->dev;
1805 SMB_INO_T inode = fsp->inode;
1806 int num_share_modes;
1807 share_mode_entry *current_shares = NULL;
1809 if (lock_share_entry_fsp(fsp) == False)
1810 return(ERROR(ERRDOS,ERRnoaccess));
1813 * Before we allow this we need to ensure that all current opens
1814 * on the file have the GET_ALLOW_SHARE_DELETE flag set. If they
1815 * do not then we deny this (as we are essentially deleting the
1816 * file at this point.
1819 num_share_modes = get_share_modes(conn, dev, inode, ¤t_shares);
1820 for(i = 0; i < num_share_modes; i++)
1822 if(!GET_ALLOW_SHARE_DELETE(current_shares[i].share_mode))
1824 DEBUG(5,("call_trans2setfilepathinfo: refusing to set delete on close flag for fnum = %d, \
1825 file %s as a share exists that was not opened with FILE_DELETE access.\n",
1826 fsp->fnum, fsp->fsp_name ));
1831 unlock_share_entry_fsp(fsp);
1834 * current_shares was malloced by get_share_modes - free it here.
1837 free((char *)current_shares);
1840 * Even though share violation would be more appropriate here,
1841 * return ERRnoaccess as that's what NT does.
1844 return(ERROR(ERRDOS,ERRnoaccess));
1849 * current_shares was malloced by get_share_modes - free it here.
1852 free((char *)current_shares);
1854 DEBUG(10,("call_trans2setfilepathinfo: %s delete on close flag for fnum = %d, file %s\n",
1855 delete_on_close ? "Adding" : "Removing", fsp->fnum, fsp->fsp_name ));
1858 * Go through all files we have open on the same device and
1859 * inode (hanging off the same hash bucket) and set the DELETE_ON_CLOSE_FLAG.
1860 * Other smbd's that have this file open will have to fend for themselves. We
1861 * take care of this (rare) case in close_file(). See the comment there.
1864 for(iterate_fsp = file_find_di_first(dev, inode); iterate_fsp;
1865 iterate_fsp = file_find_di_next(iterate_fsp))
1867 int new_share_mode = (delete_on_close ?
1868 (iterate_fsp->share_mode | DELETE_ON_CLOSE_FLAG) :
1869 (iterate_fsp->share_mode & ~DELETE_ON_CLOSE_FLAG) );
1871 DEBUG(10,("call_trans2setfilepathinfo: Changing share mode for fnum %d, file %s \
1872 dev = %x, inode = %.0f from %x to %x\n",
1873 iterate_fsp->fnum, iterate_fsp->fsp_name, (unsigned int)dev,
1874 (double)inode, iterate_fsp->share_mode, new_share_mode ));
1876 if(modify_share_mode(iterate_fsp, new_share_mode, iterate_fsp->oplock_type)==False)
1877 DEBUG(0,("call_trans2setfilepathinfo: failed to change delete on close for fnum %d, \
1878 dev = %x, inode = %.0f\n", iterate_fsp->fnum, (unsigned int)dev, (double)inode));
1882 * Set the delete on close flag in the reference
1883 * counted struct. Delete when the last reference
1886 fsp->delete_on_close = delete_on_close;
1888 unlock_share_entry_fsp(fsp);
1890 DEBUG(10, ("call_trans2setfilepathinfo: %s delete on close flag for fnum = %d, file %s\n",
1891 delete_on_close ? "Added" : "Removed", fsp->fnum, fsp->fsp_name ));
1893 } /* end if(delete_on_close && !GET_DELETE_ON_CLOSE_FLAG(fsp->share_mode)) */
1894 } /* end if is_directory. */
1896 return(ERROR(ERRDOS,ERRunknownlevel));
1902 return(ERROR(ERRDOS,ERRunknownlevel));
1906 /* get some defaults (no modifications) if any info is zero or -1. */
1907 if (tvs.actime == (time_t)0 || tvs.actime == (time_t)-1)
1908 tvs.actime = st.st_atime;
1910 if (tvs.modtime == (time_t)0 || tvs.modtime == (time_t)-1)
1911 tvs.modtime = st.st_mtime;
1913 DEBUG(6,("actime: %s " , ctime(&tvs.actime)));
1914 DEBUG(6,("modtime: %s ", ctime(&tvs.modtime)));
1915 DEBUG(6,("size: %.0f ", (double)size));
1916 DEBUG(6,("mode: %x\n" , mode));
1918 if(!((info_level == SMB_SET_FILE_END_OF_FILE_INFO) ||
1919 (info_level == SMB_SET_FILE_ALLOCATION_INFO))) {
1921 * Only do this test if we are not explicitly
1922 * changing the size of a file.
1928 /* Try and set the times, size and mode of this file -
1929 if they are different from the current values
1931 if (st.st_mtime != tvs.modtime || st.st_atime != tvs.actime) {
1934 * This was a setfileinfo on an open file.
1935 * NT does this a lot. It's actually pointless
1936 * setting the time here, as it will be overwritten
1937 * on the next write, so we save the request
1938 * away and will set it on file code. JRA.
1941 if (tvs.modtime != (time_t)0 && tvs.modtime != (time_t)-1) {
1942 DEBUG(10,("call_trans2setfilepathinfo: setting pending modtime to %s\n",
1943 ctime(&tvs.modtime) ));
1944 fsp->pending_modtime = tvs.modtime;
1949 DEBUG(10,("call_trans2setfilepathinfo: setting utimes to modified values.\n"));
1951 if(file_utime(conn, fname, &tvs)!=0)
1952 return(UNIXERROR(ERRDOS,ERRnoaccess));
1956 /* check the mode isn't different, before changing it */
1957 if ((mode != 0) && (mode != dos_mode(conn, fname, &st))) {
1959 DEBUG(10,("call_trans2setfilepathinfo: file %s : setting dos mode %x\n",
1962 if(file_chmod(conn, fname, mode, NULL)) {
1963 DEBUG(2,("chmod of %s failed (%s)\n", fname, strerror(errno)));
1964 return(UNIXERROR(ERRDOS,ERRnoaccess));
1968 if(size != st.st_size) {
1970 DEBUG(10,("call_trans2setfilepathinfo: file %s : setting new size to %.0f\n",
1971 fname, (double)size ));
1974 fd = conn->vfs_ops.open(dos_to_unix(fname,False),O_RDWR,0);
1976 return(UNIXERROR(ERRDOS,ERRbadpath));
1977 set_filelen(fd, size); /* tpot vfs */
1978 conn->vfs_ops.close(fd);
1980 set_filelen(fd, size); /* tpot vfs */
1984 set_filelen_write_cache(fsp, size);
1989 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
1994 /****************************************************************************
1995 reply to a TRANS2_MKDIR (make directory with extended attributes).
1996 ****************************************************************************/
1997 static int call_trans2mkdir(connection_struct *conn,
1998 char *inbuf, char *outbuf, int length, int bufsize,
1999 char **pparams, char **ppdata)
2001 char *params = *pparams;
2004 BOOL bad_path = False;
2006 if (!CAN_WRITE(conn))
2007 return(ERROR(ERRSRV,ERRaccess));
2009 pstrcpy(directory, ¶ms[4]);
2011 DEBUG(3,("call_trans2mkdir : name = %s\n", directory));
2013 unix_convert(directory,conn,0,&bad_path,NULL);
2014 if (check_name(directory,conn))
2015 ret = conn->vfs_ops.mkdir(dos_to_unix(directory,False),
2016 unix_mode(conn,aDIR,directory));
2020 DEBUG(5,("call_trans2mkdir error (%s)\n", strerror(errno)));
2021 if((errno == ENOENT) && bad_path)
2023 unix_ERR_class = ERRDOS;
2024 unix_ERR_code = ERRbadpath;
2026 return(UNIXERROR(ERRDOS,ERRnoaccess));
2029 /* Realloc the parameter and data sizes */
2030 params = *pparams = Realloc(*pparams,2);
2032 return(ERROR(ERRDOS,ERRnomem));
2036 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
2041 /****************************************************************************
2042 reply to a TRANS2_FINDNOTIFYFIRST (start monitoring a directory for changes)
2043 We don't actually do this - we just send a null response.
2044 ****************************************************************************/
2045 static int call_trans2findnotifyfirst(connection_struct *conn,
2046 char *inbuf, char *outbuf,
2047 int length, int bufsize,
2048 char **pparams, char **ppdata)
2050 static uint16 fnf_handle = 257;
2051 char *params = *pparams;
2052 uint16 info_level = SVAL(params,4);
2054 DEBUG(3,("call_trans2findnotifyfirst - info_level %d\n", info_level));
2062 return(ERROR(ERRDOS,ERRunknownlevel));
2065 /* Realloc the parameter and data sizes */
2066 params = *pparams = Realloc(*pparams,6);
2068 return(ERROR(ERRDOS,ERRnomem));
2070 SSVAL(params,0,fnf_handle);
2071 SSVAL(params,2,0); /* No changes */
2072 SSVAL(params,4,0); /* No EA errors */
2079 send_trans2_replies(outbuf, bufsize, params, 6, *ppdata, 0);
2084 /****************************************************************************
2085 reply to a TRANS2_FINDNOTIFYNEXT (continue monitoring a directory for
2086 changes). Currently this does nothing.
2087 ****************************************************************************/
2088 static int call_trans2findnotifynext(connection_struct *conn,
2089 char *inbuf, char *outbuf,
2090 int length, int bufsize,
2091 char **pparams, char **ppdata)
2093 char *params = *pparams;
2095 DEBUG(3,("call_trans2findnotifynext\n"));
2097 /* Realloc the parameter and data sizes */
2098 params = *pparams = Realloc(*pparams,4);
2100 return(ERROR(ERRDOS,ERRnomem));
2102 SSVAL(params,0,0); /* No changes */
2103 SSVAL(params,2,0); /* No EA errors */
2105 send_trans2_replies(outbuf, bufsize, params, 4, *ppdata, 0);
2110 /****************************************************************************
2111 reply to a TRANS2_GET_DFS_REFERRAL - Shirish Kalele <kalele@veritas.com>
2112 ****************************************************************************/
2113 static int call_trans2getdfsreferral(connection_struct *conn, char* inbuf,
2114 char* outbuf, int length, int bufsize,
2115 char** pparams, char** ppdata)
2117 char *params = *pparams;
2118 enum remote_arch_types ra_type = get_remote_arch();
2119 BOOL NT_arch = ((ra_type == RA_WINNT) || (ra_type == RA_WIN2K));
2122 int max_referral_level = SVAL(params,0);
2125 DEBUG(10,("call_trans2getdfsreferral\n"));
2127 if(!lp_host_msdfs())
2128 return(ERROR(ERRDOS,ERRbadfunc));
2130 /* if pathname is in UNICODE, convert to DOS */
2131 /* NT always sends in UNICODE, may not set UNICODE flag */
2132 if(NT_arch || (SVAL(inbuf,smb_flg2) & FLAGS2_UNICODE_STRINGS))
2134 unistr_to_dos(pathname, ¶ms[2]);
2135 DEBUG(10,("UNICODE referral for %s\n",pathname));
2138 pstrcpy(pathname,¶ms[2]);
2140 if((reply_size = setup_dfs_referral(pathname,max_referral_level,ppdata)) < 0)
2141 return(ERROR(ERRDOS,ERRbadfile));
2143 SSVAL(outbuf,smb_flg2,SVAL(outbuf,smb_flg2) | FLAGS2_UNICODE_STRINGS |
2144 FLAGS2_DFS_PATHNAMES);
2145 send_trans2_replies(outbuf,bufsize,0,0,*ppdata,reply_size);
2151 /****************************************************************************
2152 reply to a SMBfindclose (stop trans2 directory search)
2153 ****************************************************************************/
2154 int reply_findclose(connection_struct *conn,
2155 char *inbuf,char *outbuf,int length,int bufsize)
2158 int dptr_num=SVALS(inbuf,smb_vwv0);
2160 DEBUG(3,("reply_findclose, dptr_num = %d\n", dptr_num));
2162 dptr_close(&dptr_num);
2164 outsize = set_message(outbuf,0,0,True);
2166 DEBUG(3,("SMBfindclose dptr_num = %d\n", dptr_num));
2171 /****************************************************************************
2172 reply to a SMBfindnclose (stop FINDNOTIFYFIRST directory search)
2173 ****************************************************************************/
2174 int reply_findnclose(connection_struct *conn,
2175 char *inbuf,char *outbuf,int length,int bufsize)
2180 dptr_num = SVAL(inbuf,smb_vwv0);
2182 DEBUG(3,("reply_findnclose, dptr_num = %d\n", dptr_num));
2184 /* We never give out valid handles for a
2185 findnotifyfirst - so any dptr_num is ok here.
2188 outsize = set_message(outbuf,0,0,True);
2190 DEBUG(3,("SMB_findnclose dptr_num = %d\n", dptr_num));
2196 /****************************************************************************
2197 reply to a SMBtranss2 - just ignore it!
2198 ****************************************************************************/
2199 int reply_transs2(connection_struct *conn,
2200 char *inbuf,char *outbuf,int length,int bufsize)
2202 DEBUG(4,("Ignoring transs2 of length %d\n",length));
2206 /****************************************************************************
2207 reply to a SMBtrans2
2208 ****************************************************************************/
2209 int reply_trans2(connection_struct *conn,
2210 char *inbuf,char *outbuf,int length,int bufsize)
2213 unsigned int total_params = SVAL(inbuf, smb_tpscnt);
2214 unsigned int total_data =SVAL(inbuf, smb_tdscnt);
2216 unsigned int max_param_reply = SVAL(inbuf, smb_mprcnt);
2217 unsigned int max_data_reply = SVAL(inbuf, smb_mdrcnt);
2218 unsigned int max_setup_fields = SVAL(inbuf, smb_msrcnt);
2219 BOOL close_tid = BITSETW(inbuf+smb_flags,0);
2220 BOOL no_final_response = BITSETW(inbuf+smb_flags,1);
2221 int32 timeout = IVALS(inbuf,smb_timeout);
2223 unsigned int suwcnt = SVAL(inbuf, smb_suwcnt);
2224 unsigned int tran_call = SVAL(inbuf, smb_setup0);
2225 char *params = NULL, *data = NULL;
2226 int num_params, num_params_sofar, num_data, num_data_sofar;
2228 if(global_oplock_break && (tran_call == TRANSACT2_OPEN)) {
2229 /* Queue this open message as we are the process of an
2232 DEBUG(2,("reply_trans2: queueing message trans2open due to being "));
2233 DEBUGADD(2,( "in oplock break state.\n"));
2235 push_oplock_pending_smb_message(inbuf, length);
2239 outsize = set_message(outbuf,0,0,True);
2241 /* All trans2 messages we handle have smb_sucnt == 1 - ensure this
2242 is so as a sanity check */
2244 DEBUG(2,("Invalid smb_sucnt in trans2 call\n"));
2245 return(ERROR(ERRSRV,ERRerror));
2248 /* Allocate the space for the maximum needed parameters and data */
2249 if (total_params > 0)
2250 params = (char *)malloc(total_params);
2252 data = (char *)malloc(total_data);
2254 if ((total_params && !params) || (total_data && !data)) {
2255 DEBUG(2,("Out of memory in reply_trans2\n"));
2260 return(ERROR(ERRDOS,ERRnomem));
2263 /* Copy the param and data bytes sent with this request into
2264 the params buffer */
2265 num_params = num_params_sofar = SVAL(inbuf,smb_pscnt);
2266 num_data = num_data_sofar = SVAL(inbuf, smb_dscnt);
2268 if (num_params > total_params || num_data > total_data)
2269 exit_server("invalid params in reply_trans2");
2272 memcpy( params, smb_base(inbuf) + SVAL(inbuf, smb_psoff), num_params);
2274 memcpy( data, smb_base(inbuf) + SVAL(inbuf, smb_dsoff), num_data);
2276 if(num_data_sofar < total_data || num_params_sofar < total_params) {
2277 /* We need to send an interim response then receive the rest
2278 of the parameter/data bytes */
2279 outsize = set_message(outbuf,0,0,True);
2280 send_smb(smbd_server_fd(),outbuf);
2282 while (num_data_sofar < total_data ||
2283 num_params_sofar < total_params) {
2286 ret = receive_next_smb(inbuf,bufsize,SMB_SECONDARY_WAIT);
2289 (CVAL(inbuf, smb_com) != SMBtranss2)) || !ret) {
2290 outsize = set_message(outbuf,0,0,True);
2292 DEBUG(0,("reply_trans2: Invalid secondary trans2 packet\n"));
2294 DEBUG(0,("reply_trans2: %s in getting secondary trans2 response.\n",
2295 (smb_read_error == READ_ERROR) ? "error" : "timeout" ));
2300 return(ERROR(ERRSRV,ERRerror));
2303 /* Revise total_params and total_data in case
2304 they have changed downwards */
2305 total_params = SVAL(inbuf, smb_tpscnt);
2306 total_data = SVAL(inbuf, smb_tdscnt);
2307 num_params_sofar += (num_params = SVAL(inbuf,smb_spscnt));
2308 num_data_sofar += ( num_data = SVAL(inbuf, smb_sdscnt));
2309 if (num_params_sofar > total_params || num_data_sofar > total_data)
2310 exit_server("data overflow in trans2");
2312 memcpy( ¶ms[ SVAL(inbuf, smb_spsdisp)],
2313 smb_base(inbuf) + SVAL(inbuf, smb_spsoff), num_params);
2314 memcpy( &data[SVAL(inbuf, smb_sdsdisp)],
2315 smb_base(inbuf)+ SVAL(inbuf, smb_sdsoff), num_data);
2319 if (Protocol >= PROTOCOL_NT1) {
2320 uint16 flg2 = SVAL(outbuf,smb_flg2);
2321 SSVAL(outbuf,smb_flg2,flg2 | 0x40); /* IS_LONG_NAME */
2324 /* Now we must call the relevant TRANS2 function */
2326 case TRANSACT2_OPEN:
2327 outsize = call_trans2open(conn,
2328 inbuf, outbuf, bufsize,
2332 case TRANSACT2_FINDFIRST:
2333 outsize = call_trans2findfirst(conn, inbuf, outbuf,
2334 bufsize, ¶ms, &data);
2337 case TRANSACT2_FINDNEXT:
2338 outsize = call_trans2findnext(conn, inbuf, outbuf,
2343 case TRANSACT2_QFSINFO:
2344 outsize = call_trans2qfsinfo(conn, inbuf, outbuf,
2345 length, bufsize, ¶ms,
2349 case TRANSACT2_SETFSINFO:
2350 outsize = call_trans2setfsinfo(conn, inbuf, outbuf,
2355 case TRANSACT2_QPATHINFO:
2356 case TRANSACT2_QFILEINFO:
2357 outsize = call_trans2qfilepathinfo(conn, inbuf, outbuf,
2359 ¶ms, &data, total_data);
2361 case TRANSACT2_SETPATHINFO:
2362 case TRANSACT2_SETFILEINFO:
2363 outsize = call_trans2setfilepathinfo(conn, inbuf, outbuf,
2369 case TRANSACT2_FINDNOTIFYFIRST:
2370 outsize = call_trans2findnotifyfirst(conn, inbuf, outbuf,
2375 case TRANSACT2_FINDNOTIFYNEXT:
2376 outsize = call_trans2findnotifynext(conn, inbuf, outbuf,
2380 case TRANSACT2_MKDIR:
2381 outsize = call_trans2mkdir(conn, inbuf, outbuf, length,
2382 bufsize, ¶ms, &data);
2385 case TRANSACT2_GET_DFS_REFERRAL:
2386 outsize = call_trans2getdfsreferral(conn,inbuf,outbuf,length,
2387 bufsize, ¶ms, &data);
2390 /* Error in request */
2391 DEBUG(2,("Unknown request %d in trans2 call\n", tran_call));
2396 return (ERROR(ERRSRV,ERRerror));
2399 /* As we do not know how many data packets will need to be
2400 returned here the various call_trans2xxxx calls
2401 must send their own. Thus a call_trans2xxx routine only
2402 returns a value other than -1 when it wants to send
2410 return outsize; /* If a correct response was needed the
2411 call_trans2xxx calls have already sent
2412 it. If outsize != -1 then it is returning */