4 Unix SMB/Netbios implementation.
6 SMB transaction2 handling
7 Copyright (C) Jeremy Allison 1994-1998
9 Extensively modified by Andrew Tridgell, 1995
11 This program is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation; either version 2 of the License, or
14 (at your option) any later version.
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU General Public License for more details.
21 You should have received a copy of the GNU General Public License
22 along with this program; if not, write to the Free Software
23 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
28 extern int DEBUGLEVEL;
30 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(smbd_server_fd(),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(smbd_server_fd(),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);
225 if (!check_name(fname,conn))
227 if((errno == ENOENT) && bad_path)
229 unix_ERR_class = ERRDOS;
230 unix_ERR_code = ERRbadpath;
232 return(UNIXERROR(ERRDOS,ERRnoaccess));
235 unixmode = unix_mode(conn,open_attr | aARCH, fname);
237 fsp = open_file_shared(conn,fname,open_mode,open_ofun,unixmode,
238 oplock_request, &rmode,&smb_action);
242 if((errno == ENOENT) && bad_path)
244 unix_ERR_class = ERRDOS;
245 unix_ERR_code = ERRbadpath;
247 return(UNIXERROR(ERRDOS,ERRnoaccess));
250 if (fsp->conn->vfs_ops.fstat(fsp->fd,&sbuf) != 0) {
251 close_file(fsp,False);
252 return(UNIXERROR(ERRDOS,ERRnoaccess));
256 fmode = dos_mode(conn,fname,&sbuf);
257 mtime = sbuf.st_mtime;
260 close_file(fsp,False);
261 return(ERROR(ERRDOS,ERRnoaccess));
264 /* Realloc the size of parameters and data we will return */
265 params = *pparams = Realloc(*pparams, 28);
267 return(ERROR(ERRDOS,ERRnomem));
269 memset((char *)params,'\0',28);
270 SSVAL(params,0,fsp->fnum);
271 SSVAL(params,2,fmode);
272 put_dos_date2(params,4, mtime);
273 SIVAL(params,8, (uint32)size);
274 SSVAL(params,12,rmode);
276 if (oplock_request && lp_fake_oplocks(SNUM(conn))) {
277 smb_action |= EXTENDED_OPLOCK_GRANTED;
280 SSVAL(params,18,smb_action);
282 * WARNING - this may need to be changed if SMB_INO_T <> 4 bytes.
284 SIVAL(params,20,inode);
286 /* Send the required number of replies */
287 send_trans2_replies(outbuf, bufsize, params, 28, *ppdata, 0);
292 /*********************************************************
293 * Routine to check if a given string matches exactly.
294 * as a special case a mask of "." does NOT match. That
295 * is required for correct wildcard semantics
296 * Case can be significant or not.
297 **********************************************************/
298 static BOOL exact_match(char *str,char *mask, BOOL case_sig)
300 if (mask[0] == '.' && mask[1] == 0) return False;
301 if (case_sig) return strcmp(str,mask)==0;
302 return strcasecmp(str,mask) == 0;
305 /****************************************************************************
306 get a level dependent lanman2 dir entry.
307 ****************************************************************************/
308 static BOOL get_lanman2_dir_entry(connection_struct *conn,
309 char *path_mask,int dirtype,int info_level,
310 int requires_resume_key,
311 BOOL dont_descend,char **ppdata,
312 char *base_data, int space_remaining,
313 BOOL *out_of_space, BOOL *got_exact_match,
318 SMB_STRUCT_STAT sbuf;
322 char *p, *pdata = *ppdata;
328 time_t mdate=0, adate=0, cdate=0;
331 int nt_extmode; /* Used for NT connections instead of mode */
332 BOOL needslash = ( conn->dirpath[strlen(conn->dirpath) -1] != '/');
335 *out_of_space = False;
336 *got_exact_match = False;
341 p = strrchr(path_mask,'/');
350 pstrcpy(mask, path_mask);
356 /* Needed if we run out of space */
357 prev_dirpos = TellDir(conn->dirptr);
358 dname = ReadDirName(conn->dirptr);
361 * Due to bugs in NT client redirectors we are not using
362 * resume keys any more - set them to zero.
363 * Check out the related comments in findfirst/findnext.
369 DEBUG(8,("get_lanman2_dir_entry:readdir on dirptr 0x%lx now at offset %d\n",
370 (long)conn->dirptr,TellDir(conn->dirptr)));
375 pstrcpy(fname,dname);
377 if(!(got_match = *got_exact_match = exact_match(fname, mask, case_sensitive)))
378 got_match = mask_match(fname, mask, case_sensitive);
380 if(!got_match && !is_8_3(fname, False)) {
383 * It turns out that NT matches wildcards against
384 * both long *and* short names. This may explain some
385 * of the wildcard wierdness from old DOS clients
386 * that some people have been seeing.... JRA.
390 pstrcpy( newname, fname);
391 name_map_mangle( newname, True, False, SNUM(conn));
392 if(!(got_match = *got_exact_match = exact_match(newname, mask, case_sensitive)))
393 got_match = mask_match(newname, mask, case_sensitive);
398 BOOL isdots = (strequal(fname,"..") || strequal(fname,"."));
399 if (dont_descend && !isdots)
402 pstrcpy(pathreal,conn->dirpath);
404 pstrcat(pathreal,"/");
405 pstrcat(pathreal,dname);
406 if (conn->vfs_ops.stat(dos_to_unix(pathreal,False),&sbuf) != 0)
408 DEBUG(5,("get_lanman2_dir_entry:Couldn't stat [%s] (%s)\n",pathreal,strerror(errno)));
412 mode = dos_mode(conn,pathreal,&sbuf);
414 if (!dir_check_ftype(conn,mode,&sbuf,dirtype)) {
415 DEBUG(5,("[%s] attribs didn't match %x\n",fname,dirtype));
420 mdate = sbuf.st_mtime;
421 adate = sbuf.st_atime;
422 cdate = get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(conn)));
426 DEBUG(5,("get_lanman2_dir_entry found %s fname=%s\n",pathreal,fname));
432 name_map_mangle(fname,False,True,SNUM(conn));
437 nt_extmode = mode ? mode : FILE_ATTRIBUTE_NORMAL;
442 if(requires_resume_key) {
446 put_dos_date2(p,l1_fdateCreation,cdate);
447 put_dos_date2(p,l1_fdateLastAccess,adate);
448 put_dos_date2(p,l1_fdateLastWrite,mdate);
449 SIVAL(p,l1_cbFile,(uint32)size);
450 SIVAL(p,l1_cbFileAlloc,SMB_ROUNDUP(size,1024));
451 SSVAL(p,l1_attrFile,mode);
452 SCVAL(p,l1_cchName,strlen(fname));
453 pstrcpy(p + l1_achName, fname);
454 nameptr = p + l1_achName;
455 p += l1_achName + strlen(fname) + 1;
460 if(requires_resume_key) {
464 put_dos_date2(p,l2_fdateCreation,cdate);
465 put_dos_date2(p,l2_fdateLastAccess,adate);
466 put_dos_date2(p,l2_fdateLastWrite,mdate);
467 SIVAL(p,l2_cbFile,(uint32)size);
468 SIVAL(p,l2_cbFileAlloc,SMB_ROUNDUP(size,1024));
469 SSVAL(p,l2_attrFile,mode);
470 SIVAL(p,l2_cbList,0); /* No extended attributes */
471 SCVAL(p,l2_cchName,strlen(fname));
472 pstrcpy(p + l2_achName, fname);
473 nameptr = p + l2_achName;
474 p += l2_achName + strlen(fname) + 1;
479 put_dos_date2(p,4,cdate);
480 put_dos_date2(p,8,adate);
481 put_dos_date2(p,12,mdate);
482 SIVAL(p,16,(uint32)size);
483 SIVAL(p,20,SMB_ROUNDUP(size,1024));
486 CVAL(p,30) = strlen(fname);
487 pstrcpy(p+31, fname);
489 p += 31 + strlen(fname) + 1;
493 if(requires_resume_key) {
497 SIVAL(p,0,33+strlen(fname)+1);
498 put_dos_date2(p,4,cdate);
499 put_dos_date2(p,8,adate);
500 put_dos_date2(p,12,mdate);
501 SIVAL(p,16,(uint32)size);
502 SIVAL(p,20,SMB_ROUNDUP(size,1024));
504 CVAL(p,32) = strlen(fname);
505 pstrcpy(p + 33, fname);
507 p += 33 + strlen(fname) + 1;
510 case SMB_FIND_FILE_BOTH_DIRECTORY_INFO:
511 was_8_3 = is_8_3(fname, True);
512 len = 94+strlen(fname);
513 len = (len + 3) & ~3;
514 SIVAL(p,0,len); p += 4;
515 SIVAL(p,0,reskey); p += 4;
516 put_long_date(p,cdate); p += 8;
517 put_long_date(p,adate); p += 8;
518 put_long_date(p,mdate); p += 8;
519 put_long_date(p,mdate); p += 8;
523 SIVAL(p,0,nt_extmode); p += 4;
524 SIVAL(p,0,strlen(fname)); p += 4;
525 SIVAL(p,0,0); p += 4;
528 name_map_mangle(p+2,True,True,SNUM(conn));
530 SSVAL(p, 0, strlen(p+2));
537 pstrcpy(p,fname); p += strlen(p);
541 case SMB_FIND_FILE_DIRECTORY_INFO:
542 len = 64+strlen(fname);
543 len = (len + 3) & ~3;
544 SIVAL(p,0,len); p += 4;
545 SIVAL(p,0,reskey); p += 4;
546 put_long_date(p,cdate); p += 8;
547 put_long_date(p,adate); p += 8;
548 put_long_date(p,mdate); p += 8;
549 put_long_date(p,mdate); p += 8;
553 SIVAL(p,0,nt_extmode); p += 4;
554 SIVAL(p,0,strlen(fname)); p += 4;
560 case SMB_FIND_FILE_FULL_DIRECTORY_INFO:
561 len = 68+strlen(fname);
562 len = (len + 3) & ~3;
563 SIVAL(p,0,len); p += 4;
564 SIVAL(p,0,reskey); p += 4;
565 put_long_date(p,cdate); p += 8;
566 put_long_date(p,adate); p += 8;
567 put_long_date(p,mdate); p += 8;
568 put_long_date(p,mdate); p += 8;
572 SIVAL(p,0,nt_extmode); p += 4;
573 SIVAL(p,0,strlen(fname)); p += 4;
574 SIVAL(p,0,0); p += 4;
579 case SMB_FIND_FILE_NAMES_INFO:
580 len = 12+strlen(fname);
581 len = (len + 3) & ~3;
582 SIVAL(p,0,len); p += 4;
583 SIVAL(p,0,reskey); p += 4;
584 SIVAL(p,0,strlen(fname)); p += 4;
594 if (PTR_DIFF(p,pdata) > space_remaining) {
595 /* Move the dirptr back to prev_dirpos */
596 SeekDir(conn->dirptr, prev_dirpos);
597 *out_of_space = True;
598 DEBUG(9,("get_lanman2_dir_entry: out of space\n"));
599 return False; /* Not finished - just out of space */
602 /* Setup the last_filename pointer, as an offset from base_data */
603 *last_name_off = PTR_DIFF(nameptr,base_data);
604 /* Advance the data pointer to the next slot */
611 /****************************************************************************
612 Reply to a TRANS2_FINDFIRST.
613 ****************************************************************************/
615 static int call_trans2findfirst(connection_struct *conn,
616 char *inbuf, char *outbuf, int bufsize,
617 char **pparams, char **ppdata)
619 /* We must be careful here that we don't return more than the
620 allowed number of data bytes. If this means returning fewer than
621 maxentries then so be it. We assume that the redirector has
622 enough room for the fixed number of parameter bytes it has
624 uint32 max_data_bytes = SVAL(inbuf, smb_mdrcnt);
625 char *params = *pparams;
626 char *pdata = *ppdata;
627 int dirtype = SVAL(params,0);
628 int maxentries = SVAL(params,2);
629 BOOL close_after_first = BITSETW(params+4,0);
630 BOOL close_if_end = BITSETW(params+4,1);
631 BOOL requires_resume_key = BITSETW(params+4,2);
632 int info_level = SVAL(params,6);
640 BOOL finished = False;
641 BOOL dont_descend = False;
642 BOOL out_of_space = False;
644 BOOL bad_path = False;
646 *directory = *mask = 0;
648 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",
649 dirtype, maxentries, close_after_first, close_if_end, requires_resume_key,
650 info_level, max_data_bytes));
658 case SMB_FIND_FILE_DIRECTORY_INFO:
659 case SMB_FIND_FILE_FULL_DIRECTORY_INFO:
660 case SMB_FIND_FILE_NAMES_INFO:
661 case SMB_FIND_FILE_BOTH_DIRECTORY_INFO:
664 return(ERROR(ERRDOS,ERRunknownlevel));
667 pstrcpy(directory, params + 12); /* Complete directory path with
668 wildcard mask appended */
670 RESOLVE_FINDFIRST_DFSPATH(directory, conn, inbuf, outbuf);
672 DEBUG(5,("path=%s\n",directory));
674 unix_convert(directory,conn,0,&bad_path,NULL);
675 if(!check_name(directory,conn)) {
676 if((errno == ENOENT) && bad_path)
678 unix_ERR_class = ERRDOS;
679 unix_ERR_code = ERRbadpath;
683 /* Ugly - NT specific hack - maybe not needed ? (JRA) */
684 if((errno == ENOTDIR) && (Protocol >= PROTOCOL_NT1) &&
685 (get_remote_arch() == RA_WINNT))
687 unix_ERR_class = ERRDOS;
688 unix_ERR_code = ERRbaddirectory;
692 return(UNIXERROR(ERRDOS,ERRbadpath));
695 p = strrchr(directory,'/');
697 pstrcpy(mask,directory);
698 pstrcpy(directory,"./");
704 DEBUG(5,("dir=%s, mask = %s\n",directory, mask));
706 pdata = *ppdata = Realloc(*ppdata, max_data_bytes + 1024);
708 return(ERROR(ERRDOS,ERRnomem));
709 memset((char *)pdata,'\0',max_data_bytes + 1024);
711 /* Realloc the params space */
712 params = *pparams = Realloc(*pparams, 10);
714 return(ERROR(ERRDOS,ERRnomem));
716 dptr_num = dptr_create(conn,directory, False, True ,SVAL(inbuf,smb_pid));
718 return(UNIXERROR(ERRDOS,ERRbadfile));
720 /* Save the wildcard match and attribs we are using on this directory -
721 needed as lanman2 assumes these are being saved between calls */
723 if(!(wcard = strdup(mask))) {
724 dptr_close(&dptr_num);
725 return(ERROR(ERRDOS,ERRnomem));
728 dptr_set_wcard(dptr_num, wcard);
729 dptr_set_attr(dptr_num, dirtype);
731 DEBUG(4,("dptr_num is %d, wcard = %s, attr = %d\n",dptr_num, wcard, dirtype));
733 /* We don't need to check for VOL here as this is returned by
734 a different TRANS2 call. */
736 DEBUG(8,("dirpath=<%s> dontdescend=<%s>\n",
737 conn->dirpath,lp_dontdescend(SNUM(conn))));
738 if (in_list(conn->dirpath,lp_dontdescend(SNUM(conn)),case_sensitive))
742 space_remaining = max_data_bytes;
743 out_of_space = False;
745 for (i=0;(i<maxentries) && !finished && !out_of_space;i++)
747 BOOL got_exact_match = False;
749 /* this is a heuristic to avoid seeking the dirptr except when
750 absolutely necessary. It allows for a filename of about 40 chars */
751 if (space_remaining < DIRLEN_GUESS && numentries > 0)
758 finished = !get_lanman2_dir_entry(conn,mask,dirtype,info_level,
759 requires_resume_key,dont_descend,
760 &p,pdata,space_remaining, &out_of_space, &got_exact_match,
764 if (finished && out_of_space)
767 if (!finished && !out_of_space)
771 * As an optimisation if we know we aren't looking
772 * for a wildcard name (ie. the name matches the wildcard exactly)
773 * then we can finish on any (first) match.
774 * This speeds up large directory searches. JRA.
780 space_remaining = max_data_bytes - PTR_DIFF(p,pdata);
783 /* Check if we can close the dirptr */
784 if(close_after_first || (finished && close_if_end))
786 DEBUG(5,("call_trans2findfirst - (2) closing dptr_num %d\n", dptr_num));
787 dptr_close(&dptr_num);
791 * If there are no matching entries we must return ERRDOS/ERRbadfile -
792 * from observation of NT.
797 dptr_close(&dptr_num);
798 return(ERROR(ERRDOS,ERRbadfile));
801 /* At this point pdata points to numentries directory entries. */
803 /* Set up the return parameter block */
804 SSVAL(params,0,dptr_num);
805 SSVAL(params,2,numentries);
806 SSVAL(params,4,finished);
807 SSVAL(params,6,0); /* Never an EA error */
808 SSVAL(params,8,last_name_off);
810 send_trans2_replies( outbuf, bufsize, params, 10, pdata, PTR_DIFF(p,pdata));
812 if ((! *directory) && dptr_path(dptr_num))
813 slprintf(directory,sizeof(directory)-1, "(%s)",dptr_path(dptr_num));
815 DEBUG( 4, ( "%s mask=%s directory=%s dirtype=%d numentries=%d\n",
816 smb_fn_name(CVAL(inbuf,smb_com)),
817 mask, directory, dirtype, numentries ) );
820 * Force a name mangle here to ensure that the
821 * mask as an 8.3 name is top of the mangled cache.
822 * The reasons for this are subtle. Don't remove
823 * this code unless you know what you are doing
824 * (see PR#13758). JRA.
827 if(!is_8_3( mask, False))
828 name_map_mangle(mask, True, True, SNUM(conn));
834 /****************************************************************************
835 reply to a TRANS2_FINDNEXT
836 ****************************************************************************/
837 static int call_trans2findnext(connection_struct *conn,
838 char *inbuf, char *outbuf,
839 int length, int bufsize,
840 char **pparams, char **ppdata)
842 /* We must be careful here that we don't return more than the
843 allowed number of data bytes. If this means returning fewer than
844 maxentries then so be it. We assume that the redirector has
845 enough room for the fixed number of parameter bytes it has
847 int max_data_bytes = SVAL(inbuf, smb_mdrcnt);
848 char *params = *pparams;
849 char *pdata = *ppdata;
850 int dptr_num = SVAL(params,0);
851 int maxentries = SVAL(params,2);
852 uint16 info_level = SVAL(params,4);
853 uint32 resume_key = IVAL(params,6);
854 BOOL close_after_request = BITSETW(params+10,0);
855 BOOL close_if_end = BITSETW(params+10,1);
856 BOOL requires_resume_key = BITSETW(params+10,2);
857 BOOL continue_bit = BITSETW(params+10,3);
864 int i, last_name_off=0;
865 BOOL finished = False;
866 BOOL dont_descend = False;
867 BOOL out_of_space = False;
870 *mask = *directory = *resume_name = 0;
872 pstrcpy( resume_name, params+12);
874 DEBUG(3,("call_trans2findnext: dirhandle = %d, max_data_bytes = %d, maxentries = %d, \
875 close_after_request=%d, close_if_end = %d requires_resume_key = %d \
876 resume_key = %d resume name = %s continue=%d level = %d\n",
877 dptr_num, max_data_bytes, maxentries, close_after_request, close_if_end,
878 requires_resume_key, resume_key, resume_name, continue_bit, info_level));
886 case SMB_FIND_FILE_DIRECTORY_INFO:
887 case SMB_FIND_FILE_FULL_DIRECTORY_INFO:
888 case SMB_FIND_FILE_NAMES_INFO:
889 case SMB_FIND_FILE_BOTH_DIRECTORY_INFO:
892 return(ERROR(ERRDOS,ERRunknownlevel));
895 pdata = *ppdata = Realloc( *ppdata, max_data_bytes + 1024);
897 return(ERROR(ERRDOS,ERRnomem));
898 memset((char *)pdata,'\0',max_data_bytes + 1024);
900 /* Realloc the params space */
901 params = *pparams = Realloc(*pparams, 6*SIZEOFWORD);
903 return(ERROR(ERRDOS,ERRnomem));
905 /* Check that the dptr is valid */
906 if(!(conn->dirptr = dptr_fetch_lanman2(dptr_num)))
907 return(ERROR(ERRDOS,ERRnofiles));
909 string_set(&conn->dirpath,dptr_path(dptr_num));
911 /* Get the wildcard mask from the dptr */
912 if((p = dptr_wcard(dptr_num))== NULL) {
913 DEBUG(2,("dptr_num %d has no wildcard\n", dptr_num));
914 return (ERROR(ERRDOS,ERRnofiles));
917 pstrcpy(directory,conn->dirpath);
919 /* Get the attr mask from the dptr */
920 dirtype = dptr_attr(dptr_num);
922 DEBUG(3,("dptr_num is %d, mask = %s, attr = %x, dirptr=(0x%lX,%d)\n",
923 dptr_num, mask, dirtype,
925 TellDir(conn->dirptr)));
927 /* We don't need to check for VOL here as this is returned by
928 a different TRANS2 call. */
930 DEBUG(8,("dirpath=<%s> dontdescend=<%s>\n",conn->dirpath,lp_dontdescend(SNUM(conn))));
931 if (in_list(conn->dirpath,lp_dontdescend(SNUM(conn)),case_sensitive))
935 space_remaining = max_data_bytes;
936 out_of_space = False;
939 * Seek to the correct position. We no longer use the resume key but
940 * depend on the last file name instead.
942 if(requires_resume_key && *resume_name && !continue_bit)
945 * Fix for NT redirector problem triggered by resume key indexes
946 * changing between directory scans. We now return a resume key of 0
947 * and instead look for the filename to continue from (also given
948 * to us by NT/95/smbfs/smbclient). If no other scans have been done between the
949 * findfirst/findnext (as is usual) then the directory pointer
950 * should already be at the correct place. Check this by scanning
951 * backwards looking for an exact (ie. case sensitive) filename match.
952 * If we get to the beginning of the directory and haven't found it then scan
953 * forwards again looking for a match. JRA.
956 int current_pos, start_pos;
958 void *dirptr = conn->dirptr;
959 start_pos = TellDir(dirptr);
960 for(current_pos = start_pos; current_pos >= 0; current_pos--)
962 DEBUG(7,("call_trans2findnext: seeking to pos %d\n", current_pos));
964 SeekDir(dirptr, current_pos);
965 dname = ReadDirName(dirptr);
968 * Remember, name_map_mangle is called by
969 * get_lanman2_dir_entry(), so the resume name
970 * could be mangled. Ensure we do the same
975 name_map_mangle( dname, False, True, SNUM(conn));
977 if(dname && strcsequal( resume_name, dname))
979 SeekDir(dirptr, current_pos+1);
980 DEBUG(7,("call_trans2findnext: got match at pos %d\n", current_pos+1 ));
986 * Scan forward from start if not found going backwards.
991 DEBUG(7,("call_trans2findnext: notfound: seeking to pos %d\n", start_pos));
992 SeekDir(dirptr, start_pos);
993 for(current_pos = start_pos; (dname = ReadDirName(dirptr)) != NULL; SeekDir(dirptr,++current_pos))
996 * Remember, name_map_mangle is called by
997 * get_lanman2_dir_entry(), so the resume name
998 * could be mangled. Ensure we do the same
1003 name_map_mangle( dname, False, True, SNUM(conn));
1005 if(dname && strcsequal( resume_name, dname))
1007 SeekDir(dirptr, current_pos+1);
1008 DEBUG(7,("call_trans2findnext: got match at pos %d\n", current_pos+1 ));
1012 } /* end if current_pos */
1013 } /* end if requires_resume_key && !continue_bit */
1015 for (i=0;(i<(int)maxentries) && !finished && !out_of_space ;i++)
1017 BOOL got_exact_match = False;
1019 /* this is a heuristic to avoid seeking the dirptr except when
1020 absolutely necessary. It allows for a filename of about 40 chars */
1021 if (space_remaining < DIRLEN_GUESS && numentries > 0)
1023 out_of_space = True;
1028 finished = !get_lanman2_dir_entry(conn,mask,dirtype,info_level,
1029 requires_resume_key,dont_descend,
1030 &p,pdata,space_remaining, &out_of_space, &got_exact_match,
1034 if (finished && out_of_space)
1037 if (!finished && !out_of_space)
1041 * As an optimisation if we know we aren't looking
1042 * for a wildcard name (ie. the name matches the wildcard exactly)
1043 * then we can finish on any (first) match.
1044 * This speeds up large directory searches. JRA.
1050 space_remaining = max_data_bytes - PTR_DIFF(p,pdata);
1053 /* Check if we can close the dirptr */
1054 if(close_after_request || (finished && close_if_end))
1056 DEBUG(5,("call_trans2findnext: closing dptr_num = %d\n", dptr_num));
1057 dptr_close(&dptr_num); /* This frees up the saved mask */
1061 /* Set up the return parameter block */
1062 SSVAL(params,0,numentries);
1063 SSVAL(params,2,finished);
1064 SSVAL(params,4,0); /* Never an EA error */
1065 SSVAL(params,6,last_name_off);
1067 send_trans2_replies( outbuf, bufsize, params, 8, pdata, PTR_DIFF(p,pdata));
1069 if ((! *directory) && dptr_path(dptr_num))
1070 slprintf(directory,sizeof(directory)-1, "(%s)",dptr_path(dptr_num));
1072 DEBUG( 3, ( "%s mask=%s directory=%s dirtype=%d numentries=%d\n",
1073 smb_fn_name(CVAL(inbuf,smb_com)),
1074 mask, directory, dirtype, numentries ) );
1079 /****************************************************************************
1080 reply to a TRANS2_QFSINFO (query filesystem info)
1081 ****************************************************************************/
1083 static int call_trans2qfsinfo(connection_struct *conn,
1084 char *inbuf, char *outbuf,
1085 int length, int bufsize,
1086 char **pparams, char **ppdata)
1088 int max_data_bytes = SVAL(inbuf, smb_mdrcnt);
1089 char *pdata = *ppdata;
1090 char *params = *pparams;
1091 uint16 info_level = SVAL(params,0);
1094 char *vname = volume_label(SNUM(conn));
1095 int snum = SNUM(conn);
1096 char *fstype = lp_fstype(SNUM(conn));
1098 DEBUG(3,("call_trans2qfsinfo: level = %d\n", info_level));
1100 if(conn->vfs_ops.stat(".",&st)!=0) {
1101 DEBUG(2,("call_trans2qfsinfo: stat of . failed (%s)\n", strerror(errno)));
1102 return (ERROR(ERRSRV,ERRinvdevice));
1105 pdata = *ppdata = Realloc(*ppdata, max_data_bytes + 1024);
1106 memset((char *)pdata,'\0',max_data_bytes + 1024);
1112 SMB_BIG_UINT dfree,dsize,bsize;
1114 conn->vfs_ops.disk_free(".",False,&bsize,&dfree,&dsize);
1115 SIVAL(pdata,l1_idFileSystem,st.st_dev);
1116 SIVAL(pdata,l1_cSectorUnit,bsize/512);
1117 SIVAL(pdata,l1_cUnit,dsize);
1118 SIVAL(pdata,l1_cUnitAvail,dfree);
1119 SSVAL(pdata,l1_cbSector,512);
1120 DEBUG(5,("call_trans2qfsinfo : bsize=%u, id=%x, cSectorUnit=%u, cUnit=%u, cUnitAvail=%u, cbSector=%d\n",
1121 (unsigned int)bsize, (unsigned int)st.st_dev, ((unsigned int)bsize)/512, (unsigned int)dsize,
1122 (unsigned int)dfree, 512));
1127 /* Return volume name */
1128 int volname_len = MIN(strlen(vname),11);
1129 data_len = l2_vol_szVolLabel + volname_len + 1;
1131 * Add volume serial number - hash of a combination of
1132 * the called hostname and the service name.
1134 SIVAL(pdata,0,str_checksum(lp_servicename(snum)) ^ (str_checksum(local_machine)<<16) );
1135 SCVAL(pdata,l2_vol_cch,volname_len);
1136 StrnCpy(pdata+l2_vol_szVolLabel,vname,volname_len);
1137 DEBUG(5,("call_trans2qfsinfo : time = %x, namelen = %d, name = %s\n",
1138 (unsigned)st.st_ctime, volname_len,
1139 pdata+l2_vol_szVolLabel));
1142 case SMB_QUERY_FS_ATTRIBUTE_INFO:
1145 SIVAL(pdata,0,FILE_CASE_PRESERVED_NAMES|FILE_CASE_SENSITIVE_SEARCH|
1146 FILE_DEVICE_IS_MOUNTED|
1147 (lp_nt_acl_support() ? FILE_PERSISTENT_ACLS : 0)); /* FS ATTRIBUTES */
1148 #if 0 /* Old code. JRA. */
1149 SIVAL(pdata,0,0x4006); /* FS ATTRIBUTES == long filenames supported? */
1150 #endif /* Old code. */
1152 SIVAL(pdata,4,128); /* Max filename component length */
1153 fstype_len = dos_PutUniCode(pdata+12,unix_to_dos(fstype,False),sizeof(pstring), False);
1154 SIVAL(pdata,8,fstype_len);
1155 data_len = 12 + fstype_len;
1156 SSVAL(outbuf,smb_flg2,SVAL(outbuf,smb_flg2)|FLAGS2_UNICODE_STRINGS);
1159 case SMB_QUERY_FS_LABEL_INFO:
1160 data_len = 4 + strlen(vname);
1161 SIVAL(pdata,0,strlen(vname));
1162 pstrcpy(pdata+4,vname);
1164 case SMB_QUERY_FS_VOLUME_INFO:
1167 * Add volume serial number - hash of a combination of
1168 * the called hostname and the service name.
1170 SIVAL(pdata,8,str_checksum(lp_servicename(snum)) ^
1171 (str_checksum(local_machine)<<16));
1173 /* NT4 always serves this up as unicode but expects it to be
1174 * delivered as ascii! (tridge && JRA)
1176 if ((get_remote_arch() != RA_WIN2K) && (global_client_caps & CAP_NT_SMBS)) {
1177 data_len = 18 + strlen(vname);
1178 SIVAL(pdata,12,strlen(vname));
1179 pstrcpy(pdata+18,vname);
1181 data_len = 18 + 2*strlen(vname);
1182 SIVAL(pdata,12,strlen(vname)*2);
1183 dos_PutUniCode(pdata+18,unix_to_dos(vname,False),sizeof(pstring), False);
1184 SSVAL(outbuf,smb_flg2,SVAL(outbuf,smb_flg2)|FLAGS2_UNICODE_STRINGS);
1187 DEBUG(5,("call_trans2qfsinfo : SMB_QUERY_FS_VOLUME_INFO namelen = %d, vol = %s\n",
1188 (int)strlen(vname),vname));
1190 case SMB_QUERY_FS_SIZE_INFO:
1192 SMB_BIG_UINT dfree,dsize,bsize;
1194 conn->vfs_ops.disk_free(".",False,&bsize,&dfree,&dsize);
1195 SBIG_UINT(pdata,0,dsize);
1196 SBIG_UINT(pdata,8,dfree);
1197 SIVAL(pdata,16,bsize/512);
1198 SIVAL(pdata,20,512);
1201 case SMB_QUERY_FS_DEVICE_INFO:
1203 SIVAL(pdata,0,0); /* dev type */
1204 SIVAL(pdata,4,0); /* characteristics */
1206 case SMB_MAC_QUERY_FS_INFO:
1208 * Thursby MAC extension... ONLY on NTFS filesystems
1209 * once we do streams then we don't need this
1211 if (strequal(lp_fstype(SNUM(conn)),"NTFS")) {
1213 SIVAL(pdata,84,0x100); /* Don't support mac... */
1218 return(ERROR(ERRDOS,ERRunknownlevel));
1222 send_trans2_replies( outbuf, bufsize, params, 0, pdata, data_len);
1224 DEBUG( 4, ( "%s info_level = %d\n",
1225 smb_fn_name(CVAL(inbuf,smb_com)), info_level) );
1230 /****************************************************************************
1231 reply to a TRANS2_SETFSINFO (set filesystem info)
1232 ****************************************************************************/
1233 static int call_trans2setfsinfo(connection_struct *conn,
1234 char *inbuf, char *outbuf, int length,
1236 char **pparams, char **ppdata)
1238 /* Just say yes we did it - there is nothing that
1239 can be set here so it doesn't matter. */
1241 DEBUG(3,("call_trans2setfsinfo\n"));
1243 if (!CAN_WRITE(conn))
1244 return(ERROR(ERRSRV,ERRaccess));
1246 outsize = set_message(outbuf,10,0,True);
1251 /****************************************************************************
1252 Reply to a TRANS2_QFILEPATHINFO or TRANSACT2_QFILEINFO (query file info by
1253 file name or file id).
1254 ****************************************************************************/
1256 static int call_trans2qfilepathinfo(connection_struct *conn,
1257 char *inbuf, char *outbuf, int length,
1259 char **pparams,char **ppdata,
1262 int max_data_bytes = SVAL(inbuf, smb_mdrcnt);
1263 char *params = *pparams;
1264 char *pdata = *ppdata;
1265 uint16 tran_call = SVAL(inbuf, smb_setup0);
1269 unsigned int data_size;
1270 SMB_STRUCT_STAT sbuf;
1276 BOOL bad_path = False;
1277 BOOL delete_pending = False;
1279 if (tran_call == TRANSACT2_QFILEINFO) {
1280 files_struct *fsp = file_fsp(params,0);
1281 info_level = SVAL(params,2);
1283 DEBUG(3,("call_trans2qfilepathinfo: TRANSACT2_QFILEINFO: level = %d\n", info_level));
1285 if(fsp && (fsp->is_directory || fsp->stat_open)) {
1287 * This is actually a QFILEINFO on a directory
1288 * handle (returned from an NT SMB). NT5.0 seems
1289 * to do this call. JRA.
1291 fname = fsp->fsp_name;
1292 unix_convert(fname,conn,0,&bad_path,&sbuf);
1293 if (!check_name(fname,conn) ||
1294 (!VALID_STAT(sbuf) && conn->vfs_ops.stat(dos_to_unix(fname,False),&sbuf))) {
1295 DEBUG(3,("fileinfo of %s failed (%s)\n",fname,strerror(errno)));
1296 if((errno == ENOENT) && bad_path)
1298 unix_ERR_class = ERRDOS;
1299 unix_ERR_code = ERRbadpath;
1301 return(UNIXERROR(ERRDOS,ERRbadpath));
1304 delete_pending = fsp->directory_delete_on_close;
1308 * Original code - this is an open file.
1310 CHECK_FSP(fsp,conn);
1313 fname = fsp->fsp_name;
1314 if (fsp->conn->vfs_ops.fstat(fsp->fd,&sbuf) != 0) {
1315 DEBUG(3,("fstat of fnum %d failed (%s)\n",fsp->fnum, strerror(errno)));
1316 return(UNIXERROR(ERRDOS,ERRbadfid));
1318 if((pos = fsp->conn->vfs_ops.lseek(fsp->fd,0,SEEK_CUR)) == -1)
1319 return(UNIXERROR(ERRDOS,ERRnoaccess));
1321 delete_pending = fsp->delete_on_close;
1325 info_level = SVAL(params,0);
1327 DEBUG(3,("call_trans2qfilepathinfo: TRANSACT2_QPATHINFO: level = %d\n", info_level));
1330 pstrcpy(fname,¶ms[6]);
1332 RESOLVE_DFSPATH(fname, conn, inbuf, outbuf);
1334 unix_convert(fname,conn,0,&bad_path,&sbuf);
1335 if (!check_name(fname,conn) ||
1336 (!VALID_STAT(sbuf) && conn->vfs_ops.stat(dos_to_unix(fname,False),&sbuf))) {
1337 DEBUG(3,("fileinfo of %s failed (%s)\n",fname,strerror(errno)));
1338 if((errno == ENOENT) && bad_path)
1340 unix_ERR_class = ERRDOS;
1341 unix_ERR_code = ERRbadpath;
1343 return(UNIXERROR(ERRDOS,ERRbadpath));
1348 DEBUG(3,("call_trans2qfilepathinfo %s level=%d call=%d total_data=%d\n",
1349 fname,info_level,tran_call,total_data));
1351 p = strrchr(fname,'/');
1357 mode = dos_mode(conn,fname,&sbuf);
1358 size = sbuf.st_size;
1359 if (mode & aDIR) size = 0;
1361 /* from now on we only want the part after the / */
1364 params = *pparams = Realloc(*pparams,2);
1365 memset((char *)params,'\0',2);
1366 data_size = max_data_bytes + 1024;
1367 pdata = *ppdata = Realloc(*ppdata, data_size);
1369 if (total_data > 0 && IVAL(pdata,0) == total_data) {
1370 /* uggh, EAs for OS2 */
1371 DEBUG(4,("Rejecting EA request with total_data=%d\n",total_data));
1372 return(ERROR(ERRDOS,ERROR_EAS_NOT_SUPPORTED));
1375 memset((char *)pdata,'\0',data_size);
1379 case SMB_INFO_STANDARD:
1380 case SMB_INFO_QUERY_EA_SIZE:
1381 data_size = (info_level==1?22:26);
1382 put_dos_date2(pdata,l1_fdateCreation,get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(conn))));
1383 put_dos_date2(pdata,l1_fdateLastAccess,sbuf.st_atime);
1384 put_dos_date2(pdata,l1_fdateLastWrite,sbuf.st_mtime); /* write time */
1385 SIVAL(pdata,l1_cbFile,(uint32)size);
1386 SIVAL(pdata,l1_cbFileAlloc,SMB_ROUNDUP(size,1024));
1387 SSVAL(pdata,l1_attrFile,mode);
1388 SIVAL(pdata,l1_attrFile+2,4); /* this is what OS2 does */
1391 case SMB_INFO_QUERY_EAS_FROM_LIST:
1393 put_dos_date2(pdata,0,get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(conn))));
1394 put_dos_date2(pdata,4,sbuf.st_atime);
1395 put_dos_date2(pdata,8,sbuf.st_mtime);
1396 SIVAL(pdata,12,(uint32)size);
1397 SIVAL(pdata,16,SMB_ROUNDUP(size,1024));
1398 SIVAL(pdata,20,mode);
1401 case SMB_INFO_QUERY_ALL_EAS:
1403 SIVAL(pdata,0,data_size);
1407 return(ERROR(ERRDOS,ERRbadfunc)); /* os/2 needs this */
1409 case SMB_QUERY_FILE_BASIC_INFO:
1410 data_size = 36; /* w95 returns 40 bytes not 36 - why ?. */
1411 put_long_date(pdata,get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(conn))));
1412 put_long_date(pdata+8,sbuf.st_atime);
1413 put_long_date(pdata+16,sbuf.st_mtime); /* write time */
1414 put_long_date(pdata+24,sbuf.st_mtime); /* change time */
1415 SIVAL(pdata,32,mode);
1417 DEBUG(5,("SMB_QFBI - "));
1419 time_t create_time = get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(conn)));
1420 DEBUG(5,("create: %s ", ctime(&create_time)));
1422 DEBUG(5,("access: %s ", ctime(&sbuf.st_atime)));
1423 DEBUG(5,("write: %s ", ctime(&sbuf.st_mtime)));
1424 DEBUG(5,("change: %s ", ctime(&sbuf.st_mtime)));
1425 DEBUG(5,("mode: %x\n", mode));
1429 case SMB_QUERY_FILE_STANDARD_INFO:
1431 SOFF_T(pdata,0,size);
1432 SOFF_T(pdata,8,size);
1433 SIVAL(pdata,16,sbuf.st_nlink);
1435 CVAL(pdata,21) = (mode&aDIR)?1:0;
1438 case SMB_QUERY_FILE_EA_INFO:
1442 /* Get the 8.3 name - used if NT SMB was negotiated. */
1443 case SMB_QUERY_FILE_ALT_NAME_INFO:
1446 pstrcpy(short_name,p);
1447 /* Mangle if not already 8.3 */
1448 if(!is_8_3(short_name, True))
1450 if(!name_map_mangle(short_name,True,True,SNUM(conn)))
1453 strupper(short_name);
1454 l = strlen(short_name);
1455 dos_PutUniCode(pdata + 4, unix_to_dos(short_name,False),sizeof(pstring), False);
1456 data_size = 4 + (2*l);
1461 case SMB_QUERY_FILE_NAME_INFO:
1463 * The first part of this code is essential
1464 * to get security descriptors to work on mapped
1465 * drives. Don't ask how I discovered this unless
1466 * you like hearing about me suffering.... :-). JRA.
1468 if(strequal(".", fname) && (global_client_caps & CAP_UNICODE)) {
1470 SSVAL(outbuf,smb_flg2,SVAL(outbuf,smb_flg2)|FLAGS2_UNICODE_STRINGS);
1471 dos_PutUniCode(pdata + 4, unix_to_dos("\\",False),sizeof(pstring), False);
1473 pstrcpy(pdata+4,fname);
1479 case SMB_QUERY_FILE_ALLOCATION_INFO:
1480 case SMB_QUERY_FILE_END_OF_FILEINFO:
1482 SOFF_T(pdata,0,size);
1485 case SMB_QUERY_FILE_ALL_INFO:
1486 put_long_date(pdata,get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(conn))));
1487 put_long_date(pdata+8,sbuf.st_atime);
1488 put_long_date(pdata+16,sbuf.st_mtime); /* write time */
1489 put_long_date(pdata+24,sbuf.st_mtime); /* change time */
1490 SIVAL(pdata,32,mode);
1492 SOFF_T(pdata,0,size);
1493 SOFF_T(pdata,8,size);
1494 SIVAL(pdata,16,sbuf.st_nlink);
1495 CVAL(pdata,20) = delete_pending;
1496 CVAL(pdata,21) = (mode&aDIR)?1:0;
1498 SINO_T(pdata,0,(SMB_INO_T)sbuf.st_ino);
1499 pdata += 8; /* index number */
1500 pdata += 4; /* EA info */
1502 SIVAL(pdata,0,0xA9);
1504 SIVAL(pdata,0,0xd01BF);
1506 SOFF_T(pdata,0,pos); /* current offset */
1508 SIVAL(pdata,0,mode); /* is this the right sort of mode info? */
1510 pdata += 4; /* alignment */
1512 pstrcpy(pdata+4,fname);
1514 data_size = PTR_DIFF(pdata,(*ppdata));
1518 /* NT4 server just returns "invalid query" to this - if we try to answer
1519 it then NTws gets a BSOD! (tridge) */
1520 case SMB_QUERY_FILE_STREAM_INFO:
1523 SIVAL(pdata,4,size);
1524 SIVAL(pdata,12,size);
1526 pstrcpy(pdata+24,fname);
1531 return(ERROR(ERRDOS,ERRunknownlevel));
1534 send_trans2_replies( outbuf, bufsize, params, 2, *ppdata, data_size);
1539 /****************************************************************************
1540 reply to a TRANS2_SETFILEINFO (set file info by fileid)
1541 ****************************************************************************/
1542 static int call_trans2setfilepathinfo(connection_struct *conn,
1543 char *inbuf, char *outbuf, int length,
1544 int bufsize, char **pparams,
1545 char **ppdata, int total_data)
1547 char *params = *pparams;
1548 char *pdata = *ppdata;
1549 uint16 tran_call = SVAL(inbuf, smb_setup0);
1558 BOOL bad_path = False;
1559 files_struct *fsp = NULL;
1561 if (!CAN_WRITE(conn))
1562 return(ERROR(ERRSRV,ERRaccess));
1564 if (tran_call == TRANSACT2_SETFILEINFO) {
1565 fsp = file_fsp(params,0);
1566 info_level = SVAL(params,2);
1568 if(fsp && (fsp->is_directory || fsp->stat_open)) {
1570 * This is actually a SETFILEINFO on a directory
1571 * handle (returned from an NT SMB). NT5.0 seems
1572 * to do this call. JRA.
1574 fname = fsp->fsp_name;
1575 unix_convert(fname,conn,0,&bad_path,&st);
1576 if (!check_name(fname,conn) ||
1577 (!VALID_STAT(st) && conn->vfs_ops.stat(dos_to_unix(fname,False),&st))) {
1578 DEBUG(3,("fileinfo of %s failed (%s)\n",fname,strerror(errno)));
1579 if((errno == ENOENT) && bad_path)
1581 unix_ERR_class = ERRDOS;
1582 unix_ERR_code = ERRbadpath;
1584 return(UNIXERROR(ERRDOS,ERRbadpath));
1588 * Original code - this is an open file.
1590 CHECK_FSP(fsp,conn);
1593 fname = fsp->fsp_name;
1596 if (fsp->conn->vfs_ops.fstat(fd,&st) != 0) {
1597 DEBUG(3,("fstat of fnum %d failed (%s)\n",fsp->fnum, strerror(errno)));
1598 return(UNIXERROR(ERRDOS,ERRbadfid));
1603 info_level = SVAL(params,0);
1605 pstrcpy(fname,¶ms[6]);
1606 unix_convert(fname,conn,0,&bad_path,&st);
1607 if(!check_name(fname, conn))
1609 if((errno == ENOENT) && bad_path)
1611 unix_ERR_class = ERRDOS;
1612 unix_ERR_code = ERRbadpath;
1614 return(UNIXERROR(ERRDOS,ERRbadpath));
1617 if(!VALID_STAT(st) && conn->vfs_ops.stat(dos_to_unix(fname,False),&st)!=0) {
1618 DEBUG(3,("stat of %s failed (%s)\n", fname, strerror(errno)));
1619 if((errno == ENOENT) && bad_path)
1621 unix_ERR_class = ERRDOS;
1622 unix_ERR_code = ERRbadpath;
1624 return(UNIXERROR(ERRDOS,ERRbadpath));
1628 DEBUG(3,("call_trans2setfilepathinfo(%d) %s info_level=%d totdata=%d\n",
1629 tran_call,fname,info_level,total_data));
1631 /* Realloc the parameter and data sizes */
1632 params = *pparams = Realloc(*pparams,2);
1634 return(ERROR(ERRDOS,ERRnomem));
1639 tvs.modtime = st.st_mtime;
1640 tvs.actime = st.st_atime;
1641 mode = dos_mode(conn,fname,&st);
1643 if (total_data > 0 && IVAL(pdata,0) == total_data) {
1644 /* uggh, EAs for OS2 */
1645 DEBUG(4,("Rejecting EA request with total_data=%d\n",total_data));
1646 return(ERROR(ERRDOS,ERROR_EAS_NOT_SUPPORTED));
1651 case SMB_INFO_STANDARD:
1652 case SMB_INFO_QUERY_EA_SIZE:
1655 tvs.actime = make_unix_date2(pdata+l1_fdateLastAccess);
1658 tvs.modtime = make_unix_date2(pdata+l1_fdateLastWrite);
1660 mode = SVAL(pdata,l1_attrFile);
1661 size = IVAL(pdata,l1_cbFile);
1665 /* XXXX um, i don't think this is right.
1666 it's also not in the cifs6.txt spec.
1668 case SMB_INFO_QUERY_EAS_FROM_LIST:
1669 tvs.actime = make_unix_date2(pdata+8);
1670 tvs.modtime = make_unix_date2(pdata+12);
1671 size = IVAL(pdata,16);
1672 mode = IVAL(pdata,24);
1675 /* XXXX nor this. not in cifs6.txt, either. */
1676 case SMB_INFO_QUERY_ALL_EAS:
1677 tvs.actime = make_unix_date2(pdata+8);
1678 tvs.modtime = make_unix_date2(pdata+12);
1679 size = IVAL(pdata,16);
1680 mode = IVAL(pdata,24);
1683 case SMB_SET_FILE_BASIC_INFO:
1685 /* Patch to do this correctly from Paul Eggert <eggert@twinsun.com>. */
1687 time_t changed_time;
1689 /* Ignore create time at offset pdata. */
1692 tvs.actime = interpret_long_date(pdata+8);
1694 write_time = interpret_long_date(pdata+16);
1695 changed_time = interpret_long_date(pdata+24);
1697 tvs.modtime = MIN(write_time, changed_time);
1699 /* Prefer a defined time to an undefined one. */
1700 if (tvs.modtime == (time_t)0 || tvs.modtime == (time_t)-1)
1701 tvs.modtime = (write_time == (time_t)0 || write_time == (time_t)-1
1705 #if 0 /* Needs more testing... */
1706 /* Test from Luke to prevent Win95 from
1707 setting incorrect values here.
1709 if (tvs.actime < tvs.modtime)
1710 return(ERROR(ERRDOS,ERRnoaccess));
1711 #endif /* Needs more testing... */
1714 mode = IVAL(pdata,32);
1719 * NT seems to use this call with a size of zero
1720 * to mean truncate the file. JRA.
1723 case SMB_SET_FILE_ALLOCATION_INFO:
1725 SMB_OFF_T newsize = IVAL(pdata,0);
1726 #ifdef LARGE_SMB_OFF_T
1727 newsize |= (((SMB_OFF_T)IVAL(pdata,4)) << 32);
1728 #else /* LARGE_SMB_OFF_T */
1729 if (IVAL(pdata,4) != 0) /* more than 32 bits? */
1730 return(ERROR(ERRDOS,ERRunknownlevel));
1731 #endif /* LARGE_SMB_OFF_T */
1732 DEBUG(10,("call_trans2setfilepathinfo: Set file allocation info for file %s to %.0f\n", fname, (double)newsize ));
1738 case SMB_SET_FILE_END_OF_FILE_INFO:
1740 size = IVAL(pdata,0);
1741 #ifdef LARGE_SMB_OFF_T
1742 size |= (((SMB_OFF_T)IVAL(pdata,4)) << 32);
1743 #else /* LARGE_SMB_OFF_T */
1744 if (IVAL(pdata,4) != 0) /* more than 32 bits? */
1745 return(ERROR(ERRDOS,ERRunknownlevel));
1746 #endif /* LARGE_SMB_OFF_T */
1747 DEBUG(10,("call_trans2setfilepathinfo: Set end of file info for file %s to %.0f\n", fname, (double)size ));
1751 case SMB_SET_FILE_DISPOSITION_INFO: /* Set delete on close for open file. */
1753 if ((tran_call == TRANSACT2_SETFILEINFO) && (fsp != NULL))
1755 BOOL delete_on_close = (CVAL(pdata,0) ? True : False);
1757 if(fsp->is_directory)
1759 fsp->directory_delete_on_close = delete_on_close;
1760 DEBUG(10, ("call_trans2setfilepathinfo: %s delete on close flag for fnum = %d, directory %s\n",
1761 delete_on_close ? "Added" : "Removed", fsp->fnum, fsp->fsp_name ));
1764 else if(fsp->stat_open)
1766 DEBUG(10, ("call_trans2setfilepathinfo: %s delete on close flag for fnum = %d, stat open %s\n",
1767 delete_on_close ? "Added" : "Removed", fsp->fnum, fsp->fsp_name ));
1773 * We can only set the delete on close flag if
1774 * the share mode contained ALLOW_SHARE_DELETE
1777 if(!GET_ALLOW_SHARE_DELETE(fsp->share_mode))
1778 return(ERROR(ERRDOS,ERRnoaccess));
1781 * If the flag has been set then
1782 * modify the share mode entry for all files we have open
1783 * on this device and inode to tell other smbds we have
1784 * changed the delete on close flag.
1787 if(delete_on_close && !GET_DELETE_ON_CLOSE_FLAG(fsp->share_mode))
1790 files_struct *iterate_fsp;
1791 SMB_DEV_T dev = fsp->dev;
1792 SMB_INO_T inode = fsp->inode;
1793 int num_share_modes;
1794 share_mode_entry *current_shares = NULL;
1796 if (lock_share_entry_fsp(fsp) == False)
1797 return(ERROR(ERRDOS,ERRnoaccess));
1800 * Before we allow this we need to ensure that all current opens
1801 * on the file have the GET_ALLOW_SHARE_DELETE flag set. If they
1802 * do not then we deny this (as we are essentially deleting the
1803 * file at this point.
1806 num_share_modes = get_share_modes(conn, dev, inode, ¤t_shares);
1807 for(i = 0; i < num_share_modes; i++)
1809 if(!GET_ALLOW_SHARE_DELETE(current_shares[i].share_mode))
1811 DEBUG(5,("call_trans2setfilepathinfo: refusing to set delete on close flag for fnum = %d, \
1812 file %s as a share exists that was not opened with FILE_DELETE access.\n",
1813 fsp->fnum, fsp->fsp_name ));
1818 unlock_share_entry_fsp(fsp);
1821 * current_shares was malloced by get_share_modes - free it here.
1824 free((char *)current_shares);
1827 * Even though share violation would be more appropriate here,
1828 * return ERRnoaccess as that's what NT does.
1831 return(ERROR(ERRDOS,ERRnoaccess));
1836 * current_shares was malloced by get_share_modes - free it here.
1839 free((char *)current_shares);
1841 DEBUG(10,("call_trans2setfilepathinfo: %s delete on close flag for fnum = %d, file %s\n",
1842 delete_on_close ? "Adding" : "Removing", fsp->fnum, fsp->fsp_name ));
1845 * Go through all files we have open on the same device and
1846 * inode (hanging off the same hash bucket) and set the DELETE_ON_CLOSE_FLAG.
1847 * Other smbd's that have this file open will have to fend for themselves. We
1848 * take care of this (rare) case in close_file(). See the comment there.
1851 for(iterate_fsp = file_find_di_first(dev, inode); iterate_fsp;
1852 iterate_fsp = file_find_di_next(iterate_fsp))
1854 int new_share_mode = (delete_on_close ?
1855 (iterate_fsp->share_mode | DELETE_ON_CLOSE_FLAG) :
1856 (iterate_fsp->share_mode & ~DELETE_ON_CLOSE_FLAG) );
1858 DEBUG(10,("call_trans2setfilepathinfo: Changing share mode for fnum %d, file %s \
1859 dev = %x, inode = %.0f from %x to %x\n",
1860 iterate_fsp->fnum, iterate_fsp->fsp_name, (unsigned int)dev,
1861 (double)inode, iterate_fsp->share_mode, new_share_mode ));
1863 if(modify_share_mode(iterate_fsp, new_share_mode, iterate_fsp->oplock_type)==False)
1864 DEBUG(0,("call_trans2setfilepathinfo: failed to change delete on close for fnum %d, \
1865 dev = %x, inode = %.0f\n", iterate_fsp->fnum, (unsigned int)dev, (double)inode));
1869 * Set the delete on close flag in the reference
1870 * counted struct. Delete when the last reference
1873 fsp->delete_on_close = delete_on_close;
1875 unlock_share_entry_fsp(fsp);
1877 DEBUG(10, ("call_trans2setfilepathinfo: %s delete on close flag for fnum = %d, file %s\n",
1878 delete_on_close ? "Added" : "Removed", fsp->fnum, fsp->fsp_name ));
1880 } /* end if(delete_on_close && !GET_DELETE_ON_CLOSE_FLAG(fsp->share_mode)) */
1881 } /* end if is_directory. */
1883 return(ERROR(ERRDOS,ERRunknownlevel));
1889 return(ERROR(ERRDOS,ERRunknownlevel));
1893 /* get some defaults (no modifications) if any info is zero or -1. */
1894 if (tvs.actime == (time_t)0 || tvs.actime == (time_t)-1)
1895 tvs.actime = st.st_atime;
1897 if (tvs.modtime == (time_t)0 || tvs.modtime == (time_t)-1)
1898 tvs.modtime = st.st_mtime;
1900 DEBUG(6,("actime: %s " , ctime(&tvs.actime)));
1901 DEBUG(6,("modtime: %s ", ctime(&tvs.modtime)));
1902 DEBUG(6,("size: %.0f ", (double)size));
1903 DEBUG(6,("mode: %x\n" , mode));
1905 if(!((info_level == SMB_SET_FILE_END_OF_FILE_INFO) ||
1906 (info_level == SMB_SET_FILE_ALLOCATION_INFO))) {
1908 * Only do this test if we are not explicitly
1909 * changing the size of a file.
1915 /* Try and set the times, size and mode of this file -
1916 if they are different from the current values
1918 if (st.st_mtime != tvs.modtime || st.st_atime != tvs.actime) {
1921 * This was a setfileinfo on an open file.
1922 * NT does this a lot. It's actually pointless
1923 * setting the time here, as it will be overwritten
1924 * on the next write, so we save the request
1925 * away and will set it on file code. JRA.
1928 if (tvs.modtime != (time_t)0 && tvs.modtime != (time_t)-1) {
1929 DEBUG(10,("call_trans2setfilepathinfo: setting pending modtime to %s\n",
1930 ctime(&tvs.modtime) ));
1931 fsp->pending_modtime = tvs.modtime;
1936 DEBUG(10,("call_trans2setfilepathinfo: setting utimes to modified values.\n"));
1938 if(file_utime(conn, fname, &tvs)!=0)
1939 return(UNIXERROR(ERRDOS,ERRnoaccess));
1943 /* check the mode isn't different, before changing it */
1944 if ((mode != 0) && (mode != dos_mode(conn, fname, &st))) {
1946 DEBUG(10,("call_trans2setfilepathinfo: file %s : setting dos mode %x\n",
1949 if(file_chmod(conn, fname, mode, NULL)) {
1950 DEBUG(2,("chmod of %s failed (%s)\n", fname, strerror(errno)));
1951 return(UNIXERROR(ERRDOS,ERRnoaccess));
1955 if(size != st.st_size) {
1957 DEBUG(10,("call_trans2setfilepathinfo: file %s : setting new size to %.0f\n",
1958 fname, (double)size ));
1961 fd = conn->vfs_ops.open(dos_to_unix(fname,False),O_RDWR,0);
1963 return(UNIXERROR(ERRDOS,ERRbadpath));
1964 set_filelen(fd, size); /* tpot vfs */
1965 conn->vfs_ops.close(fd);
1967 set_filelen(fd, size); /* tpot vfs */
1971 set_filelen_write_cache(fsp, size);
1976 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
1981 /****************************************************************************
1982 reply to a TRANS2_MKDIR (make directory with extended attributes).
1983 ****************************************************************************/
1984 static int call_trans2mkdir(connection_struct *conn,
1985 char *inbuf, char *outbuf, int length, int bufsize,
1986 char **pparams, char **ppdata)
1988 char *params = *pparams;
1991 BOOL bad_path = False;
1993 if (!CAN_WRITE(conn))
1994 return(ERROR(ERRSRV,ERRaccess));
1996 pstrcpy(directory, ¶ms[4]);
1998 DEBUG(3,("call_trans2mkdir : name = %s\n", directory));
2000 unix_convert(directory,conn,0,&bad_path,NULL);
2001 if (check_name(directory,conn))
2002 ret = conn->vfs_ops.mkdir(dos_to_unix(directory,False),
2003 unix_mode(conn,aDIR,directory));
2007 DEBUG(5,("call_trans2mkdir error (%s)\n", strerror(errno)));
2008 if((errno == ENOENT) && bad_path)
2010 unix_ERR_class = ERRDOS;
2011 unix_ERR_code = ERRbadpath;
2013 return(UNIXERROR(ERRDOS,ERRnoaccess));
2016 /* Realloc the parameter and data sizes */
2017 params = *pparams = Realloc(*pparams,2);
2019 return(ERROR(ERRDOS,ERRnomem));
2023 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
2028 /****************************************************************************
2029 reply to a TRANS2_FINDNOTIFYFIRST (start monitoring a directory for changes)
2030 We don't actually do this - we just send a null response.
2031 ****************************************************************************/
2032 static int call_trans2findnotifyfirst(connection_struct *conn,
2033 char *inbuf, char *outbuf,
2034 int length, int bufsize,
2035 char **pparams, char **ppdata)
2037 static uint16 fnf_handle = 257;
2038 char *params = *pparams;
2039 uint16 info_level = SVAL(params,4);
2041 DEBUG(3,("call_trans2findnotifyfirst - info_level %d\n", info_level));
2049 return(ERROR(ERRDOS,ERRunknownlevel));
2052 /* Realloc the parameter and data sizes */
2053 params = *pparams = Realloc(*pparams,6);
2055 return(ERROR(ERRDOS,ERRnomem));
2057 SSVAL(params,0,fnf_handle);
2058 SSVAL(params,2,0); /* No changes */
2059 SSVAL(params,4,0); /* No EA errors */
2066 send_trans2_replies(outbuf, bufsize, params, 6, *ppdata, 0);
2071 /****************************************************************************
2072 reply to a TRANS2_FINDNOTIFYNEXT (continue monitoring a directory for
2073 changes). Currently this does nothing.
2074 ****************************************************************************/
2075 static int call_trans2findnotifynext(connection_struct *conn,
2076 char *inbuf, char *outbuf,
2077 int length, int bufsize,
2078 char **pparams, char **ppdata)
2080 char *params = *pparams;
2082 DEBUG(3,("call_trans2findnotifynext\n"));
2084 /* Realloc the parameter and data sizes */
2085 params = *pparams = Realloc(*pparams,4);
2087 return(ERROR(ERRDOS,ERRnomem));
2089 SSVAL(params,0,0); /* No changes */
2090 SSVAL(params,2,0); /* No EA errors */
2092 send_trans2_replies(outbuf, bufsize, params, 4, *ppdata, 0);
2097 /****************************************************************************
2098 reply to a TRANS2_GET_DFS_REFERRAL - Shirish Kalele <kalele@veritas.com>
2099 ****************************************************************************/
2100 static int call_trans2getdfsreferral(connection_struct *conn, char* inbuf,
2101 char* outbuf, int length, int bufsize,
2102 char** pparams, char** ppdata)
2104 char *params = *pparams;
2105 enum remote_arch_types ra_type = get_remote_arch();
2106 BOOL NT_arch = ((ra_type == RA_WINNT) || (ra_type == RA_WIN2K));
2109 int max_referral_level = SVAL(params,0);
2112 DEBUG(10,("call_trans2getdfsreferral\n"));
2114 if(!lp_host_msdfs())
2115 return(ERROR(ERRDOS,ERRbadfunc));
2117 /* if pathname is in UNICODE, convert to DOS */
2118 /* NT always sends in UNICODE, may not set UNICODE flag */
2119 if(NT_arch || (SVAL(inbuf,smb_flg2) & FLAGS2_UNICODE_STRINGS))
2121 unistr_to_dos(pathname, ¶ms[2], sizeof(pathname));
2122 DEBUG(10,("UNICODE referral for %s\n",pathname));
2125 pstrcpy(pathname,¶ms[2]);
2127 if((reply_size = setup_dfs_referral(pathname,max_referral_level,ppdata)) < 0)
2128 return(ERROR(ERRDOS,ERRbadfile));
2130 SSVAL(outbuf,smb_flg2,SVAL(outbuf,smb_flg2) | FLAGS2_UNICODE_STRINGS |
2131 FLAGS2_DFS_PATHNAMES);
2132 send_trans2_replies(outbuf,bufsize,0,0,*ppdata,reply_size);
2138 /****************************************************************************
2139 reply to a SMBfindclose (stop trans2 directory search)
2140 ****************************************************************************/
2141 int reply_findclose(connection_struct *conn,
2142 char *inbuf,char *outbuf,int length,int bufsize)
2145 int dptr_num=SVALS(inbuf,smb_vwv0);
2147 DEBUG(3,("reply_findclose, dptr_num = %d\n", dptr_num));
2149 dptr_close(&dptr_num);
2151 outsize = set_message(outbuf,0,0,True);
2153 DEBUG(3,("SMBfindclose dptr_num = %d\n", dptr_num));
2158 /****************************************************************************
2159 reply to a SMBfindnclose (stop FINDNOTIFYFIRST directory search)
2160 ****************************************************************************/
2161 int reply_findnclose(connection_struct *conn,
2162 char *inbuf,char *outbuf,int length,int bufsize)
2167 dptr_num = SVAL(inbuf,smb_vwv0);
2169 DEBUG(3,("reply_findnclose, dptr_num = %d\n", dptr_num));
2171 /* We never give out valid handles for a
2172 findnotifyfirst - so any dptr_num is ok here.
2175 outsize = set_message(outbuf,0,0,True);
2177 DEBUG(3,("SMB_findnclose dptr_num = %d\n", dptr_num));
2183 /****************************************************************************
2184 reply to a SMBtranss2 - just ignore it!
2185 ****************************************************************************/
2186 int reply_transs2(connection_struct *conn,
2187 char *inbuf,char *outbuf,int length,int bufsize)
2189 DEBUG(4,("Ignoring transs2 of length %d\n",length));
2193 /****************************************************************************
2194 reply to a SMBtrans2
2195 ****************************************************************************/
2196 int reply_trans2(connection_struct *conn,
2197 char *inbuf,char *outbuf,int length,int bufsize)
2200 unsigned int total_params = SVAL(inbuf, smb_tpscnt);
2201 unsigned int total_data =SVAL(inbuf, smb_tdscnt);
2203 unsigned int max_param_reply = SVAL(inbuf, smb_mprcnt);
2204 unsigned int max_data_reply = SVAL(inbuf, smb_mdrcnt);
2205 unsigned int max_setup_fields = SVAL(inbuf, smb_msrcnt);
2206 BOOL close_tid = BITSETW(inbuf+smb_flags,0);
2207 BOOL no_final_response = BITSETW(inbuf+smb_flags,1);
2208 int32 timeout = IVALS(inbuf,smb_timeout);
2210 unsigned int suwcnt = SVAL(inbuf, smb_suwcnt);
2211 unsigned int tran_call = SVAL(inbuf, smb_setup0);
2212 char *params = NULL, *data = NULL;
2213 int num_params, num_params_sofar, num_data, num_data_sofar;
2215 if(global_oplock_break && (tran_call == TRANSACT2_OPEN)) {
2216 /* Queue this open message as we are the process of an
2219 DEBUG(2,("reply_trans2: queueing message trans2open due to being "));
2220 DEBUGADD(2,( "in oplock break state.\n"));
2222 push_oplock_pending_smb_message(inbuf, length);
2226 outsize = set_message(outbuf,0,0,True);
2228 /* All trans2 messages we handle have smb_sucnt == 1 - ensure this
2229 is so as a sanity check */
2231 DEBUG(2,("Invalid smb_sucnt in trans2 call\n"));
2232 return(ERROR(ERRSRV,ERRerror));
2235 /* Allocate the space for the maximum needed parameters and data */
2236 if (total_params > 0)
2237 params = (char *)malloc(total_params);
2239 data = (char *)malloc(total_data);
2241 if ((total_params && !params) || (total_data && !data)) {
2242 DEBUG(2,("Out of memory in reply_trans2\n"));
2247 return(ERROR(ERRDOS,ERRnomem));
2250 /* Copy the param and data bytes sent with this request into
2251 the params buffer */
2252 num_params = num_params_sofar = SVAL(inbuf,smb_pscnt);
2253 num_data = num_data_sofar = SVAL(inbuf, smb_dscnt);
2255 if (num_params > total_params || num_data > total_data)
2256 exit_server("invalid params in reply_trans2");
2259 memcpy( params, smb_base(inbuf) + SVAL(inbuf, smb_psoff), num_params);
2261 memcpy( data, smb_base(inbuf) + SVAL(inbuf, smb_dsoff), num_data);
2263 if(num_data_sofar < total_data || num_params_sofar < total_params) {
2264 /* We need to send an interim response then receive the rest
2265 of the parameter/data bytes */
2266 outsize = set_message(outbuf,0,0,True);
2267 send_smb(smbd_server_fd(),outbuf);
2269 while (num_data_sofar < total_data ||
2270 num_params_sofar < total_params) {
2273 ret = receive_next_smb(inbuf,bufsize,SMB_SECONDARY_WAIT);
2276 (CVAL(inbuf, smb_com) != SMBtranss2)) || !ret) {
2277 outsize = set_message(outbuf,0,0,True);
2279 DEBUG(0,("reply_trans2: Invalid secondary trans2 packet\n"));
2281 DEBUG(0,("reply_trans2: %s in getting secondary trans2 response.\n",
2282 (smb_read_error == READ_ERROR) ? "error" : "timeout" ));
2287 return(ERROR(ERRSRV,ERRerror));
2290 /* Revise total_params and total_data in case
2291 they have changed downwards */
2292 total_params = SVAL(inbuf, smb_tpscnt);
2293 total_data = SVAL(inbuf, smb_tdscnt);
2294 num_params_sofar += (num_params = SVAL(inbuf,smb_spscnt));
2295 num_data_sofar += ( num_data = SVAL(inbuf, smb_sdscnt));
2296 if (num_params_sofar > total_params || num_data_sofar > total_data)
2297 exit_server("data overflow in trans2");
2299 memcpy( ¶ms[ SVAL(inbuf, smb_spsdisp)],
2300 smb_base(inbuf) + SVAL(inbuf, smb_spsoff), num_params);
2301 memcpy( &data[SVAL(inbuf, smb_sdsdisp)],
2302 smb_base(inbuf)+ SVAL(inbuf, smb_sdsoff), num_data);
2306 if (Protocol >= PROTOCOL_NT1) {
2307 uint16 flg2 = SVAL(outbuf,smb_flg2);
2308 SSVAL(outbuf,smb_flg2,flg2 | 0x40); /* IS_LONG_NAME */
2311 /* Now we must call the relevant TRANS2 function */
2313 case TRANSACT2_OPEN:
2314 outsize = call_trans2open(conn,
2315 inbuf, outbuf, bufsize,
2319 case TRANSACT2_FINDFIRST:
2320 outsize = call_trans2findfirst(conn, inbuf, outbuf,
2321 bufsize, ¶ms, &data);
2324 case TRANSACT2_FINDNEXT:
2325 outsize = call_trans2findnext(conn, inbuf, outbuf,
2330 case TRANSACT2_QFSINFO:
2331 outsize = call_trans2qfsinfo(conn, inbuf, outbuf,
2332 length, bufsize, ¶ms,
2336 case TRANSACT2_SETFSINFO:
2337 outsize = call_trans2setfsinfo(conn, inbuf, outbuf,
2342 case TRANSACT2_QPATHINFO:
2343 case TRANSACT2_QFILEINFO:
2344 outsize = call_trans2qfilepathinfo(conn, inbuf, outbuf,
2346 ¶ms, &data, total_data);
2348 case TRANSACT2_SETPATHINFO:
2349 case TRANSACT2_SETFILEINFO:
2350 outsize = call_trans2setfilepathinfo(conn, inbuf, outbuf,
2356 case TRANSACT2_FINDNOTIFYFIRST:
2357 outsize = call_trans2findnotifyfirst(conn, inbuf, outbuf,
2362 case TRANSACT2_FINDNOTIFYNEXT:
2363 outsize = call_trans2findnotifynext(conn, inbuf, outbuf,
2367 case TRANSACT2_MKDIR:
2368 outsize = call_trans2mkdir(conn, inbuf, outbuf, length,
2369 bufsize, ¶ms, &data);
2372 case TRANSACT2_GET_DFS_REFERRAL:
2373 outsize = call_trans2getdfsreferral(conn,inbuf,outbuf,length,
2374 bufsize, ¶ms, &data);
2377 /* Error in request */
2378 DEBUG(2,("Unknown request %d in trans2 call\n", tran_call));
2383 return (ERROR(ERRSRV,ERRerror));
2386 /* As we do not know how many data packets will need to be
2387 returned here the various call_trans2xxxx calls
2388 must send their own. Thus a call_trans2xxx routine only
2389 returns a value other than -1 when it wants to send
2397 return outsize; /* If a correct response was needed the
2398 call_trans2xxx calls have already sent
2399 it. If outsize != -1 then it is returning */