2 Unix SMB/Netbios implementation.
4 SMB transaction2 handling
5 Copyright (C) Jeremy Allison 1994-1998
7 Extensively modified by Andrew Tridgell, 1995
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
27 extern int DEBUGLEVEL;
29 extern BOOL case_sensitive;
31 extern int smb_read_error;
32 extern fstring local_machine;
33 extern int global_oplock_break;
34 extern uint32 global_client_caps;
36 /****************************************************************************
37 Send the required number of replies back.
38 We assume all fields other than the data fields are
39 set correctly for the type of call.
40 HACK ! Always assumes smb_setup field is zero.
41 ****************************************************************************/
42 static int send_trans2_replies(char *outbuf, int bufsize, char *params,
43 int paramsize, char *pdata, int datasize)
45 /* As we are using a protocol > LANMAN1 then the max_send
46 variable must have been set in the sessetupX call.
47 This takes precedence over the max_xmit field in the
48 global struct. These different max_xmit variables should
49 be merged as this is now too confusing */
52 int data_to_send = datasize;
53 int params_to_send = paramsize;
57 int params_sent_thistime, data_sent_thistime, total_sent_thistime;
58 int alignment_offset = 3;
59 int data_alignment_offset = 0;
61 /* Initially set the wcnt area to be 10 - this is true for all
63 set_message(outbuf,10,0,True);
65 /* If there genuinely are no parameters or data to send just send
67 if(params_to_send == 0 && data_to_send == 0)
69 send_smb(Client,outbuf);
73 /* When sending params and data ensure that both are nicely aligned */
74 /* Only do this alignment when there is also data to send - else
75 can cause NT redirector problems. */
76 if (((params_to_send % 4) != 0) && (data_to_send != 0))
77 data_alignment_offset = 4 - (params_to_send % 4);
79 /* Space is bufsize minus Netbios over TCP header minus SMB header */
80 /* The alignment_offset is to align the param bytes on an even byte
81 boundary. NT 4.0 Beta needs this to work correctly. */
82 useable_space = bufsize - ((smb_buf(outbuf)+
83 alignment_offset+data_alignment_offset) -
86 /* useable_space can never be more than max_send minus the
88 useable_space = MIN(useable_space,
89 max_send - (alignment_offset+data_alignment_offset));
92 while (params_to_send || data_to_send)
94 /* Calculate whether we will totally or partially fill this packet */
95 total_sent_thistime = params_to_send + data_to_send +
96 alignment_offset + data_alignment_offset;
97 /* We can never send more than useable_space */
99 * Note that 'useable_space' does not include the alignment offsets,
100 * but we must include the alignment offsets in the calculation of
101 * the length of the data we send over the wire, as the alignment offsets
102 * are sent here. Fix from Marc_Jacobsen@hp.com.
104 total_sent_thistime = MIN(total_sent_thistime, useable_space+
105 alignment_offset + data_alignment_offset);
107 set_message(outbuf, 10, total_sent_thistime, True);
109 /* Set total params and data to be sent */
110 SSVAL(outbuf,smb_tprcnt,paramsize);
111 SSVAL(outbuf,smb_tdrcnt,datasize);
113 /* Calculate how many parameters and data we can fit into
114 this packet. Parameters get precedence */
116 params_sent_thistime = MIN(params_to_send,useable_space);
117 data_sent_thistime = useable_space - params_sent_thistime;
118 data_sent_thistime = MIN(data_sent_thistime,data_to_send);
120 SSVAL(outbuf,smb_prcnt, params_sent_thistime);
121 if(params_sent_thistime == 0)
123 SSVAL(outbuf,smb_proff,((smb_buf(outbuf)+alignment_offset) - smb_base(outbuf)));
124 SSVAL(outbuf,smb_prdisp,0);
128 /* smb_proff is the offset from the start of the SMB header to the
129 parameter bytes, however the first 4 bytes of outbuf are
130 the Netbios over TCP header. Thus use smb_base() to subtract
131 them from the calculation */
132 SSVAL(outbuf,smb_proff,((smb_buf(outbuf)+alignment_offset) - smb_base(outbuf)));
133 /* Absolute displacement of param bytes sent in this packet */
134 SSVAL(outbuf,smb_prdisp,pp - params);
137 SSVAL(outbuf,smb_drcnt, data_sent_thistime);
138 if(data_sent_thistime == 0)
140 SSVAL(outbuf,smb_droff,0);
141 SSVAL(outbuf,smb_drdisp, 0);
145 /* The offset of the data bytes is the offset of the
146 parameter bytes plus the number of parameters being sent this time */
147 SSVAL(outbuf,smb_droff,((smb_buf(outbuf)+alignment_offset) -
148 smb_base(outbuf)) + params_sent_thistime + data_alignment_offset);
149 SSVAL(outbuf,smb_drdisp, pd - pdata);
152 /* Copy the param bytes into the packet */
153 if(params_sent_thistime)
154 memcpy((smb_buf(outbuf)+alignment_offset),pp,params_sent_thistime);
155 /* Copy in the data bytes */
156 if(data_sent_thistime)
157 memcpy(smb_buf(outbuf)+alignment_offset+params_sent_thistime+
158 data_alignment_offset,pd,data_sent_thistime);
160 DEBUG(9,("t2_rep: params_sent_thistime = %d, data_sent_thistime = %d, useable_space = %d\n",
161 params_sent_thistime, data_sent_thistime, useable_space));
162 DEBUG(9,("t2_rep: params_to_send = %d, data_to_send = %d, paramsize = %d, datasize = %d\n",
163 params_to_send, data_to_send, paramsize, datasize));
165 /* Send the packet */
166 send_smb(Client,outbuf);
168 pp += params_sent_thistime;
169 pd += data_sent_thistime;
171 params_to_send -= params_sent_thistime;
172 data_to_send -= data_sent_thistime;
175 if(params_to_send < 0 || data_to_send < 0)
177 DEBUG(0,("send_trans2_replies failed sanity check pts = %d, dts = %d\n!!!",
178 params_to_send, data_to_send));
187 /****************************************************************************
188 reply to a TRANSACT2_OPEN
189 ****************************************************************************/
190 static int call_trans2open(connection_struct *conn, char *inbuf, char *outbuf,
192 char **pparams, char **ppdata)
194 char *params = *pparams;
195 int16 open_mode = SVAL(params, 2);
196 int16 open_attr = SVAL(params,6);
197 BOOL oplock_request = (((SVAL(params,0)|(1<<1))>>1) | ((SVAL(params,0)|(1<<2))>>1));
199 BOOL return_additional_info = BITSETW(params,0);
200 int16 open_sattr = SVAL(params, 4);
201 time_t open_time = make_unix_date3(params+8);
203 int16 open_ofun = SVAL(params,12);
204 int32 open_size = IVAL(params,14);
205 char *pname = ¶ms[28];
206 int16 namelen = strlen(pname)+1;
211 int fmode=0,mtime=0,rmode;
213 SMB_STRUCT_STAT sbuf;
215 BOOL bad_path = False;
218 StrnCpy(fname,pname,namelen);
220 DEBUG(3,("trans2open %s mode=%d attr=%d ofun=%d size=%d\n",
221 fname,open_mode, open_attr, open_ofun, open_size));
223 /* XXXX we need to handle passed times, sattr and flags */
225 unix_convert(fname,conn,0,&bad_path,NULL);
229 return(ERROR(ERRSRV,ERRnofids));
231 if (!check_name(fname,conn))
233 if((errno == ENOENT) && bad_path)
235 unix_ERR_class = ERRDOS;
236 unix_ERR_code = ERRbadpath;
239 return(UNIXERROR(ERRDOS,ERRnoaccess));
242 unixmode = unix_mode(conn,open_attr | aARCH, fname);
244 open_file_shared(fsp,conn,fname,open_mode,open_ofun,unixmode,
245 oplock_request, &rmode,&smb_action);
249 if((errno == ENOENT) && bad_path)
251 unix_ERR_class = ERRDOS;
252 unix_ERR_code = ERRbadpath;
255 return(UNIXERROR(ERRDOS,ERRnoaccess));
258 if (fsp->conn->vfs_ops.fstat(fsp->fd_ptr->fd,&sbuf) != 0) {
259 close_file(fsp,False);
260 return(UNIXERROR(ERRDOS,ERRnoaccess));
264 fmode = dos_mode(conn,fname,&sbuf);
265 mtime = sbuf.st_mtime;
268 close_file(fsp,False);
269 return(ERROR(ERRDOS,ERRnoaccess));
272 /* Realloc the size of parameters and data we will return */
273 params = *pparams = Realloc(*pparams, 28);
275 return(ERROR(ERRDOS,ERRnomem));
277 memset((char *)params,'\0',28);
278 SSVAL(params,0,fsp->fnum);
279 SSVAL(params,2,fmode);
280 put_dos_date2(params,4, mtime);
281 SIVAL(params,8, (uint32)size);
282 SSVAL(params,12,rmode);
284 if (oplock_request && lp_fake_oplocks(SNUM(conn))) {
285 smb_action |= EXTENDED_OPLOCK_GRANTED;
288 SSVAL(params,18,smb_action);
290 * WARNING - this may need to be changed if SMB_INO_T <> 4 bytes.
292 SIVAL(params,20,inode);
294 /* Send the required number of replies */
295 send_trans2_replies(outbuf, bufsize, params, 28, *ppdata, 0);
300 /****************************************************************************
301 get a level dependent lanman2 dir entry.
302 ****************************************************************************/
303 static BOOL get_lanman2_dir_entry(connection_struct *conn,
304 char *path_mask,int dirtype,int info_level,
305 int requires_resume_key,
306 BOOL dont_descend,char **ppdata,
307 char *base_data, int space_remaining,
308 BOOL *out_of_space, BOOL *got_exact_match,
313 SMB_STRUCT_STAT sbuf;
317 char *p, *pdata = *ppdata;
323 time_t mdate=0, adate=0, cdate=0;
325 BOOL isrootdir = (strequal(conn->dirpath,"./") ||
326 strequal(conn->dirpath,".") ||
327 strequal(conn->dirpath,"/"));
329 int nt_extmode; /* Used for NT connections instead of mode */
330 BOOL needslash = ( conn->dirpath[strlen(conn->dirpath) -1] != '/');
333 *out_of_space = False;
334 *got_exact_match = False;
339 p = strrchr(path_mask,'/');
348 pstrcpy(mask, path_mask);
354 /* Needed if we run out of space */
355 prev_dirpos = TellDir(conn->dirptr);
356 dname = ReadDirName(conn->dirptr);
359 * Due to bugs in NT client redirectors we are not using
360 * resume keys any more - set them to zero.
361 * Check out the related comments in findfirst/findnext.
367 DEBUG(8,("get_lanman2_dir_entry:readdir on dirptr 0x%lx now at offset %d\n",
368 (long)conn->dirptr,TellDir(conn->dirptr)));
373 pstrcpy(fname,dname);
375 if(!(got_match = *got_exact_match = exact_match(fname, mask, case_sensitive)))
376 got_match = mask_match(fname, mask, case_sensitive, True);
378 if(!got_match && !is_8_3(fname, False)) {
381 * It turns out that NT matches wildcards against
382 * both long *and* short names. This may explain some
383 * of the wildcard wierdness from old DOS clients
384 * that some people have been seeing.... JRA.
388 pstrcpy( newname, fname);
389 name_map_mangle( newname, True, False, SNUM(conn));
390 if(!(got_match = *got_exact_match = exact_match(newname, mask, case_sensitive)))
391 got_match = mask_match(newname, mask, case_sensitive, True);
396 BOOL isdots = (strequal(fname,"..") || strequal(fname,"."));
397 if (dont_descend && !isdots)
400 if (isrootdir && isdots)
403 pstrcpy(pathreal,conn->dirpath);
405 pstrcat(pathreal,"/");
406 pstrcat(pathreal,dname);
407 if (conn->vfs_ops.stat(dos_to_unix(pathreal,False),&sbuf) != 0)
409 DEBUG(5,("get_lanman2_dir_entry:Couldn't stat [%s] (%s)\n",pathreal,strerror(errno)));
413 mode = dos_mode(conn,pathreal,&sbuf);
415 if (!dir_check_ftype(conn,mode,&sbuf,dirtype)) {
416 DEBUG(5,("[%s] attribs didn't match %x\n",fname,dirtype));
421 mdate = sbuf.st_mtime;
422 adate = sbuf.st_atime;
423 cdate = get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(conn)));
427 DEBUG(5,("get_lanman2_dir_entry found %s fname=%s\n",pathreal,fname));
433 name_map_mangle(fname,False,True,SNUM(conn));
438 nt_extmode = mode ? mode : FILE_ATTRIBUTE_NORMAL;
443 if(requires_resume_key) {
447 put_dos_date2(p,l1_fdateCreation,cdate);
448 put_dos_date2(p,l1_fdateLastAccess,adate);
449 put_dos_date2(p,l1_fdateLastWrite,mdate);
450 SIVAL(p,l1_cbFile,(uint32)size);
451 SIVAL(p,l1_cbFileAlloc,SMB_ROUNDUP(size,1024));
452 SSVAL(p,l1_attrFile,mode);
453 SCVAL(p,l1_cchName,strlen(fname));
454 pstrcpy(p + l1_achName, fname);
455 nameptr = p + l1_achName;
456 p += l1_achName + strlen(fname) + 1;
461 if(requires_resume_key) {
465 put_dos_date2(p,l2_fdateCreation,cdate);
466 put_dos_date2(p,l2_fdateLastAccess,adate);
467 put_dos_date2(p,l2_fdateLastWrite,mdate);
468 SIVAL(p,l2_cbFile,(uint32)size);
469 SIVAL(p,l2_cbFileAlloc,SMB_ROUNDUP(size,1024));
470 SSVAL(p,l2_attrFile,mode);
471 SIVAL(p,l2_cbList,0); /* No extended attributes */
472 SCVAL(p,l2_cchName,strlen(fname));
473 pstrcpy(p + l2_achName, fname);
474 nameptr = p + l2_achName;
475 p += l2_achName + strlen(fname) + 1;
480 put_dos_date2(p,4,cdate);
481 put_dos_date2(p,8,adate);
482 put_dos_date2(p,12,mdate);
483 SIVAL(p,16,(uint32)size);
484 SIVAL(p,20,SMB_ROUNDUP(size,1024));
487 CVAL(p,30) = strlen(fname);
488 pstrcpy(p+31, fname);
490 p += 31 + strlen(fname) + 1;
494 if(requires_resume_key) {
498 SIVAL(p,0,33+strlen(fname)+1);
499 put_dos_date2(p,4,cdate);
500 put_dos_date2(p,8,adate);
501 put_dos_date2(p,12,mdate);
502 SIVAL(p,16,(uint32)size);
503 SIVAL(p,20,SMB_ROUNDUP(size,1024));
505 CVAL(p,32) = strlen(fname);
506 pstrcpy(p + 33, fname);
508 p += 33 + strlen(fname) + 1;
511 case SMB_FIND_FILE_BOTH_DIRECTORY_INFO:
512 was_8_3 = is_8_3(fname, True);
513 len = 94+strlen(fname);
514 len = (len + 3) & ~3;
515 SIVAL(p,0,len); p += 4;
516 SIVAL(p,0,reskey); p += 4;
517 put_long_date(p,cdate); p += 8;
518 put_long_date(p,adate); p += 8;
519 put_long_date(p,mdate); p += 8;
520 put_long_date(p,mdate); p += 8;
524 SIVAL(p,0,nt_extmode); p += 4;
525 SIVAL(p,0,strlen(fname)); p += 4;
526 SIVAL(p,0,0); p += 4;
529 if (!name_map_mangle(p+2,True,True,SNUM(conn)))
534 SSVAL(p,0,strlen(p+2));
537 pstrcpy(p,fname); p += strlen(p);
541 case SMB_FIND_FILE_DIRECTORY_INFO:
542 len = 64+strlen(fname);
543 len = (len + 3) & ~3;
544 SIVAL(p,0,len); p += 4;
545 SIVAL(p,0,reskey); p += 4;
546 put_long_date(p,cdate); p += 8;
547 put_long_date(p,adate); p += 8;
548 put_long_date(p,mdate); p += 8;
549 put_long_date(p,mdate); p += 8;
553 SIVAL(p,0,nt_extmode); p += 4;
554 SIVAL(p,0,strlen(fname)); p += 4;
560 case SMB_FIND_FILE_FULL_DIRECTORY_INFO:
561 len = 68+strlen(fname);
562 len = (len + 3) & ~3;
563 SIVAL(p,0,len); p += 4;
564 SIVAL(p,0,reskey); p += 4;
565 put_long_date(p,cdate); p += 8;
566 put_long_date(p,adate); p += 8;
567 put_long_date(p,mdate); p += 8;
568 put_long_date(p,mdate); p += 8;
572 SIVAL(p,0,nt_extmode); p += 4;
573 SIVAL(p,0,strlen(fname)); p += 4;
574 SIVAL(p,0,0); p += 4;
579 case SMB_FIND_FILE_NAMES_INFO:
580 len = 12+strlen(fname);
581 len = (len + 3) & ~3;
582 SIVAL(p,0,len); p += 4;
583 SIVAL(p,0,reskey); p += 4;
584 SIVAL(p,0,strlen(fname)); p += 4;
594 if (PTR_DIFF(p,pdata) > space_remaining) {
595 /* Move the dirptr back to prev_dirpos */
596 SeekDir(conn->dirptr, prev_dirpos);
597 *out_of_space = True;
598 DEBUG(9,("get_lanman2_dir_entry: out of space\n"));
599 return False; /* Not finished - just out of space */
602 /* Setup the last_filename pointer, as an offset from base_data */
603 *last_name_off = PTR_DIFF(nameptr,base_data);
604 /* Advance the data pointer to the next slot */
610 /****************************************************************************
611 Convert the directory masks formated for the wire.
612 ****************************************************************************/
614 void mask_convert( char *mask)
617 * We know mask is a pstring.
623 if(p[1] != '"' && p[1] != '.') {
624 pstrcpy( expnd, p+1 );
627 safe_strcpy( p+1, expnd, sizeof(pstring) - (p - mask) - 2);
631 if (*p == '>') *p = '?';
632 if (*p == '"') *p = '.';
637 /****************************************************************************
638 Reply to a TRANS2_FINDFIRST.
639 ****************************************************************************/
641 static int call_trans2findfirst(connection_struct *conn,
642 char *inbuf, char *outbuf, int bufsize,
643 char **pparams, char **ppdata)
645 /* We must be careful here that we don't return more than the
646 allowed number of data bytes. If this means returning fewer than
647 maxentries then so be it. We assume that the redirector has
648 enough room for the fixed number of parameter bytes it has
650 uint32 max_data_bytes = SVAL(inbuf, smb_mdrcnt);
651 char *params = *pparams;
652 char *pdata = *ppdata;
653 int dirtype = SVAL(params,0);
654 int maxentries = SVAL(params,2);
655 BOOL close_after_first = BITSETW(params+4,0);
656 BOOL close_if_end = BITSETW(params+4,1);
657 BOOL requires_resume_key = BITSETW(params+4,2);
658 int info_level = SVAL(params,6);
666 BOOL finished = False;
667 BOOL dont_descend = False;
668 BOOL out_of_space = False;
670 BOOL bad_path = False;
672 *directory = *mask = 0;
674 DEBUG(3,("call_trans2findfirst: dirtype = %d, maxentries = %d, close_after_first=%d, close_if_end = %d requires_resume_key = %d level = %d, max_data_bytes = %d\n",
675 dirtype, maxentries, close_after_first, close_if_end, requires_resume_key,
676 info_level, max_data_bytes));
684 case SMB_FIND_FILE_DIRECTORY_INFO:
685 case SMB_FIND_FILE_FULL_DIRECTORY_INFO:
686 case SMB_FIND_FILE_NAMES_INFO:
687 case SMB_FIND_FILE_BOTH_DIRECTORY_INFO:
690 return(ERROR(ERRDOS,ERRunknownlevel));
693 pstrcpy(directory, params + 12); /* Complete directory path with
694 wildcard mask appended */
696 RESOLVE_FINDFIRST_DFSPATH(directory, conn, inbuf, outbuf);
698 DEBUG(5,("path=%s\n",directory));
700 unix_convert(directory,conn,0,&bad_path,NULL);
701 if(!check_name(directory,conn)) {
702 if((errno == ENOENT) && bad_path)
704 unix_ERR_class = ERRDOS;
705 unix_ERR_code = ERRbadpath;
709 /* Ugly - NT specific hack - maybe not needed ? (JRA) */
710 if((errno == ENOTDIR) && (Protocol >= PROTOCOL_NT1) &&
711 (get_remote_arch() == RA_WINNT))
713 unix_ERR_class = ERRDOS;
714 unix_ERR_code = ERRbaddirectory;
718 return(UNIXERROR(ERRDOS,ERRbadpath));
721 p = strrchr(directory,'/');
723 pstrcpy(mask,directory);
724 pstrcpy(directory,"./");
730 DEBUG(5,("dir=%s, mask = %s\n",directory, mask));
732 pdata = *ppdata = Realloc(*ppdata, max_data_bytes + 1024);
734 return(ERROR(ERRDOS,ERRnomem));
735 memset((char *)pdata,'\0',max_data_bytes + 1024);
737 /* Realloc the params space */
738 params = *pparams = Realloc(*pparams, 10);
740 return(ERROR(ERRDOS,ERRnomem));
742 dptr_num = dptr_create(conn,directory, False, True ,SVAL(inbuf,smb_pid));
744 return(UNIXERROR(ERRDOS,ERRbadfile));
746 /* Convert the formatted mask. */
749 /* Save the wildcard match and attribs we are using on this directory -
750 needed as lanman2 assumes these are being saved between calls */
752 if(!(wcard = strdup(mask))) {
753 dptr_close(&dptr_num);
754 return(ERROR(ERRDOS,ERRnomem));
757 dptr_set_wcard(dptr_num, wcard);
758 dptr_set_attr(dptr_num, dirtype);
760 DEBUG(4,("dptr_num is %d, wcard = %s, attr = %d\n",dptr_num, wcard, dirtype));
762 /* We don't need to check for VOL here as this is returned by
763 a different TRANS2 call. */
765 DEBUG(8,("dirpath=<%s> dontdescend=<%s>\n",
766 conn->dirpath,lp_dontdescend(SNUM(conn))));
767 if (in_list(conn->dirpath,lp_dontdescend(SNUM(conn)),case_sensitive))
771 space_remaining = max_data_bytes;
772 out_of_space = False;
774 for (i=0;(i<maxentries) && !finished && !out_of_space;i++)
776 BOOL got_exact_match;
778 /* this is a heuristic to avoid seeking the dirptr except when
779 absolutely necessary. It allows for a filename of about 40 chars */
780 if (space_remaining < DIRLEN_GUESS && numentries > 0)
787 finished = !get_lanman2_dir_entry(conn,mask,dirtype,info_level,
788 requires_resume_key,dont_descend,
789 &p,pdata,space_remaining, &out_of_space, &got_exact_match,
793 if (finished && out_of_space)
796 if (!finished && !out_of_space)
800 * As an optimisation if we know we aren't looking
801 * for a wildcard name (ie. the name matches the wildcard exactly)
802 * then we can finish on any (first) match.
803 * This speeds up large directory searches. JRA.
809 space_remaining = max_data_bytes - PTR_DIFF(p,pdata);
812 /* Check if we can close the dirptr */
813 if(close_after_first || (finished && close_if_end))
815 DEBUG(5,("call_trans2findfirst - (2) closing dptr_num %d\n", dptr_num));
816 dptr_close(&dptr_num);
820 * If there are no matching entries we must return ERRDOS/ERRbadfile -
821 * from observation of NT.
826 dptr_close(&dptr_num);
827 return(ERROR(ERRDOS,ERRbadfile));
830 /* At this point pdata points to numentries directory entries. */
832 /* Set up the return parameter block */
833 SSVAL(params,0,dptr_num);
834 SSVAL(params,2,numentries);
835 SSVAL(params,4,finished);
836 SSVAL(params,6,0); /* Never an EA error */
837 SSVAL(params,8,last_name_off);
839 send_trans2_replies( outbuf, bufsize, params, 10, pdata, PTR_DIFF(p,pdata));
841 if ((! *directory) && dptr_path(dptr_num))
842 slprintf(directory,sizeof(directory)-1, "(%s)",dptr_path(dptr_num));
844 DEBUG( 4, ( "%s mask=%s directory=%s dirtype=%d numentries=%d\n",
845 smb_fn_name(CVAL(inbuf,smb_com)),
846 mask, directory, dirtype, numentries ) );
849 * Force a name mangle here to ensure that the
850 * mask as an 8.3 name is top of the mangled cache.
851 * The reasons for this are subtle. Don't remove
852 * this code unless you know what you are doing
853 * (see PR#13758). JRA.
856 if(!is_8_3( mask, False))
857 name_map_mangle(mask, True, True, SNUM(conn));
863 /****************************************************************************
864 reply to a TRANS2_FINDNEXT
865 ****************************************************************************/
866 static int call_trans2findnext(connection_struct *conn,
867 char *inbuf, char *outbuf,
868 int length, int bufsize,
869 char **pparams, char **ppdata)
871 /* We must be careful here that we don't return more than the
872 allowed number of data bytes. If this means returning fewer than
873 maxentries then so be it. We assume that the redirector has
874 enough room for the fixed number of parameter bytes it has
876 int max_data_bytes = SVAL(inbuf, smb_mdrcnt);
877 char *params = *pparams;
878 char *pdata = *ppdata;
879 int dptr_num = SVAL(params,0);
880 int maxentries = SVAL(params,2);
881 uint16 info_level = SVAL(params,4);
882 uint32 resume_key = IVAL(params,6);
883 BOOL close_after_request = BITSETW(params+10,0);
884 BOOL close_if_end = BITSETW(params+10,1);
885 BOOL requires_resume_key = BITSETW(params+10,2);
886 BOOL continue_bit = BITSETW(params+10,3);
893 int i, last_name_off=0;
894 BOOL finished = False;
895 BOOL dont_descend = False;
896 BOOL out_of_space = False;
899 *mask = *directory = *resume_name = 0;
901 pstrcpy( resume_name, params+12);
903 DEBUG(3,("call_trans2findnext: dirhandle = %d, max_data_bytes = %d, maxentries = %d, \
904 close_after_request=%d, close_if_end = %d requires_resume_key = %d \
905 resume_key = %d resume name = %s continue=%d level = %d\n",
906 dptr_num, max_data_bytes, maxentries, close_after_request, close_if_end,
907 requires_resume_key, resume_key, resume_name, continue_bit, info_level));
915 case SMB_FIND_FILE_DIRECTORY_INFO:
916 case SMB_FIND_FILE_FULL_DIRECTORY_INFO:
917 case SMB_FIND_FILE_NAMES_INFO:
918 case SMB_FIND_FILE_BOTH_DIRECTORY_INFO:
921 return(ERROR(ERRDOS,ERRunknownlevel));
924 pdata = *ppdata = Realloc( *ppdata, max_data_bytes + 1024);
926 return(ERROR(ERRDOS,ERRnomem));
927 memset((char *)pdata,'\0',max_data_bytes + 1024);
929 /* Realloc the params space */
930 params = *pparams = Realloc(*pparams, 6*SIZEOFWORD);
932 return(ERROR(ERRDOS,ERRnomem));
934 /* Check that the dptr is valid */
935 if(!(conn->dirptr = dptr_fetch_lanman2(dptr_num)))
936 return(ERROR(ERRDOS,ERRnofiles));
938 string_set(&conn->dirpath,dptr_path(dptr_num));
940 /* Get the wildcard mask from the dptr */
941 if((p = dptr_wcard(dptr_num))== NULL) {
942 DEBUG(2,("dptr_num %d has no wildcard\n", dptr_num));
943 return (ERROR(ERRDOS,ERRnofiles));
946 pstrcpy(directory,conn->dirpath);
948 /* Get the attr mask from the dptr */
949 dirtype = dptr_attr(dptr_num);
951 DEBUG(3,("dptr_num is %d, mask = %s, attr = %x, dirptr=(0x%lX,%d)\n",
952 dptr_num, mask, dirtype,
954 TellDir(conn->dirptr)));
956 /* We don't need to check for VOL here as this is returned by
957 a different TRANS2 call. */
959 DEBUG(8,("dirpath=<%s> dontdescend=<%s>\n",conn->dirpath,lp_dontdescend(SNUM(conn))));
960 if (in_list(conn->dirpath,lp_dontdescend(SNUM(conn)),case_sensitive))
964 space_remaining = max_data_bytes;
965 out_of_space = False;
968 * Seek to the correct position. We no longer use the resume key but
969 * depend on the last file name instead.
971 if(requires_resume_key && *resume_name && !continue_bit)
974 * Fix for NT redirector problem triggered by resume key indexes
975 * changing between directory scans. We now return a resume key of 0
976 * and instead look for the filename to continue from (also given
977 * to us by NT/95/smbfs/smbclient). If no other scans have been done between the
978 * findfirst/findnext (as is usual) then the directory pointer
979 * should already be at the correct place. Check this by scanning
980 * backwards looking for an exact (ie. case sensitive) filename match.
981 * If we get to the beginning of the directory and haven't found it then scan
982 * forwards again looking for a match. JRA.
985 int current_pos, start_pos;
987 void *dirptr = conn->dirptr;
988 start_pos = TellDir(dirptr);
989 for(current_pos = start_pos; current_pos >= 0; current_pos--)
991 DEBUG(7,("call_trans2findnext: seeking to pos %d\n", current_pos));
993 SeekDir(dirptr, current_pos);
994 dname = ReadDirName(dirptr);
997 * Remember, name_map_mangle is called by
998 * get_lanman2_dir_entry(), so the resume name
999 * could be mangled. Ensure we do the same
1004 name_map_mangle( dname, False, True, SNUM(conn));
1006 if(dname && strcsequal( resume_name, dname))
1008 SeekDir(dirptr, current_pos+1);
1009 DEBUG(7,("call_trans2findnext: got match at pos %d\n", current_pos+1 ));
1015 * Scan forward from start if not found going backwards.
1020 DEBUG(7,("call_trans2findnext: notfound: seeking to pos %d\n", start_pos));
1021 SeekDir(dirptr, start_pos);
1022 for(current_pos = start_pos; (dname = ReadDirName(dirptr)) != NULL; SeekDir(dirptr,++current_pos))
1025 * Remember, name_map_mangle is called by
1026 * get_lanman2_dir_entry(), so the resume name
1027 * could be mangled. Ensure we do the same
1032 name_map_mangle( dname, False, True, SNUM(conn));
1034 if(dname && strcsequal( resume_name, dname))
1036 SeekDir(dirptr, current_pos+1);
1037 DEBUG(7,("call_trans2findnext: got match at pos %d\n", current_pos+1 ));
1041 } /* end if current_pos */
1042 } /* end if requires_resume_key && !continue_bit */
1044 for (i=0;(i<(int)maxentries) && !finished && !out_of_space ;i++)
1046 BOOL got_exact_match;
1048 /* this is a heuristic to avoid seeking the dirptr except when
1049 absolutely necessary. It allows for a filename of about 40 chars */
1050 if (space_remaining < DIRLEN_GUESS && numentries > 0)
1052 out_of_space = True;
1057 finished = !get_lanman2_dir_entry(conn,mask,dirtype,info_level,
1058 requires_resume_key,dont_descend,
1059 &p,pdata,space_remaining, &out_of_space, &got_exact_match,
1063 if (finished && out_of_space)
1066 if (!finished && !out_of_space)
1070 * As an optimisation if we know we aren't looking
1071 * for a wildcard name (ie. the name matches the wildcard exactly)
1072 * then we can finish on any (first) match.
1073 * This speeds up large directory searches. JRA.
1079 space_remaining = max_data_bytes - PTR_DIFF(p,pdata);
1082 /* Check if we can close the dirptr */
1083 if(close_after_request || (finished && close_if_end))
1085 DEBUG(5,("call_trans2findnext: closing dptr_num = %d\n", dptr_num));
1086 dptr_close(&dptr_num); /* This frees up the saved mask */
1090 /* Set up the return parameter block */
1091 SSVAL(params,0,numentries);
1092 SSVAL(params,2,finished);
1093 SSVAL(params,4,0); /* Never an EA error */
1094 SSVAL(params,6,last_name_off);
1096 send_trans2_replies( outbuf, bufsize, params, 8, pdata, PTR_DIFF(p,pdata));
1098 if ((! *directory) && dptr_path(dptr_num))
1099 slprintf(directory,sizeof(directory)-1, "(%s)",dptr_path(dptr_num));
1101 DEBUG( 3, ( "%s mask=%s directory=%s dirtype=%d numentries=%d\n",
1102 smb_fn_name(CVAL(inbuf,smb_com)),
1103 mask, directory, dirtype, numentries ) );
1108 /****************************************************************************
1109 reply to a TRANS2_QFSINFO (query filesystem info)
1110 ****************************************************************************/
1112 static int call_trans2qfsinfo(connection_struct *conn,
1113 char *inbuf, char *outbuf,
1114 int length, int bufsize,
1115 char **pparams, char **ppdata)
1117 int max_data_bytes = SVAL(inbuf, smb_mdrcnt);
1118 char *pdata = *ppdata;
1119 char *params = *pparams;
1120 uint16 info_level = SVAL(params,0);
1123 char *vname = volume_label(SNUM(conn));
1124 int snum = SNUM(conn);
1125 char *fstype = lp_fstype(SNUM(conn));
1127 DEBUG(3,("call_trans2qfsinfo: level = %d\n", info_level));
1129 if(conn->vfs_ops.stat(".",&st)!=0) {
1130 DEBUG(2,("call_trans2qfsinfo: stat of . failed (%s)\n", strerror(errno)));
1131 return (ERROR(ERRSRV,ERRinvdevice));
1134 pdata = *ppdata = Realloc(*ppdata, max_data_bytes + 1024);
1135 memset((char *)pdata,'\0',max_data_bytes + 1024);
1141 SMB_BIG_UINT dfree,dsize,bsize;
1143 conn->vfs_ops.disk_free(".",False,&bsize,&dfree,&dsize);
1144 SIVAL(pdata,l1_idFileSystem,st.st_dev);
1145 SIVAL(pdata,l1_cSectorUnit,bsize/512);
1146 SIVAL(pdata,l1_cUnit,dsize);
1147 SIVAL(pdata,l1_cUnitAvail,dfree);
1148 SSVAL(pdata,l1_cbSector,512);
1149 DEBUG(5,("call_trans2qfsinfo : bsize=%u, id=%x, cSectorUnit=%u, cUnit=%u, cUnitAvail=%u, cbSector=%d\n",
1150 (unsigned int)bsize, (unsigned int)st.st_dev, ((unsigned int)bsize)/512, (unsigned int)dsize,
1151 (unsigned int)dfree, 512));
1156 /* Return volume name */
1157 int volname_len = MIN(strlen(vname),11);
1158 data_len = l2_vol_szVolLabel + volname_len + 1;
1160 * Add volume serial number - hash of a combination of
1161 * the called hostname and the service name.
1163 SIVAL(pdata,0,str_checksum(lp_servicename(snum)) ^ (str_checksum(local_machine)<<16) );
1164 SCVAL(pdata,l2_vol_cch,volname_len);
1165 StrnCpy(pdata+l2_vol_szVolLabel,vname,volname_len);
1166 DEBUG(5,("call_trans2qfsinfo : time = %x, namelen = %d, name = %s\n",
1167 (unsigned)st.st_ctime, volname_len,
1168 pdata+l2_vol_szVolLabel));
1171 case SMB_QUERY_FS_ATTRIBUTE_INFO:
1174 SIVAL(pdata,0,FILE_CASE_PRESERVED_NAMES|FILE_CASE_SENSITIVE_SEARCH|
1175 FILE_DEVICE_IS_MOUNTED|
1176 (lp_nt_acl_support() ? FILE_PERSISTENT_ACLS : 0)); /* FS ATTRIBUTES */
1177 #if 0 /* Old code. JRA. */
1178 SIVAL(pdata,0,0x4006); /* FS ATTRIBUTES == long filenames supported? */
1179 #endif /* Old code. */
1181 SIVAL(pdata,4,128); /* Max filename component length */
1182 fstype_len = dos_PutUniCode(pdata+12,unix_to_dos(fstype,False),sizeof(pstring), False);
1183 SIVAL(pdata,8,fstype_len);
1184 data_len = 12 + fstype_len;
1185 SSVAL(outbuf,smb_flg2,SVAL(outbuf,smb_flg2)|FLAGS2_UNICODE_STRINGS);
1188 case SMB_QUERY_FS_LABEL_INFO:
1189 data_len = 4 + strlen(vname);
1190 SIVAL(pdata,0,strlen(vname));
1191 pstrcpy(pdata+4,vname);
1193 case SMB_QUERY_FS_VOLUME_INFO:
1196 * Add volume serial number - hash of a combination of
1197 * the called hostname and the service name.
1199 SIVAL(pdata,8,str_checksum(lp_servicename(snum)) ^
1200 (str_checksum(local_machine)<<16));
1202 /* NT4 always serves this up as unicode but expects it to be
1203 * delivered as ascii! (tridge && JRA)
1205 if (global_client_caps & CAP_NT_SMBS) {
1206 data_len = 18 + strlen(vname);
1207 SIVAL(pdata,12,strlen(vname));
1208 pstrcpy(pdata+18,vname);
1210 data_len = 18 + 2*strlen(vname);
1211 SIVAL(pdata,12,strlen(vname)*2);
1212 dos_PutUniCode(pdata+18,unix_to_dos(vname,False),sizeof(pstring), False);
1215 DEBUG(5,("call_trans2qfsinfo : SMB_QUERY_FS_VOLUME_INFO namelen = %d, vol = %s\n",
1216 (int)strlen(vname),vname));
1218 case SMB_QUERY_FS_SIZE_INFO:
1220 SMB_BIG_UINT dfree,dsize,bsize;
1222 conn->vfs_ops.disk_free(".",False,&bsize,&dfree,&dsize);
1223 SBIG_UINT(pdata,0,dsize);
1224 SBIG_UINT(pdata,8,dfree);
1225 SIVAL(pdata,16,bsize/512);
1226 SIVAL(pdata,20,512);
1229 case SMB_QUERY_FS_DEVICE_INFO:
1231 SIVAL(pdata,0,0); /* dev type */
1232 SIVAL(pdata,4,0); /* characteristics */
1234 case SMB_MAC_QUERY_FS_INFO:
1236 * Thursby MAC extension... ONLY on NTFS filesystems
1237 * once we do streams then we don't need this
1239 if (strequal(lp_fstype(SNUM(conn)),"NTFS")) {
1241 SIVAL(pdata,84,0x100); /* Don't support mac... */
1246 return(ERROR(ERRDOS,ERRunknownlevel));
1250 send_trans2_replies( outbuf, bufsize, params, 0, pdata, data_len);
1252 DEBUG( 4, ( "%s info_level = %d\n",
1253 smb_fn_name(CVAL(inbuf,smb_com)), info_level) );
1258 /****************************************************************************
1259 reply to a TRANS2_SETFSINFO (set filesystem info)
1260 ****************************************************************************/
1261 static int call_trans2setfsinfo(connection_struct *conn,
1262 char *inbuf, char *outbuf, int length,
1264 char **pparams, char **ppdata)
1266 /* Just say yes we did it - there is nothing that
1267 can be set here so it doesn't matter. */
1269 DEBUG(3,("call_trans2setfsinfo\n"));
1271 if (!CAN_WRITE(conn))
1272 return(ERROR(ERRSRV,ERRaccess));
1274 outsize = set_message(outbuf,10,0,True);
1279 /****************************************************************************
1280 Reply to a TRANS2_QFILEPATHINFO or TRANSACT2_QFILEINFO (query file info by
1281 file name or file id).
1282 ****************************************************************************/
1284 static int call_trans2qfilepathinfo(connection_struct *conn,
1285 char *inbuf, char *outbuf, int length,
1287 char **pparams,char **ppdata,
1290 int max_data_bytes = SVAL(inbuf, smb_mdrcnt);
1291 char *params = *pparams;
1292 char *pdata = *ppdata;
1293 uint16 tran_call = SVAL(inbuf, smb_setup0);
1297 unsigned int data_size;
1298 SMB_STRUCT_STAT sbuf;
1304 BOOL bad_path = False;
1305 BOOL delete_pending = False;
1307 if (tran_call == TRANSACT2_QFILEINFO) {
1308 files_struct *fsp = file_fsp(params,0);
1309 info_level = SVAL(params,2);
1311 DEBUG(3,("call_trans2qfilepathinfo: TRANSACT2_QFILEINFO: level = %d\n", info_level));
1313 if(fsp && fsp->open && (fsp->is_directory || fsp->stat_open)) {
1315 * This is actually a QFILEINFO on a directory
1316 * handle (returned from an NT SMB). NT5.0 seems
1317 * to do this call. JRA.
1319 fname = fsp->fsp_name;
1320 unix_convert(fname,conn,0,&bad_path,&sbuf);
1321 if (!check_name(fname,conn) ||
1322 (!VALID_STAT(sbuf) && conn->vfs_ops.stat(dos_to_unix(fname,False),&sbuf))) {
1323 DEBUG(3,("fileinfo of %s failed (%s)\n",fname,strerror(errno)));
1324 if((errno == ENOENT) && bad_path)
1326 unix_ERR_class = ERRDOS;
1327 unix_ERR_code = ERRbadpath;
1329 return(UNIXERROR(ERRDOS,ERRbadpath));
1332 delete_pending = fsp->directory_delete_on_close;
1336 * Original code - this is an open file.
1338 CHECK_FSP(fsp,conn);
1341 fname = fsp->fsp_name;
1342 if (fsp->conn->vfs_ops.fstat(fsp->fd_ptr->fd,&sbuf) != 0) {
1343 DEBUG(3,("fstat of fnum %d failed (%s)\n",fsp->fnum, strerror(errno)));
1344 return(UNIXERROR(ERRDOS,ERRbadfid));
1346 if((pos = fsp->conn->vfs_ops.lseek(fsp->fd_ptr->fd,0,SEEK_CUR)) == -1)
1347 return(UNIXERROR(ERRDOS,ERRnoaccess));
1349 delete_pending = fsp->fd_ptr->delete_on_close;
1353 info_level = SVAL(params,0);
1355 DEBUG(3,("call_trans2qfilepathinfo: TRANSACT2_QPATHINFO: level = %d\n", info_level));
1358 pstrcpy(fname,¶ms[6]);
1360 RESOLVE_DFSPATH(fname, conn, inbuf, outbuf);
1362 unix_convert(fname,conn,0,&bad_path,&sbuf);
1363 if (!check_name(fname,conn) ||
1364 (!VALID_STAT(sbuf) && conn->vfs_ops.stat(dos_to_unix(fname,False),&sbuf))) {
1365 DEBUG(3,("fileinfo of %s failed (%s)\n",fname,strerror(errno)));
1366 if((errno == ENOENT) && bad_path)
1368 unix_ERR_class = ERRDOS;
1369 unix_ERR_code = ERRbadpath;
1371 return(UNIXERROR(ERRDOS,ERRbadpath));
1376 DEBUG(3,("call_trans2qfilepathinfo %s level=%d call=%d total_data=%d\n",
1377 fname,info_level,tran_call,total_data));
1379 p = strrchr(fname,'/');
1385 mode = dos_mode(conn,fname,&sbuf);
1386 size = sbuf.st_size;
1387 if (mode & aDIR) size = 0;
1389 /* from now on we only want the part after the / */
1392 params = *pparams = Realloc(*pparams,2);
1393 memset((char *)params,'\0',2);
1394 data_size = max_data_bytes + 1024;
1395 pdata = *ppdata = Realloc(*ppdata, data_size);
1397 if (total_data > 0 && IVAL(pdata,0) == total_data) {
1398 /* uggh, EAs for OS2 */
1399 DEBUG(4,("Rejecting EA request with total_data=%d\n",total_data));
1400 return(ERROR(ERRDOS,ERROR_EAS_NOT_SUPPORTED));
1403 memset((char *)pdata,'\0',data_size);
1407 case SMB_INFO_STANDARD:
1408 case SMB_INFO_QUERY_EA_SIZE:
1409 data_size = (info_level==1?22:26);
1410 put_dos_date2(pdata,l1_fdateCreation,get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(conn))));
1411 put_dos_date2(pdata,l1_fdateLastAccess,sbuf.st_atime);
1412 put_dos_date2(pdata,l1_fdateLastWrite,sbuf.st_mtime); /* write time */
1413 SIVAL(pdata,l1_cbFile,(uint32)size);
1414 SIVAL(pdata,l1_cbFileAlloc,SMB_ROUNDUP(size,1024));
1415 SSVAL(pdata,l1_attrFile,mode);
1416 SIVAL(pdata,l1_attrFile+2,4); /* this is what OS2 does */
1419 case SMB_INFO_QUERY_EAS_FROM_LIST:
1421 put_dos_date2(pdata,0,get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(conn))));
1422 put_dos_date2(pdata,4,sbuf.st_atime);
1423 put_dos_date2(pdata,8,sbuf.st_mtime);
1424 SIVAL(pdata,12,(uint32)size);
1425 SIVAL(pdata,16,SMB_ROUNDUP(size,1024));
1426 SIVAL(pdata,20,mode);
1429 case SMB_INFO_QUERY_ALL_EAS:
1431 SIVAL(pdata,0,data_size);
1435 return(ERROR(ERRDOS,ERRbadfunc)); /* os/2 needs this */
1437 case SMB_QUERY_FILE_BASIC_INFO:
1438 data_size = 36; /* w95 returns 40 bytes not 36 - why ?. */
1439 put_long_date(pdata,get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(conn))));
1440 put_long_date(pdata+8,sbuf.st_atime);
1441 put_long_date(pdata+16,sbuf.st_mtime); /* write time */
1442 put_long_date(pdata+24,sbuf.st_mtime); /* change time */
1443 SIVAL(pdata,32,mode);
1445 DEBUG(5,("SMB_QFBI - "));
1447 time_t create_time = get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(conn)));
1448 DEBUG(5,("create: %s ", ctime(&create_time)));
1450 DEBUG(5,("access: %s ", ctime(&sbuf.st_atime)));
1451 DEBUG(5,("write: %s ", ctime(&sbuf.st_mtime)));
1452 DEBUG(5,("change: %s ", ctime(&sbuf.st_mtime)));
1453 DEBUG(5,("mode: %x\n", mode));
1457 case SMB_QUERY_FILE_STANDARD_INFO:
1459 SOFF_T(pdata,0,size);
1460 SOFF_T(pdata,8,size);
1461 SIVAL(pdata,16,sbuf.st_nlink);
1463 CVAL(pdata,21) = (mode&aDIR)?1:0;
1466 case SMB_QUERY_FILE_EA_INFO:
1470 /* Get the 8.3 name - used if NT SMB was negotiated. */
1471 case SMB_QUERY_FILE_ALT_NAME_INFO:
1474 pstrcpy(short_name,p);
1475 /* Mangle if not already 8.3 */
1476 if(!is_8_3(short_name, True))
1478 if(!name_map_mangle(short_name,True,True,SNUM(conn)))
1481 strupper(short_name);
1482 l = strlen(short_name);
1483 dos_PutUniCode(pdata + 4, unix_to_dos(short_name,False),sizeof(pstring), False);
1484 data_size = 4 + (2*l);
1489 case SMB_QUERY_FILE_NAME_INFO:
1491 * The first part of this code is essential
1492 * to get security descriptors to work on mapped
1493 * drives. Don't ask how I discovered this unless
1494 * you like hearing about me suffering.... :-). JRA.
1496 if(strequal(".", fname) && (global_client_caps & CAP_UNICODE)) {
1498 SSVAL(outbuf,smb_flg2,SVAL(outbuf,smb_flg2)|FLAGS2_UNICODE_STRINGS);
1499 dos_PutUniCode(pdata + 4, unix_to_dos("\\",False),sizeof(pstring), False);
1501 pstrcpy(pdata+4,fname);
1507 case SMB_QUERY_FILE_ALLOCATION_INFO:
1508 case SMB_QUERY_FILE_END_OF_FILEINFO:
1510 SOFF_T(pdata,0,size);
1513 case SMB_QUERY_FILE_ALL_INFO:
1514 put_long_date(pdata,get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(conn))));
1515 put_long_date(pdata+8,sbuf.st_atime);
1516 put_long_date(pdata+16,sbuf.st_mtime); /* write time */
1517 put_long_date(pdata+24,sbuf.st_mtime); /* change time */
1518 SIVAL(pdata,32,mode);
1520 SOFF_T(pdata,0,size);
1521 SOFF_T(pdata,8,size);
1522 SIVAL(pdata,16,sbuf.st_nlink);
1523 CVAL(pdata,20) = delete_pending;
1524 CVAL(pdata,21) = (mode&aDIR)?1:0;
1526 SINO_T(pdata,0,(SMB_INO_T)sbuf.st_ino);
1527 pdata += 8; /* index number */
1528 pdata += 4; /* EA info */
1530 SIVAL(pdata,0,0xA9);
1532 SIVAL(pdata,0,0xd01BF);
1534 SOFF_T(pdata,0,pos); /* current offset */
1536 SIVAL(pdata,0,mode); /* is this the right sort of mode info? */
1538 pdata += 4; /* alignment */
1540 pstrcpy(pdata+4,fname);
1542 data_size = PTR_DIFF(pdata,(*ppdata));
1546 /* NT4 server just returns "invalid query" to this - if we try to answer
1547 it then NTws gets a BSOD! (tridge) */
1548 case SMB_QUERY_FILE_STREAM_INFO:
1551 SIVAL(pdata,4,size);
1552 SIVAL(pdata,12,size);
1554 pstrcpy(pdata+24,fname);
1559 return(ERROR(ERRDOS,ERRunknownlevel));
1562 send_trans2_replies( outbuf, bufsize, params, 2, *ppdata, data_size);
1567 /****************************************************************************
1568 reply to a TRANS2_SETFILEINFO (set file info by fileid)
1569 ****************************************************************************/
1570 static int call_trans2setfilepathinfo(connection_struct *conn,
1571 char *inbuf, char *outbuf, int length,
1572 int bufsize, char **pparams,
1573 char **ppdata, int total_data)
1575 char *params = *pparams;
1576 char *pdata = *ppdata;
1577 uint16 tran_call = SVAL(inbuf, smb_setup0);
1586 BOOL bad_path = False;
1587 files_struct *fsp = NULL;
1589 if (!CAN_WRITE(conn))
1590 return(ERROR(ERRSRV,ERRaccess));
1592 if (tran_call == TRANSACT2_SETFILEINFO) {
1593 fsp = file_fsp(params,0);
1594 info_level = SVAL(params,2);
1596 if(fsp && fsp->open && (fsp->is_directory || fsp->stat_open)) {
1598 * This is actually a SETFILEINFO on a directory
1599 * handle (returned from an NT SMB). NT5.0 seems
1600 * to do this call. JRA.
1602 fname = fsp->fsp_name;
1603 unix_convert(fname,conn,0,&bad_path,&st);
1604 if (!check_name(fname,conn) ||
1605 (!VALID_STAT(st) && conn->vfs_ops.stat(dos_to_unix(fname,False),&st))) {
1606 DEBUG(3,("fileinfo of %s failed (%s)\n",fname,strerror(errno)));
1607 if((errno == ENOENT) && bad_path)
1609 unix_ERR_class = ERRDOS;
1610 unix_ERR_code = ERRbadpath;
1612 return(UNIXERROR(ERRDOS,ERRbadpath));
1616 * Original code - this is an open file.
1618 CHECK_FSP(fsp,conn);
1621 fname = fsp->fsp_name;
1622 fd = fsp->fd_ptr->fd;
1624 if (fsp->conn->vfs_ops.fstat(fd,&st) != 0) {
1625 DEBUG(3,("fstat of fnum %d failed (%s)\n",fsp->fnum, strerror(errno)));
1626 return(UNIXERROR(ERRDOS,ERRbadfid));
1631 info_level = SVAL(params,0);
1633 pstrcpy(fname,¶ms[6]);
1634 unix_convert(fname,conn,0,&bad_path,&st);
1635 if(!check_name(fname, conn))
1637 if((errno == ENOENT) && bad_path)
1639 unix_ERR_class = ERRDOS;
1640 unix_ERR_code = ERRbadpath;
1642 return(UNIXERROR(ERRDOS,ERRbadpath));
1645 if(!VALID_STAT(st) && conn->vfs_ops.stat(dos_to_unix(fname,False),&st)!=0) {
1646 DEBUG(3,("stat of %s failed (%s)\n", fname, strerror(errno)));
1647 if((errno == ENOENT) && bad_path)
1649 unix_ERR_class = ERRDOS;
1650 unix_ERR_code = ERRbadpath;
1652 return(UNIXERROR(ERRDOS,ERRbadpath));
1656 DEBUG(3,("call_trans2setfilepathinfo(%d) %s info_level=%d totdata=%d\n",
1657 tran_call,fname,info_level,total_data));
1659 /* Realloc the parameter and data sizes */
1660 params = *pparams = Realloc(*pparams,2);
1662 return(ERROR(ERRDOS,ERRnomem));
1667 tvs.modtime = st.st_mtime;
1668 tvs.actime = st.st_atime;
1669 mode = dos_mode(conn,fname,&st);
1671 if (total_data > 0 && IVAL(pdata,0) == total_data) {
1672 /* uggh, EAs for OS2 */
1673 DEBUG(4,("Rejecting EA request with total_data=%d\n",total_data));
1674 return(ERROR(ERRDOS,ERROR_EAS_NOT_SUPPORTED));
1679 case SMB_INFO_STANDARD:
1680 case SMB_INFO_QUERY_EA_SIZE:
1683 tvs.actime = make_unix_date2(pdata+l1_fdateLastAccess);
1686 tvs.modtime = make_unix_date2(pdata+l1_fdateLastWrite);
1688 mode = SVAL(pdata,l1_attrFile);
1689 size = IVAL(pdata,l1_cbFile);
1693 /* XXXX um, i don't think this is right.
1694 it's also not in the cifs6.txt spec.
1696 case SMB_INFO_QUERY_EAS_FROM_LIST:
1697 tvs.actime = make_unix_date2(pdata+8);
1698 tvs.modtime = make_unix_date2(pdata+12);
1699 size = IVAL(pdata,16);
1700 mode = IVAL(pdata,24);
1703 /* XXXX nor this. not in cifs6.txt, either. */
1704 case SMB_INFO_QUERY_ALL_EAS:
1705 tvs.actime = make_unix_date2(pdata+8);
1706 tvs.modtime = make_unix_date2(pdata+12);
1707 size = IVAL(pdata,16);
1708 mode = IVAL(pdata,24);
1711 case SMB_SET_FILE_BASIC_INFO:
1713 /* Patch to do this correctly from Paul Eggert <eggert@twinsun.com>. */
1715 time_t changed_time;
1717 /* Ignore create time at offset pdata. */
1720 tvs.actime = interpret_long_date(pdata+8);
1722 write_time = interpret_long_date(pdata+16);
1723 changed_time = interpret_long_date(pdata+24);
1725 tvs.modtime = MIN(write_time, changed_time);
1727 /* Prefer a defined time to an undefined one. */
1728 if (tvs.modtime == (time_t)0 || tvs.modtime == (time_t)-1)
1729 tvs.modtime = (write_time == (time_t)0 || write_time == (time_t)-1
1733 #if 0 /* Needs more testing... */
1734 /* Test from Luke to prevent Win95 from
1735 setting incorrect values here.
1737 if (tvs.actime < tvs.modtime)
1738 return(ERROR(ERRDOS,ERRnoaccess));
1739 #endif /* Needs more testing... */
1742 mode = IVAL(pdata,32);
1747 * NT seems to use this call with a size of zero
1748 * to mean truncate the file. JRA.
1751 case SMB_SET_FILE_ALLOCATION_INFO:
1753 SMB_OFF_T newsize = IVAL(pdata,0);
1754 #ifdef LARGE_SMB_OFF_T
1755 newsize |= (((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 file allocation info for file %s to %.0f\n", fname, (double)newsize ));
1766 case SMB_SET_FILE_END_OF_FILE_INFO:
1768 size = IVAL(pdata,0);
1769 #ifdef LARGE_SMB_OFF_T
1770 size |= (((SMB_OFF_T)IVAL(pdata,4)) << 32);
1771 #else /* LARGE_SMB_OFF_T */
1772 if (IVAL(pdata,4) != 0) /* more than 32 bits? */
1773 return(ERROR(ERRDOS,ERRunknownlevel));
1774 #endif /* LARGE_SMB_OFF_T */
1775 DEBUG(10,("call_trans2setfilepathinfo: Set end of file info for file %s to %.0f\n", fname, (double)size ));
1779 case SMB_SET_FILE_DISPOSITION_INFO: /* Set delete on close for open file. */
1781 if ((tran_call == TRANSACT2_SETFILEINFO) && (fsp != NULL))
1783 BOOL delete_on_close = (CVAL(pdata,0) ? True : False);
1785 if(fsp->is_directory)
1787 fsp->directory_delete_on_close = delete_on_close;
1788 DEBUG(10, ("call_trans2setfilepathinfo: %s delete on close flag for fnum = %d, directory %s\n",
1789 delete_on_close ? "Added" : "Removed", fsp->fnum, fsp->fsp_name ));
1792 else if(fsp->stat_open)
1794 DEBUG(10, ("call_trans2setfilepathinfo: %s delete on close flag for fnum = %d, stat open %s\n",
1795 delete_on_close ? "Added" : "Removed", fsp->fnum, fsp->fsp_name ));
1801 * We can only set the delete on close flag if
1802 * the share mode contained ALLOW_SHARE_DELETE
1805 if(lp_share_modes(SNUM(conn)))
1807 if(!GET_ALLOW_SHARE_DELETE(fsp->share_mode))
1808 return(ERROR(ERRDOS,ERRnoaccess));
1811 * If the flag has been set then
1812 * modify the share mode entry for all files we have open
1813 * on this device and inode to tell other smbds we have
1814 * changed the delete on close flag.
1817 if(delete_on_close && !GET_DELETE_ON_CLOSE_FLAG(fsp->share_mode))
1820 files_struct *iterate_fsp;
1821 SMB_DEV_T dev = fsp->fd_ptr->dev;
1822 SMB_INO_T inode = fsp->fd_ptr->inode;
1823 int num_share_modes;
1824 share_mode_entry *current_shares = NULL;
1826 if(lock_share_entry(fsp->conn, dev, inode) == False)
1827 return(ERROR(ERRDOS,ERRnoaccess));
1830 * Before we allow this we need to ensure that all current opens
1831 * on the file have the GET_ALLOW_SHARE_DELETE flag set. If they
1832 * do not then we deny this (as we are essentially deleting the
1833 * file at this point.
1836 num_share_modes = get_share_modes(conn, dev, inode, ¤t_shares);
1837 for(i = 0; i < num_share_modes; i++)
1839 if(!GET_ALLOW_SHARE_DELETE(current_shares[i].share_mode))
1841 DEBUG(5,("call_trans2setfilepathinfo: refusing to set delete on close flag for fnum = %d, \
1842 file %s as a share exists that was not opened with FILE_DELETE access.\n",
1843 fsp->fnum, fsp->fsp_name ));
1848 unlock_share_entry(fsp->conn, dev, inode);
1851 * current_shares was malloced by get_share_modes - free it here.
1854 free((char *)current_shares);
1857 * Even though share violation would be more appropriate here,
1858 * return ERRnoaccess as that's what NT does.
1861 return(ERROR(ERRDOS,ERRnoaccess));
1866 * current_shares was malloced by get_share_modes - free it here.
1869 free((char *)current_shares);
1871 DEBUG(10,("call_trans2setfilepathinfo: %s delete on close flag for fnum = %d, file %s\n",
1872 delete_on_close ? "Adding" : "Removing", fsp->fnum, fsp->fsp_name ));
1875 * Go through all files we have open on the same device and
1876 * inode (hanging off the same hash bucket) and set the DELETE_ON_CLOSE_FLAG.
1877 * Other smbd's that have this file open will have to fend for themselves. We
1878 * take care of this (rare) case in close_file(). See the comment there.
1881 for(iterate_fsp = file_find_di_first(dev, inode); iterate_fsp;
1882 iterate_fsp = file_find_di_next(iterate_fsp))
1884 int new_share_mode = (delete_on_close ?
1885 (iterate_fsp->share_mode | DELETE_ON_CLOSE_FLAG) :
1886 (iterate_fsp->share_mode & ~DELETE_ON_CLOSE_FLAG) );
1888 DEBUG(10,("call_trans2setfilepathinfo: Changing share mode for fnum %d, file %s \
1889 dev = %x, inode = %.0f from %x to %x\n",
1890 iterate_fsp->fnum, iterate_fsp->fsp_name, (unsigned int)dev,
1891 (double)inode, iterate_fsp->share_mode, new_share_mode ));
1893 if(modify_share_mode(iterate_fsp, new_share_mode, iterate_fsp->oplock_type)==False)
1894 DEBUG(0,("call_trans2setfilepathinfo: failed to change delete on close for fnum %d, \
1895 dev = %x, inode = %.0f\n", iterate_fsp->fnum, (unsigned int)dev, (double)inode));
1899 * Set the delete on close flag in the reference
1900 * counted struct. Delete when the last reference
1903 fsp->fd_ptr->delete_on_close = delete_on_close;
1905 unlock_share_entry(fsp->conn, dev, inode);
1907 DEBUG(10, ("call_trans2setfilepathinfo: %s delete on close flag for fnum = %d, file %s\n",
1908 delete_on_close ? "Added" : "Removed", fsp->fnum, fsp->fsp_name ));
1910 } /* end if(delete_on_close && !GET_DELETE_ON_CLOSE_FLAG(fsp->share_mode)) */
1911 } /* end if lp_share_modes() */
1912 } /* end if is_directory. */
1914 return(ERROR(ERRDOS,ERRunknownlevel));
1920 return(ERROR(ERRDOS,ERRunknownlevel));
1924 /* get some defaults (no modifications) if any info is zero or -1. */
1925 if (tvs.actime == (time_t)0 || tvs.actime == (time_t)-1)
1926 tvs.actime = st.st_atime;
1928 if (tvs.modtime == (time_t)0 || tvs.modtime == (time_t)-1)
1929 tvs.modtime = st.st_mtime;
1931 DEBUG(6,("actime: %s " , ctime(&tvs.actime)));
1932 DEBUG(6,("modtime: %s ", ctime(&tvs.modtime)));
1933 DEBUG(6,("size: %.0f ", (double)size));
1934 DEBUG(6,("mode: %x\n" , mode));
1936 if(!((info_level == SMB_SET_FILE_END_OF_FILE_INFO) ||
1937 (info_level == SMB_SET_FILE_ALLOCATION_INFO))) {
1939 * Only do this test if we are not explicitly
1940 * changing the size of a file.
1946 /* Try and set the times, size and mode of this file -
1947 if they are different from the current values
1949 if (st.st_mtime != tvs.modtime || st.st_atime != tvs.actime) {
1952 * This was a setfileinfo on an open file.
1953 * NT does this a lot. It's actually pointless
1954 * setting the time here, as it will be overwritten
1955 * on the next write, so we save the request
1956 * away and will set it on file code. JRA.
1959 if (tvs.modtime != (time_t)0 && tvs.modtime != (time_t)-1) {
1960 DEBUG(10,("call_trans2setfilepathinfo: setting pending modtime to %s\n",
1961 ctime(&tvs.modtime) ));
1962 fsp->pending_modtime = tvs.modtime;
1967 DEBUG(10,("call_trans2setfilepathinfo: setting utimes to modified values.\n"));
1969 if(file_utime(conn, fname, &tvs)!=0)
1970 return(UNIXERROR(ERRDOS,ERRnoaccess));
1974 /* check the mode isn't different, before changing it */
1975 if ((mode != 0) && (mode != dos_mode(conn, fname, &st))) {
1977 DEBUG(10,("call_trans2setfilepathinfo: file %s : setting dos mode %x\n",
1980 if(file_chmod(conn, fname, mode, NULL)) {
1981 DEBUG(2,("chmod of %s failed (%s)\n", fname, strerror(errno)));
1982 return(UNIXERROR(ERRDOS,ERRnoaccess));
1986 if(size != st.st_size) {
1988 DEBUG(10,("call_trans2setfilepathinfo: file %s : setting new size to %.0f\n",
1989 fname, (double)size ));
1992 fd = conn->vfs_ops.open(dos_to_unix(fname,False),O_RDWR,0);
1994 return(UNIXERROR(ERRDOS,ERRbadpath));
1995 set_filelen(fd, size); /* tpot vfs */
1996 conn->vfs_ops.close(fd);
1998 set_filelen(fd, size); /* tpot vfs */
2002 set_filelen_write_cache(fsp, size);
2007 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
2012 /****************************************************************************
2013 reply to a TRANS2_MKDIR (make directory with extended attributes).
2014 ****************************************************************************/
2015 static int call_trans2mkdir(connection_struct *conn,
2016 char *inbuf, char *outbuf, int length, int bufsize,
2017 char **pparams, char **ppdata)
2019 char *params = *pparams;
2022 BOOL bad_path = False;
2024 if (!CAN_WRITE(conn))
2025 return(ERROR(ERRSRV,ERRaccess));
2027 pstrcpy(directory, ¶ms[4]);
2029 DEBUG(3,("call_trans2mkdir : name = %s\n", directory));
2031 unix_convert(directory,conn,0,&bad_path,NULL);
2032 if (check_name(directory,conn))
2033 ret = conn->vfs_ops.mkdir(dos_to_unix(directory,False),
2034 unix_mode(conn,aDIR,directory));
2038 DEBUG(5,("call_trans2mkdir error (%s)\n", strerror(errno)));
2039 if((errno == ENOENT) && bad_path)
2041 unix_ERR_class = ERRDOS;
2042 unix_ERR_code = ERRbadpath;
2044 return(UNIXERROR(ERRDOS,ERRnoaccess));
2047 /* Realloc the parameter and data sizes */
2048 params = *pparams = Realloc(*pparams,2);
2050 return(ERROR(ERRDOS,ERRnomem));
2054 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
2059 /****************************************************************************
2060 reply to a TRANS2_FINDNOTIFYFIRST (start monitoring a directory for changes)
2061 We don't actually do this - we just send a null response.
2062 ****************************************************************************/
2063 static int call_trans2findnotifyfirst(connection_struct *conn,
2064 char *inbuf, char *outbuf,
2065 int length, int bufsize,
2066 char **pparams, char **ppdata)
2068 static uint16 fnf_handle = 257;
2069 char *params = *pparams;
2070 uint16 info_level = SVAL(params,4);
2072 DEBUG(3,("call_trans2findnotifyfirst - info_level %d\n", info_level));
2080 return(ERROR(ERRDOS,ERRunknownlevel));
2083 /* Realloc the parameter and data sizes */
2084 params = *pparams = Realloc(*pparams,6);
2086 return(ERROR(ERRDOS,ERRnomem));
2088 SSVAL(params,0,fnf_handle);
2089 SSVAL(params,2,0); /* No changes */
2090 SSVAL(params,4,0); /* No EA errors */
2097 send_trans2_replies(outbuf, bufsize, params, 6, *ppdata, 0);
2102 /****************************************************************************
2103 reply to a TRANS2_FINDNOTIFYNEXT (continue monitoring a directory for
2104 changes). Currently this does nothing.
2105 ****************************************************************************/
2106 static int call_trans2findnotifynext(connection_struct *conn,
2107 char *inbuf, char *outbuf,
2108 int length, int bufsize,
2109 char **pparams, char **ppdata)
2111 char *params = *pparams;
2113 DEBUG(3,("call_trans2findnotifynext\n"));
2115 /* Realloc the parameter and data sizes */
2116 params = *pparams = Realloc(*pparams,4);
2118 return(ERROR(ERRDOS,ERRnomem));
2120 SSVAL(params,0,0); /* No changes */
2121 SSVAL(params,2,0); /* No EA errors */
2123 send_trans2_replies(outbuf, bufsize, params, 4, *ppdata, 0);
2128 /****************************************************************************
2129 reply to a TRANS2_GET_DFS_REFERRAL - Shirish Kalele <kalele@veritas.com>
2130 ****************************************************************************/
2131 static int call_trans2getdfsreferral(connection_struct *conn, char* inbuf,
2132 char* outbuf, int length, int bufsize,
2133 char** pparams, char** ppdata)
2135 char *params = *pparams;
2136 enum remote_arch_types ra_type = get_remote_arch();
2137 BOOL NT_arch = ((ra_type == RA_WINNT) || (ra_type == RA_WIN2K));
2140 int max_referral_level = SVAL(params,0);
2143 DEBUG(10,("call_trans2getdfsreferral\n"));
2145 if(!lp_host_msdfs())
2146 return(ERROR(ERRDOS,ERRbadfunc));
2148 /* if pathname is in UNICODE, convert to DOS */
2149 /* NT always sends in UNICODE, may not set UNICODE flag */
2150 if(NT_arch || (SVAL(inbuf,smb_flg2) & FLAGS2_UNICODE_STRINGS))
2152 unistr_to_dos(pathname, ¶ms[2]);
2153 DEBUG(10,("UNICODE referral for %s\n",pathname));
2156 pstrcpy(pathname,¶ms[2]);
2158 if((reply_size = setup_dfs_referral(pathname,max_referral_level,ppdata)) < 0)
2159 return(ERROR(ERRDOS,ERRbadfile));
2161 SSVAL(outbuf,smb_flg2,SVAL(outbuf,smb_flg2) | FLAGS2_UNICODE_STRINGS |
2162 FLAGS2_DFS_PATHNAMES);
2163 send_trans2_replies(outbuf,bufsize,0,0,*ppdata,reply_size);
2169 /****************************************************************************
2170 reply to a SMBfindclose (stop trans2 directory search)
2171 ****************************************************************************/
2172 int reply_findclose(connection_struct *conn,
2173 char *inbuf,char *outbuf,int length,int bufsize)
2176 int dptr_num=SVALS(inbuf,smb_vwv0);
2178 DEBUG(3,("reply_findclose, dptr_num = %d\n", dptr_num));
2180 dptr_close(&dptr_num);
2182 outsize = set_message(outbuf,0,0,True);
2184 DEBUG(3,("SMBfindclose dptr_num = %d\n", dptr_num));
2189 /****************************************************************************
2190 reply to a SMBfindnclose (stop FINDNOTIFYFIRST directory search)
2191 ****************************************************************************/
2192 int reply_findnclose(connection_struct *conn,
2193 char *inbuf,char *outbuf,int length,int bufsize)
2198 dptr_num = SVAL(inbuf,smb_vwv0);
2200 DEBUG(3,("reply_findnclose, dptr_num = %d\n", dptr_num));
2202 /* We never give out valid handles for a
2203 findnotifyfirst - so any dptr_num is ok here.
2206 outsize = set_message(outbuf,0,0,True);
2208 DEBUG(3,("SMB_findnclose dptr_num = %d\n", dptr_num));
2214 /****************************************************************************
2215 reply to a SMBtranss2 - just ignore it!
2216 ****************************************************************************/
2217 int reply_transs2(connection_struct *conn,
2218 char *inbuf,char *outbuf,int length,int bufsize)
2220 DEBUG(4,("Ignoring transs2 of length %d\n",length));
2224 /****************************************************************************
2225 reply to a SMBtrans2
2226 ****************************************************************************/
2227 int reply_trans2(connection_struct *conn,
2228 char *inbuf,char *outbuf,int length,int bufsize)
2231 unsigned int total_params = SVAL(inbuf, smb_tpscnt);
2232 unsigned int total_data =SVAL(inbuf, smb_tdscnt);
2234 unsigned int max_param_reply = SVAL(inbuf, smb_mprcnt);
2235 unsigned int max_data_reply = SVAL(inbuf, smb_mdrcnt);
2236 unsigned int max_setup_fields = SVAL(inbuf, smb_msrcnt);
2237 BOOL close_tid = BITSETW(inbuf+smb_flags,0);
2238 BOOL no_final_response = BITSETW(inbuf+smb_flags,1);
2239 int32 timeout = IVALS(inbuf,smb_timeout);
2241 unsigned int suwcnt = SVAL(inbuf, smb_suwcnt);
2242 unsigned int tran_call = SVAL(inbuf, smb_setup0);
2243 char *params = NULL, *data = NULL;
2244 int num_params, num_params_sofar, num_data, num_data_sofar;
2246 if(global_oplock_break && (tran_call == TRANSACT2_OPEN)) {
2247 /* Queue this open message as we are the process of an
2250 DEBUG(2,("reply_trans2: queueing message trans2open due to being "));
2251 DEBUGADD(2,( "in oplock break state.\n"));
2253 push_oplock_pending_smb_message(inbuf, length);
2257 outsize = set_message(outbuf,0,0,True);
2259 /* All trans2 messages we handle have smb_sucnt == 1 - ensure this
2260 is so as a sanity check */
2262 DEBUG(2,("Invalid smb_sucnt in trans2 call\n"));
2263 return(ERROR(ERRSRV,ERRerror));
2266 /* Allocate the space for the maximum needed parameters and data */
2267 if (total_params > 0)
2268 params = (char *)malloc(total_params);
2270 data = (char *)malloc(total_data);
2272 if ((total_params && !params) || (total_data && !data)) {
2273 DEBUG(2,("Out of memory in reply_trans2\n"));
2278 return(ERROR(ERRDOS,ERRnomem));
2281 /* Copy the param and data bytes sent with this request into
2282 the params buffer */
2283 num_params = num_params_sofar = SVAL(inbuf,smb_pscnt);
2284 num_data = num_data_sofar = SVAL(inbuf, smb_dscnt);
2286 if (num_params > total_params || num_data > total_data)
2287 exit_server("invalid params in reply_trans2");
2290 memcpy( params, smb_base(inbuf) + SVAL(inbuf, smb_psoff), num_params);
2292 memcpy( data, smb_base(inbuf) + SVAL(inbuf, smb_dsoff), num_data);
2294 if(num_data_sofar < total_data || num_params_sofar < total_params) {
2295 /* We need to send an interim response then receive the rest
2296 of the parameter/data bytes */
2297 outsize = set_message(outbuf,0,0,True);
2298 send_smb(Client,outbuf);
2300 while (num_data_sofar < total_data ||
2301 num_params_sofar < total_params) {
2304 ret = receive_next_smb(inbuf,bufsize,SMB_SECONDARY_WAIT);
2307 (CVAL(inbuf, smb_com) != SMBtranss2)) || !ret) {
2308 outsize = set_message(outbuf,0,0,True);
2310 DEBUG(0,("reply_trans2: Invalid secondary trans2 packet\n"));
2312 DEBUG(0,("reply_trans2: %s in getting secondary trans2 response.\n",
2313 (smb_read_error == READ_ERROR) ? "error" : "timeout" ));
2318 return(ERROR(ERRSRV,ERRerror));
2321 /* Revise total_params and total_data in case
2322 they have changed downwards */
2323 total_params = SVAL(inbuf, smb_tpscnt);
2324 total_data = SVAL(inbuf, smb_tdscnt);
2325 num_params_sofar += (num_params = SVAL(inbuf,smb_spscnt));
2326 num_data_sofar += ( num_data = SVAL(inbuf, smb_sdscnt));
2327 if (num_params_sofar > total_params || num_data_sofar > total_data)
2328 exit_server("data overflow in trans2");
2330 memcpy( ¶ms[ SVAL(inbuf, smb_spsdisp)],
2331 smb_base(inbuf) + SVAL(inbuf, smb_spsoff), num_params);
2332 memcpy( &data[SVAL(inbuf, smb_sdsdisp)],
2333 smb_base(inbuf)+ SVAL(inbuf, smb_sdsoff), num_data);
2337 if (Protocol >= PROTOCOL_NT1) {
2338 uint16 flg2 = SVAL(outbuf,smb_flg2);
2339 SSVAL(outbuf,smb_flg2,flg2 | 0x40); /* IS_LONG_NAME */
2342 /* Now we must call the relevant TRANS2 function */
2344 case TRANSACT2_OPEN:
2345 outsize = call_trans2open(conn,
2346 inbuf, outbuf, bufsize,
2350 case TRANSACT2_FINDFIRST:
2351 outsize = call_trans2findfirst(conn, inbuf, outbuf,
2352 bufsize, ¶ms, &data);
2355 case TRANSACT2_FINDNEXT:
2356 outsize = call_trans2findnext(conn, inbuf, outbuf,
2361 case TRANSACT2_QFSINFO:
2362 outsize = call_trans2qfsinfo(conn, inbuf, outbuf,
2363 length, bufsize, ¶ms,
2367 case TRANSACT2_SETFSINFO:
2368 outsize = call_trans2setfsinfo(conn, inbuf, outbuf,
2373 case TRANSACT2_QPATHINFO:
2374 case TRANSACT2_QFILEINFO:
2375 outsize = call_trans2qfilepathinfo(conn, inbuf, outbuf,
2377 ¶ms, &data, total_data);
2379 case TRANSACT2_SETPATHINFO:
2380 case TRANSACT2_SETFILEINFO:
2381 outsize = call_trans2setfilepathinfo(conn, inbuf, outbuf,
2387 case TRANSACT2_FINDNOTIFYFIRST:
2388 outsize = call_trans2findnotifyfirst(conn, inbuf, outbuf,
2393 case TRANSACT2_FINDNOTIFYNEXT:
2394 outsize = call_trans2findnotifynext(conn, inbuf, outbuf,
2398 case TRANSACT2_MKDIR:
2399 outsize = call_trans2mkdir(conn, inbuf, outbuf, length,
2400 bufsize, ¶ms, &data);
2403 case TRANSACT2_GET_DFS_REFERRAL:
2404 outsize = call_trans2getdfsreferral(conn,inbuf,outbuf,length,
2405 bufsize, ¶ms, &data);
2408 /* Error in request */
2409 DEBUG(2,("Unknown request %d in trans2 call\n", tran_call));
2414 return (ERROR(ERRSRV,ERRerror));
2417 /* As we do not know how many data packets will need to be
2418 returned here the various call_trans2xxxx calls
2419 must send their own. Thus a call_trans2xxx routine only
2420 returns a value other than -1 when it wants to send
2428 return outsize; /* If a correct response was needed the
2429 call_trans2xxx calls have already sent
2430 it. If outsize != -1 then it is returning */