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));
222 return(ERROR(ERRSRV,ERRaccess));
225 /* XXXX we need to handle passed times, sattr and flags */
227 unix_convert(fname,conn,0,&bad_path,NULL);
229 if (!check_name(fname,conn))
231 if((errno == ENOENT) && bad_path)
233 unix_ERR_class = ERRDOS;
234 unix_ERR_code = ERRbadpath;
236 return(UNIXERROR(ERRDOS,ERRnoaccess));
239 unixmode = unix_mode(conn,open_attr | aARCH, fname);
241 fsp = open_file_shared(conn,fname,open_mode,open_ofun,unixmode,
242 oplock_request, &rmode,&smb_action);
246 if((errno == ENOENT) && bad_path)
248 unix_ERR_class = ERRDOS;
249 unix_ERR_code = ERRbadpath;
251 return(UNIXERROR(ERRDOS,ERRnoaccess));
254 if (fsp->conn->vfs_ops.fstat(fsp->fd,&sbuf) != 0) {
255 close_file(fsp,False);
256 return(UNIXERROR(ERRDOS,ERRnoaccess));
260 fmode = dos_mode(conn,fname,&sbuf);
261 mtime = sbuf.st_mtime;
264 close_file(fsp,False);
265 return(ERROR(ERRDOS,ERRnoaccess));
268 /* Realloc the size of parameters and data we will return */
269 params = *pparams = Realloc(*pparams, 28);
271 return(ERROR(ERRDOS,ERRnomem));
273 memset((char *)params,'\0',28);
274 SSVAL(params,0,fsp->fnum);
275 SSVAL(params,2,fmode);
276 put_dos_date2(params,4, mtime);
277 SIVAL(params,8, (uint32)size);
278 SSVAL(params,12,rmode);
280 if (oplock_request && lp_fake_oplocks(SNUM(conn))) {
281 smb_action |= EXTENDED_OPLOCK_GRANTED;
284 SSVAL(params,18,smb_action);
286 * WARNING - this may need to be changed if SMB_INO_T <> 4 bytes.
288 SIVAL(params,20,inode);
290 /* Send the required number of replies */
291 send_trans2_replies(outbuf, bufsize, params, 28, *ppdata, 0);
296 /*********************************************************
297 * Routine to check if a given string matches exactly.
298 * as a special case a mask of "." does NOT match. That
299 * is required for correct wildcard semantics
300 * Case can be significant or not.
301 **********************************************************/
302 static BOOL exact_match(char *str,char *mask, BOOL case_sig)
304 if (mask[0] == '.' && mask[1] == 0) return False;
305 if (case_sig) return strcmp(str,mask)==0;
306 return strcasecmp(str,mask) == 0;
309 /****************************************************************************
310 get a level dependent lanman2 dir entry.
311 ****************************************************************************/
312 static BOOL get_lanman2_dir_entry(connection_struct *conn,
313 char *path_mask,int dirtype,int info_level,
314 int requires_resume_key,
315 BOOL dont_descend,char **ppdata,
316 char *base_data, int space_remaining,
317 BOOL *out_of_space, BOOL *got_exact_match,
322 SMB_STRUCT_STAT sbuf;
326 char *p, *pdata = *ppdata;
332 time_t mdate=0, adate=0, cdate=0;
335 int nt_extmode; /* Used for NT connections instead of mode */
336 BOOL needslash = ( conn->dirpath[strlen(conn->dirpath) -1] != '/');
339 *out_of_space = False;
340 *got_exact_match = False;
345 p = strrchr(path_mask,'/');
354 pstrcpy(mask, path_mask);
360 /* Needed if we run out of space */
361 prev_dirpos = TellDir(conn->dirptr);
362 dname = ReadDirName(conn->dirptr);
365 * Due to bugs in NT client redirectors we are not using
366 * resume keys any more - set them to zero.
367 * Check out the related comments in findfirst/findnext.
373 DEBUG(8,("get_lanman2_dir_entry:readdir on dirptr 0x%lx now at offset %d\n",
374 (long)conn->dirptr,TellDir(conn->dirptr)));
379 pstrcpy(fname,dname);
381 if(!(got_match = *got_exact_match = exact_match(fname, mask, case_sensitive)))
382 got_match = mask_match(fname, mask, case_sensitive);
384 if(!got_match && !is_8_3(fname, False)) {
387 * It turns out that NT matches wildcards against
388 * both long *and* short names. This may explain some
389 * of the wildcard wierdness from old DOS clients
390 * that some people have been seeing.... JRA.
394 pstrcpy( newname, fname);
395 name_map_mangle( newname, True, False, SNUM(conn));
396 if(!(got_match = *got_exact_match = exact_match(newname, mask, case_sensitive)))
397 got_match = mask_match(newname, mask, case_sensitive);
402 BOOL isdots = (strequal(fname,"..") || strequal(fname,"."));
403 if (dont_descend && !isdots)
406 pstrcpy(pathreal,conn->dirpath);
408 pstrcat(pathreal,"/");
409 pstrcat(pathreal,dname);
410 if (conn->vfs_ops.stat(dos_to_unix(pathreal,False),&sbuf) != 0)
412 /* Needed to show the msdfs symlinks as directories */
413 if(!lp_host_msdfs() || !lp_msdfs_root(SNUM(conn))
414 || !is_msdfs_link(conn, pathreal))
416 DEBUG(5,("get_lanman2_dir_entry:Couldn't stat [%s] (%s)\n",
417 pathreal,strerror(errno)));
422 DEBUG(5,("get_lanman2_dir_entry: Masquerading msdfs link %s as a directory\n", pathreal));
423 sbuf.st_mode = (sbuf.st_mode & 0xFFF) | S_IFDIR;
427 mode = dos_mode(conn,pathreal,&sbuf);
429 if (!dir_check_ftype(conn,mode,&sbuf,dirtype)) {
430 DEBUG(5,("[%s] attribs didn't match %x\n",fname,dirtype));
435 mdate = sbuf.st_mtime;
436 adate = sbuf.st_atime;
437 cdate = get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(conn)));
441 DEBUG(5,("get_lanman2_dir_entry found %s fname=%s\n",pathreal,fname));
447 name_map_mangle(fname,False,True,SNUM(conn));
452 nt_extmode = mode ? mode : FILE_ATTRIBUTE_NORMAL;
457 if(requires_resume_key) {
461 put_dos_date2(p,l1_fdateCreation,cdate);
462 put_dos_date2(p,l1_fdateLastAccess,adate);
463 put_dos_date2(p,l1_fdateLastWrite,mdate);
464 SIVAL(p,l1_cbFile,(uint32)size);
465 SIVAL(p,l1_cbFileAlloc,SMB_ROUNDUP(size,1024));
466 SSVAL(p,l1_attrFile,mode);
467 SCVAL(p,l1_cchName,strlen(fname));
468 pstrcpy(p + l1_achName, fname);
469 nameptr = p + l1_achName;
470 p += l1_achName + strlen(fname) + 1;
475 if(requires_resume_key) {
479 put_dos_date2(p,l2_fdateCreation,cdate);
480 put_dos_date2(p,l2_fdateLastAccess,adate);
481 put_dos_date2(p,l2_fdateLastWrite,mdate);
482 SIVAL(p,l2_cbFile,(uint32)size);
483 SIVAL(p,l2_cbFileAlloc,SMB_ROUNDUP(size,1024));
484 SSVAL(p,l2_attrFile,mode);
485 SIVAL(p,l2_cbList,0); /* No extended attributes */
486 SCVAL(p,l2_cchName,strlen(fname));
487 pstrcpy(p + l2_achName, fname);
488 nameptr = p + l2_achName;
489 p += l2_achName + strlen(fname) + 1;
494 put_dos_date2(p,4,cdate);
495 put_dos_date2(p,8,adate);
496 put_dos_date2(p,12,mdate);
497 SIVAL(p,16,(uint32)size);
498 SIVAL(p,20,SMB_ROUNDUP(size,1024));
501 CVAL(p,30) = strlen(fname);
502 pstrcpy(p+31, fname);
504 p += 31 + strlen(fname) + 1;
508 if(requires_resume_key) {
512 SIVAL(p,0,33+strlen(fname)+1);
513 put_dos_date2(p,4,cdate);
514 put_dos_date2(p,8,adate);
515 put_dos_date2(p,12,mdate);
516 SIVAL(p,16,(uint32)size);
517 SIVAL(p,20,SMB_ROUNDUP(size,1024));
519 CVAL(p,32) = strlen(fname);
520 pstrcpy(p + 33, fname);
522 p += 33 + strlen(fname) + 1;
525 case SMB_FIND_FILE_BOTH_DIRECTORY_INFO:
526 was_8_3 = is_8_3(fname, True);
527 len = 94+strlen(fname);
528 len = (len + 3) & ~3;
529 SIVAL(p,0,len); p += 4;
530 SIVAL(p,0,reskey); p += 4;
531 put_long_date(p,cdate); p += 8;
532 put_long_date(p,adate); p += 8;
533 put_long_date(p,mdate); p += 8;
534 put_long_date(p,mdate); p += 8;
538 SIVAL(p,0,nt_extmode); p += 4;
539 SIVAL(p,0,strlen(fname)); p += 4;
540 SIVAL(p,0,0); p += 4;
543 name_map_mangle(p+2,True,True,SNUM(conn));
545 SSVAL(p, 0, strlen(p+2));
552 pstrcpy(p,fname); p += strlen(p);
556 case SMB_FIND_FILE_DIRECTORY_INFO:
557 len = 64+strlen(fname);
558 len = (len + 3) & ~3;
559 SIVAL(p,0,len); p += 4;
560 SIVAL(p,0,reskey); p += 4;
561 put_long_date(p,cdate); p += 8;
562 put_long_date(p,adate); p += 8;
563 put_long_date(p,mdate); p += 8;
564 put_long_date(p,mdate); p += 8;
568 SIVAL(p,0,nt_extmode); p += 4;
569 SIVAL(p,0,strlen(fname)); p += 4;
575 case SMB_FIND_FILE_FULL_DIRECTORY_INFO:
576 len = 68+strlen(fname);
577 len = (len + 3) & ~3;
578 SIVAL(p,0,len); p += 4;
579 SIVAL(p,0,reskey); p += 4;
580 put_long_date(p,cdate); p += 8;
581 put_long_date(p,adate); p += 8;
582 put_long_date(p,mdate); p += 8;
583 put_long_date(p,mdate); p += 8;
587 SIVAL(p,0,nt_extmode); p += 4;
588 SIVAL(p,0,strlen(fname)); p += 4;
589 SIVAL(p,0,0); p += 4;
594 case SMB_FIND_FILE_NAMES_INFO:
595 len = 12+strlen(fname);
596 len = (len + 3) & ~3;
597 SIVAL(p,0,len); p += 4;
598 SIVAL(p,0,reskey); p += 4;
599 SIVAL(p,0,strlen(fname)); p += 4;
609 if (PTR_DIFF(p,pdata) > space_remaining) {
610 /* Move the dirptr back to prev_dirpos */
611 SeekDir(conn->dirptr, prev_dirpos);
612 *out_of_space = True;
613 DEBUG(9,("get_lanman2_dir_entry: out of space\n"));
614 return False; /* Not finished - just out of space */
617 /* Setup the last_filename pointer, as an offset from base_data */
618 *last_name_off = PTR_DIFF(nameptr,base_data);
619 /* Advance the data pointer to the next slot */
626 /****************************************************************************
627 Reply to a TRANS2_FINDFIRST.
628 ****************************************************************************/
630 static int call_trans2findfirst(connection_struct *conn,
631 char *inbuf, char *outbuf, int bufsize,
632 char **pparams, char **ppdata)
634 /* We must be careful here that we don't return more than the
635 allowed number of data bytes. If this means returning fewer than
636 maxentries then so be it. We assume that the redirector has
637 enough room for the fixed number of parameter bytes it has
639 uint32 max_data_bytes = SVAL(inbuf, smb_mdrcnt);
640 char *params = *pparams;
641 char *pdata = *ppdata;
642 int dirtype = SVAL(params,0);
643 int maxentries = SVAL(params,2);
644 BOOL close_after_first = BITSETW(params+4,0);
645 BOOL close_if_end = BITSETW(params+4,1);
646 BOOL requires_resume_key = BITSETW(params+4,2);
647 int info_level = SVAL(params,6);
655 BOOL finished = False;
656 BOOL dont_descend = False;
657 BOOL out_of_space = False;
659 BOOL bad_path = False;
661 *directory = *mask = 0;
663 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",
664 dirtype, maxentries, close_after_first, close_if_end, requires_resume_key,
665 info_level, max_data_bytes));
673 case SMB_FIND_FILE_DIRECTORY_INFO:
674 case SMB_FIND_FILE_FULL_DIRECTORY_INFO:
675 case SMB_FIND_FILE_NAMES_INFO:
676 case SMB_FIND_FILE_BOTH_DIRECTORY_INFO:
679 return(ERROR(ERRDOS,ERRunknownlevel));
682 pstrcpy(directory, params + 12); /* Complete directory path with
683 wildcard mask appended */
685 RESOLVE_FINDFIRST_DFSPATH(directory, conn, inbuf, outbuf);
687 DEBUG(5,("path=%s\n",directory));
689 unix_convert(directory,conn,0,&bad_path,NULL);
690 if(!check_name(directory,conn)) {
691 if((errno == ENOENT) && bad_path)
693 unix_ERR_class = ERRDOS;
694 unix_ERR_code = ERRbadpath;
698 /* Ugly - NT specific hack - maybe not needed ? (JRA) */
699 if((errno == ENOTDIR) && (Protocol >= PROTOCOL_NT1) &&
700 (get_remote_arch() == RA_WINNT))
702 unix_ERR_class = ERRDOS;
703 unix_ERR_code = ERRbaddirectory;
707 return(UNIXERROR(ERRDOS,ERRbadpath));
710 p = strrchr(directory,'/');
712 pstrcpy(mask,directory);
713 pstrcpy(directory,"./");
719 DEBUG(5,("dir=%s, mask = %s\n",directory, mask));
721 pdata = *ppdata = Realloc(*ppdata, max_data_bytes + 1024);
723 return(ERROR(ERRDOS,ERRnomem));
724 memset((char *)pdata,'\0',max_data_bytes + 1024);
726 /* Realloc the params space */
727 params = *pparams = Realloc(*pparams, 10);
729 return(ERROR(ERRDOS,ERRnomem));
731 dptr_num = dptr_create(conn,directory, False, True ,SVAL(inbuf,smb_pid));
733 return(UNIXERROR(ERRDOS,ERRbadfile));
735 /* Save the wildcard match and attribs we are using on this directory -
736 needed as lanman2 assumes these are being saved between calls */
738 if(!(wcard = strdup(mask))) {
739 dptr_close(&dptr_num);
740 return(ERROR(ERRDOS,ERRnomem));
743 dptr_set_wcard(dptr_num, wcard);
744 dptr_set_attr(dptr_num, dirtype);
746 DEBUG(4,("dptr_num is %d, wcard = %s, attr = %d\n",dptr_num, wcard, dirtype));
748 /* We don't need to check for VOL here as this is returned by
749 a different TRANS2 call. */
751 DEBUG(8,("dirpath=<%s> dontdescend=<%s>\n",
752 conn->dirpath,lp_dontdescend(SNUM(conn))));
753 if (in_list(conn->dirpath,lp_dontdescend(SNUM(conn)),case_sensitive))
757 space_remaining = max_data_bytes;
758 out_of_space = False;
760 for (i=0;(i<maxentries) && !finished && !out_of_space;i++)
762 BOOL got_exact_match = False;
764 /* this is a heuristic to avoid seeking the dirptr except when
765 absolutely necessary. It allows for a filename of about 40 chars */
766 if (space_remaining < DIRLEN_GUESS && numentries > 0)
773 finished = !get_lanman2_dir_entry(conn,mask,dirtype,info_level,
774 requires_resume_key,dont_descend,
775 &p,pdata,space_remaining, &out_of_space, &got_exact_match,
779 if (finished && out_of_space)
782 if (!finished && !out_of_space)
786 * As an optimisation if we know we aren't looking
787 * for a wildcard name (ie. the name matches the wildcard exactly)
788 * then we can finish on any (first) match.
789 * This speeds up large directory searches. JRA.
795 space_remaining = max_data_bytes - PTR_DIFF(p,pdata);
798 /* Check if we can close the dirptr */
799 if(close_after_first || (finished && close_if_end))
801 DEBUG(5,("call_trans2findfirst - (2) closing dptr_num %d\n", dptr_num));
802 dptr_close(&dptr_num);
806 * If there are no matching entries we must return ERRDOS/ERRbadfile -
807 * from observation of NT.
812 dptr_close(&dptr_num);
813 return(ERROR(ERRDOS,ERRbadfile));
816 /* At this point pdata points to numentries directory entries. */
818 /* Set up the return parameter block */
819 SSVAL(params,0,dptr_num);
820 SSVAL(params,2,numentries);
821 SSVAL(params,4,finished);
822 SSVAL(params,6,0); /* Never an EA error */
823 SSVAL(params,8,last_name_off);
825 send_trans2_replies( outbuf, bufsize, params, 10, pdata, PTR_DIFF(p,pdata));
827 if ((! *directory) && dptr_path(dptr_num))
828 slprintf(directory,sizeof(directory)-1, "(%s)",dptr_path(dptr_num));
830 DEBUG( 4, ( "%s mask=%s directory=%s dirtype=%d numentries=%d\n",
831 smb_fn_name(CVAL(inbuf,smb_com)),
832 mask, directory, dirtype, numentries ) );
835 * Force a name mangle here to ensure that the
836 * mask as an 8.3 name is top of the mangled cache.
837 * The reasons for this are subtle. Don't remove
838 * this code unless you know what you are doing
839 * (see PR#13758). JRA.
842 if(!is_8_3( mask, False))
843 name_map_mangle(mask, True, True, SNUM(conn));
849 /****************************************************************************
850 reply to a TRANS2_FINDNEXT
851 ****************************************************************************/
852 static int call_trans2findnext(connection_struct *conn,
853 char *inbuf, char *outbuf,
854 int length, int bufsize,
855 char **pparams, char **ppdata)
857 /* We must be careful here that we don't return more than the
858 allowed number of data bytes. If this means returning fewer than
859 maxentries then so be it. We assume that the redirector has
860 enough room for the fixed number of parameter bytes it has
862 int max_data_bytes = SVAL(inbuf, smb_mdrcnt);
863 char *params = *pparams;
864 char *pdata = *ppdata;
865 int dptr_num = SVAL(params,0);
866 int maxentries = SVAL(params,2);
867 uint16 info_level = SVAL(params,4);
868 uint32 resume_key = IVAL(params,6);
869 BOOL close_after_request = BITSETW(params+10,0);
870 BOOL close_if_end = BITSETW(params+10,1);
871 BOOL requires_resume_key = BITSETW(params+10,2);
872 BOOL continue_bit = BITSETW(params+10,3);
879 int i, last_name_off=0;
880 BOOL finished = False;
881 BOOL dont_descend = False;
882 BOOL out_of_space = False;
885 *mask = *directory = *resume_name = 0;
887 pstrcpy( resume_name, params+12);
889 DEBUG(3,("call_trans2findnext: dirhandle = %d, max_data_bytes = %d, maxentries = %d, \
890 close_after_request=%d, close_if_end = %d requires_resume_key = %d \
891 resume_key = %d resume name = %s continue=%d level = %d\n",
892 dptr_num, max_data_bytes, maxentries, close_after_request, close_if_end,
893 requires_resume_key, resume_key, resume_name, continue_bit, info_level));
901 case SMB_FIND_FILE_DIRECTORY_INFO:
902 case SMB_FIND_FILE_FULL_DIRECTORY_INFO:
903 case SMB_FIND_FILE_NAMES_INFO:
904 case SMB_FIND_FILE_BOTH_DIRECTORY_INFO:
907 return(ERROR(ERRDOS,ERRunknownlevel));
910 pdata = *ppdata = Realloc( *ppdata, max_data_bytes + 1024);
912 return(ERROR(ERRDOS,ERRnomem));
913 memset((char *)pdata,'\0',max_data_bytes + 1024);
915 /* Realloc the params space */
916 params = *pparams = Realloc(*pparams, 6*SIZEOFWORD);
918 return(ERROR(ERRDOS,ERRnomem));
920 /* Check that the dptr is valid */
921 if(!(conn->dirptr = dptr_fetch_lanman2(dptr_num)))
922 return(ERROR(ERRDOS,ERRnofiles));
924 string_set(&conn->dirpath,dptr_path(dptr_num));
926 /* Get the wildcard mask from the dptr */
927 if((p = dptr_wcard(dptr_num))== NULL) {
928 DEBUG(2,("dptr_num %d has no wildcard\n", dptr_num));
929 return (ERROR(ERRDOS,ERRnofiles));
932 pstrcpy(directory,conn->dirpath);
934 /* Get the attr mask from the dptr */
935 dirtype = dptr_attr(dptr_num);
937 DEBUG(3,("dptr_num is %d, mask = %s, attr = %x, dirptr=(0x%lX,%d)\n",
938 dptr_num, mask, dirtype,
940 TellDir(conn->dirptr)));
942 /* We don't need to check for VOL here as this is returned by
943 a different TRANS2 call. */
945 DEBUG(8,("dirpath=<%s> dontdescend=<%s>\n",conn->dirpath,lp_dontdescend(SNUM(conn))));
946 if (in_list(conn->dirpath,lp_dontdescend(SNUM(conn)),case_sensitive))
950 space_remaining = max_data_bytes;
951 out_of_space = False;
954 * Seek to the correct position. We no longer use the resume key but
955 * depend on the last file name instead.
957 if(requires_resume_key && *resume_name && !continue_bit)
960 * Fix for NT redirector problem triggered by resume key indexes
961 * changing between directory scans. We now return a resume key of 0
962 * and instead look for the filename to continue from (also given
963 * to us by NT/95/smbfs/smbclient). If no other scans have been done between the
964 * findfirst/findnext (as is usual) then the directory pointer
965 * should already be at the correct place. Check this by scanning
966 * backwards looking for an exact (ie. case sensitive) filename match.
967 * If we get to the beginning of the directory and haven't found it then scan
968 * forwards again looking for a match. JRA.
971 int current_pos, start_pos;
973 void *dirptr = conn->dirptr;
974 start_pos = TellDir(dirptr);
975 for(current_pos = start_pos; current_pos >= 0; current_pos--)
977 DEBUG(7,("call_trans2findnext: seeking to pos %d\n", current_pos));
979 SeekDir(dirptr, current_pos);
980 dname = ReadDirName(dirptr);
983 * Remember, name_map_mangle is called by
984 * get_lanman2_dir_entry(), so the resume name
985 * could be mangled. Ensure we do the same
990 name_map_mangle( dname, False, True, SNUM(conn));
992 if(dname && strcsequal( resume_name, dname))
994 SeekDir(dirptr, current_pos+1);
995 DEBUG(7,("call_trans2findnext: got match at pos %d\n", current_pos+1 ));
1001 * Scan forward from start if not found going backwards.
1006 DEBUG(7,("call_trans2findnext: notfound: seeking to pos %d\n", start_pos));
1007 SeekDir(dirptr, start_pos);
1008 for(current_pos = start_pos; (dname = ReadDirName(dirptr)) != NULL; SeekDir(dirptr,++current_pos))
1011 * Remember, name_map_mangle is called by
1012 * get_lanman2_dir_entry(), so the resume name
1013 * could be mangled. Ensure we do the same
1018 name_map_mangle( dname, False, True, SNUM(conn));
1020 if(dname && strcsequal( resume_name, dname))
1022 SeekDir(dirptr, current_pos+1);
1023 DEBUG(7,("call_trans2findnext: got match at pos %d\n", current_pos+1 ));
1027 } /* end if current_pos */
1028 } /* end if requires_resume_key && !continue_bit */
1030 for (i=0;(i<(int)maxentries) && !finished && !out_of_space ;i++)
1032 BOOL got_exact_match = False;
1034 /* this is a heuristic to avoid seeking the dirptr except when
1035 absolutely necessary. It allows for a filename of about 40 chars */
1036 if (space_remaining < DIRLEN_GUESS && numentries > 0)
1038 out_of_space = True;
1043 finished = !get_lanman2_dir_entry(conn,mask,dirtype,info_level,
1044 requires_resume_key,dont_descend,
1045 &p,pdata,space_remaining, &out_of_space, &got_exact_match,
1049 if (finished && out_of_space)
1052 if (!finished && !out_of_space)
1056 * As an optimisation if we know we aren't looking
1057 * for a wildcard name (ie. the name matches the wildcard exactly)
1058 * then we can finish on any (first) match.
1059 * This speeds up large directory searches. JRA.
1065 space_remaining = max_data_bytes - PTR_DIFF(p,pdata);
1068 /* Check if we can close the dirptr */
1069 if(close_after_request || (finished && close_if_end))
1071 DEBUG(5,("call_trans2findnext: closing dptr_num = %d\n", dptr_num));
1072 dptr_close(&dptr_num); /* This frees up the saved mask */
1076 /* Set up the return parameter block */
1077 SSVAL(params,0,numentries);
1078 SSVAL(params,2,finished);
1079 SSVAL(params,4,0); /* Never an EA error */
1080 SSVAL(params,6,last_name_off);
1082 send_trans2_replies( outbuf, bufsize, params, 8, pdata, PTR_DIFF(p,pdata));
1084 if ((! *directory) && dptr_path(dptr_num))
1085 slprintf(directory,sizeof(directory)-1, "(%s)",dptr_path(dptr_num));
1087 DEBUG( 3, ( "%s mask=%s directory=%s dirtype=%d numentries=%d\n",
1088 smb_fn_name(CVAL(inbuf,smb_com)),
1089 mask, directory, dirtype, numentries ) );
1094 /****************************************************************************
1095 reply to a TRANS2_QFSINFO (query filesystem info)
1096 ****************************************************************************/
1098 static int call_trans2qfsinfo(connection_struct *conn,
1099 char *inbuf, char *outbuf,
1100 int length, int bufsize,
1101 char **pparams, char **ppdata)
1103 int max_data_bytes = SVAL(inbuf, smb_mdrcnt);
1104 char *pdata = *ppdata;
1105 char *params = *pparams;
1106 uint16 info_level = SVAL(params,0);
1109 char *vname = volume_label(SNUM(conn));
1110 int snum = SNUM(conn);
1111 char *fstype = lp_fstype(SNUM(conn));
1113 DEBUG(3,("call_trans2qfsinfo: level = %d\n", info_level));
1115 if(conn->vfs_ops.stat(".",&st)!=0) {
1116 DEBUG(2,("call_trans2qfsinfo: stat of . failed (%s)\n", strerror(errno)));
1117 return (ERROR(ERRSRV,ERRinvdevice));
1120 pdata = *ppdata = Realloc(*ppdata, max_data_bytes + 1024);
1121 memset((char *)pdata,'\0',max_data_bytes + 1024);
1127 SMB_BIG_UINT dfree,dsize,bsize;
1129 conn->vfs_ops.disk_free(".",False,&bsize,&dfree,&dsize);
1130 SIVAL(pdata,l1_idFileSystem,st.st_dev);
1131 SIVAL(pdata,l1_cSectorUnit,bsize/512);
1132 SIVAL(pdata,l1_cUnit,dsize);
1133 SIVAL(pdata,l1_cUnitAvail,dfree);
1134 SSVAL(pdata,l1_cbSector,512);
1135 DEBUG(5,("call_trans2qfsinfo : bsize=%u, id=%x, cSectorUnit=%u, cUnit=%u, cUnitAvail=%u, cbSector=%d\n",
1136 (unsigned int)bsize, (unsigned int)st.st_dev, ((unsigned int)bsize)/512, (unsigned int)dsize,
1137 (unsigned int)dfree, 512));
1142 /* Return volume name */
1143 int volname_len = MIN(strlen(vname),11);
1144 data_len = l2_vol_szVolLabel + volname_len + 1;
1146 * Add volume serial number - hash of a combination of
1147 * the called hostname and the service name.
1149 SIVAL(pdata,0,str_checksum(lp_servicename(snum)) ^ (str_checksum(local_machine)<<16) );
1150 SCVAL(pdata,l2_vol_cch,volname_len);
1151 StrnCpy(pdata+l2_vol_szVolLabel,vname,volname_len);
1152 DEBUG(5,("call_trans2qfsinfo : time = %x, namelen = %d, name = %s\n",
1153 (unsigned)st.st_ctime, volname_len,
1154 pdata+l2_vol_szVolLabel));
1157 case SMB_QUERY_FS_ATTRIBUTE_INFO:
1160 SIVAL(pdata,0,FILE_CASE_PRESERVED_NAMES|FILE_CASE_SENSITIVE_SEARCH|
1161 FILE_DEVICE_IS_MOUNTED|
1162 (lp_nt_acl_support() ? FILE_PERSISTENT_ACLS : 0)); /* FS ATTRIBUTES */
1163 #if 0 /* Old code. JRA. */
1164 SIVAL(pdata,0,0x4006); /* FS ATTRIBUTES == long filenames supported? */
1165 #endif /* Old code. */
1167 SIVAL(pdata,4,128); /* Max filename component length */
1168 fstype_len = dos_PutUniCode(pdata+12,unix_to_dos(fstype,False),sizeof(pstring), False);
1169 SIVAL(pdata,8,fstype_len);
1170 data_len = 12 + fstype_len;
1171 SSVAL(outbuf,smb_flg2,SVAL(outbuf,smb_flg2)|FLAGS2_UNICODE_STRINGS);
1174 case SMB_QUERY_FS_LABEL_INFO:
1175 data_len = 4 + strlen(vname);
1176 SIVAL(pdata,0,strlen(vname));
1177 pstrcpy(pdata+4,vname);
1179 case SMB_QUERY_FS_VOLUME_INFO:
1182 * Add volume serial number - hash of a combination of
1183 * the called hostname and the service name.
1185 SIVAL(pdata,8,str_checksum(lp_servicename(snum)) ^
1186 (str_checksum(local_machine)<<16));
1188 /* NT4 always serves this up as unicode but expects it to be
1189 * delivered as ascii! (tridge && JRA)
1191 if ((get_remote_arch() != RA_WIN2K) && (global_client_caps & CAP_NT_SMBS)) {
1192 data_len = 18 + strlen(vname);
1193 SIVAL(pdata,12,strlen(vname));
1194 pstrcpy(pdata+18,vname);
1196 data_len = 18 + 2*strlen(vname);
1197 SIVAL(pdata,12,strlen(vname)*2);
1198 dos_PutUniCode(pdata+18,unix_to_dos(vname,False),sizeof(pstring), False);
1199 SSVAL(outbuf,smb_flg2,SVAL(outbuf,smb_flg2)|FLAGS2_UNICODE_STRINGS);
1202 DEBUG(5,("call_trans2qfsinfo : SMB_QUERY_FS_VOLUME_INFO namelen = %d, vol = %s\n",
1203 (int)strlen(vname),vname));
1205 case SMB_QUERY_FS_SIZE_INFO:
1207 SMB_BIG_UINT dfree,dsize,bsize;
1209 conn->vfs_ops.disk_free(".",False,&bsize,&dfree,&dsize);
1210 SBIG_UINT(pdata,0,dsize);
1211 SBIG_UINT(pdata,8,dfree);
1212 SIVAL(pdata,16,bsize/512);
1213 SIVAL(pdata,20,512);
1216 case SMB_QUERY_FS_DEVICE_INFO:
1218 SIVAL(pdata,0,0); /* dev type */
1219 SIVAL(pdata,4,0); /* characteristics */
1221 case SMB_MAC_QUERY_FS_INFO:
1223 * Thursby MAC extension... ONLY on NTFS filesystems
1224 * once we do streams then we don't need this
1226 if (strequal(lp_fstype(SNUM(conn)),"NTFS")) {
1228 SIVAL(pdata,84,0x100); /* Don't support mac... */
1233 return(ERROR(ERRDOS,ERRunknownlevel));
1237 send_trans2_replies( outbuf, bufsize, params, 0, pdata, data_len);
1239 DEBUG( 4, ( "%s info_level = %d\n",
1240 smb_fn_name(CVAL(inbuf,smb_com)), info_level) );
1245 /****************************************************************************
1246 reply to a TRANS2_SETFSINFO (set filesystem info)
1247 ****************************************************************************/
1248 static int call_trans2setfsinfo(connection_struct *conn,
1249 char *inbuf, char *outbuf, int length,
1251 char **pparams, char **ppdata)
1253 /* Just say yes we did it - there is nothing that
1254 can be set here so it doesn't matter. */
1256 DEBUG(3,("call_trans2setfsinfo\n"));
1258 if (!CAN_WRITE(conn))
1259 return(ERROR(ERRSRV,ERRaccess));
1261 outsize = set_message(outbuf,10,0,True);
1266 /****************************************************************************
1267 Reply to a TRANS2_QFILEPATHINFO or TRANSACT2_QFILEINFO (query file info by
1268 file name or file id).
1269 ****************************************************************************/
1271 static int call_trans2qfilepathinfo(connection_struct *conn,
1272 char *inbuf, char *outbuf, int length,
1274 char **pparams,char **ppdata,
1277 int max_data_bytes = SVAL(inbuf, smb_mdrcnt);
1278 char *params = *pparams;
1279 char *pdata = *ppdata;
1280 uint16 tran_call = SVAL(inbuf, smb_setup0);
1284 unsigned int data_size;
1285 SMB_STRUCT_STAT sbuf;
1291 BOOL bad_path = False;
1292 BOOL delete_pending = False;
1294 if (tran_call == TRANSACT2_QFILEINFO) {
1295 files_struct *fsp = file_fsp(params,0);
1296 info_level = SVAL(params,2);
1298 DEBUG(3,("call_trans2qfilepathinfo: TRANSACT2_QFILEINFO: level = %d\n", info_level));
1300 if(fsp && (fsp->is_directory || fsp->stat_open)) {
1302 * This is actually a QFILEINFO on a directory
1303 * handle (returned from an NT SMB). NT5.0 seems
1304 * to do this call. JRA.
1306 fname = fsp->fsp_name;
1307 unix_convert(fname,conn,0,&bad_path,&sbuf);
1308 if (!check_name(fname,conn) ||
1309 (!VALID_STAT(sbuf) && conn->vfs_ops.stat(dos_to_unix(fname,False),&sbuf))) {
1310 DEBUG(3,("fileinfo of %s failed (%s)\n",fname,strerror(errno)));
1311 if((errno == ENOENT) && bad_path)
1313 unix_ERR_class = ERRDOS;
1314 unix_ERR_code = ERRbadpath;
1316 return(UNIXERROR(ERRDOS,ERRbadpath));
1319 delete_pending = fsp->directory_delete_on_close;
1323 * Original code - this is an open file.
1325 CHECK_FSP(fsp,conn);
1328 fname = fsp->fsp_name;
1329 if (fsp->conn->vfs_ops.fstat(fsp->fd,&sbuf) != 0) {
1330 DEBUG(3,("fstat of fnum %d failed (%s)\n",fsp->fnum, strerror(errno)));
1331 return(UNIXERROR(ERRDOS,ERRbadfid));
1333 if((pos = fsp->conn->vfs_ops.lseek(fsp->fd,0,SEEK_CUR)) == -1)
1334 return(UNIXERROR(ERRDOS,ERRnoaccess));
1336 delete_pending = fsp->delete_on_close;
1340 info_level = SVAL(params,0);
1342 DEBUG(3,("call_trans2qfilepathinfo: TRANSACT2_QPATHINFO: level = %d\n", info_level));
1345 pstrcpy(fname,¶ms[6]);
1347 RESOLVE_DFSPATH(fname, conn, inbuf, outbuf);
1349 unix_convert(fname,conn,0,&bad_path,&sbuf);
1350 if (!check_name(fname,conn) ||
1351 (!VALID_STAT(sbuf) && conn->vfs_ops.stat(dos_to_unix(fname,False),&sbuf))) {
1352 DEBUG(3,("fileinfo of %s failed (%s)\n",fname,strerror(errno)));
1353 if((errno == ENOENT) && bad_path)
1355 unix_ERR_class = ERRDOS;
1356 unix_ERR_code = ERRbadpath;
1358 return(UNIXERROR(ERRDOS,ERRbadpath));
1363 DEBUG(3,("call_trans2qfilepathinfo %s level=%d call=%d total_data=%d\n",
1364 fname,info_level,tran_call,total_data));
1366 p = strrchr(fname,'/');
1372 mode = dos_mode(conn,fname,&sbuf);
1373 size = sbuf.st_size;
1374 if (mode & aDIR) size = 0;
1376 /* from now on we only want the part after the / */
1379 params = *pparams = Realloc(*pparams,2);
1380 memset((char *)params,'\0',2);
1381 data_size = max_data_bytes + 1024;
1382 pdata = *ppdata = Realloc(*ppdata, data_size);
1384 if (total_data > 0 && IVAL(pdata,0) == total_data) {
1385 /* uggh, EAs for OS2 */
1386 DEBUG(4,("Rejecting EA request with total_data=%d\n",total_data));
1387 return(ERROR(ERRDOS,ERROR_EAS_NOT_SUPPORTED));
1390 memset((char *)pdata,'\0',data_size);
1394 case SMB_INFO_STANDARD:
1395 case SMB_INFO_QUERY_EA_SIZE:
1396 data_size = (info_level==1?22:26);
1397 put_dos_date2(pdata,l1_fdateCreation,get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(conn))));
1398 put_dos_date2(pdata,l1_fdateLastAccess,sbuf.st_atime);
1399 put_dos_date2(pdata,l1_fdateLastWrite,sbuf.st_mtime); /* write time */
1400 SIVAL(pdata,l1_cbFile,(uint32)size);
1401 SIVAL(pdata,l1_cbFileAlloc,SMB_ROUNDUP(size,1024));
1402 SSVAL(pdata,l1_attrFile,mode);
1403 SIVAL(pdata,l1_attrFile+2,4); /* this is what OS2 does */
1406 case SMB_INFO_QUERY_EAS_FROM_LIST:
1408 put_dos_date2(pdata,0,get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(conn))));
1409 put_dos_date2(pdata,4,sbuf.st_atime);
1410 put_dos_date2(pdata,8,sbuf.st_mtime);
1411 SIVAL(pdata,12,(uint32)size);
1412 SIVAL(pdata,16,SMB_ROUNDUP(size,1024));
1413 SIVAL(pdata,20,mode);
1416 case SMB_INFO_QUERY_ALL_EAS:
1418 SIVAL(pdata,0,data_size);
1422 return(ERROR(ERRDOS,ERRbadfunc)); /* os/2 needs this */
1424 case SMB_QUERY_FILE_BASIC_INFO:
1425 data_size = 36; /* w95 returns 40 bytes not 36 - why ?. */
1426 put_long_date(pdata,get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(conn))));
1427 put_long_date(pdata+8,sbuf.st_atime);
1428 put_long_date(pdata+16,sbuf.st_mtime); /* write time */
1429 put_long_date(pdata+24,sbuf.st_mtime); /* change time */
1430 SIVAL(pdata,32,mode);
1432 DEBUG(5,("SMB_QFBI - "));
1434 time_t create_time = get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(conn)));
1435 DEBUG(5,("create: %s ", ctime(&create_time)));
1437 DEBUG(5,("access: %s ", ctime(&sbuf.st_atime)));
1438 DEBUG(5,("write: %s ", ctime(&sbuf.st_mtime)));
1439 DEBUG(5,("change: %s ", ctime(&sbuf.st_mtime)));
1440 DEBUG(5,("mode: %x\n", mode));
1444 case SMB_QUERY_FILE_STANDARD_INFO:
1446 SOFF_T(pdata,0,size);
1447 SOFF_T(pdata,8,size);
1448 SIVAL(pdata,16,sbuf.st_nlink);
1450 CVAL(pdata,21) = (mode&aDIR)?1:0;
1453 case SMB_QUERY_FILE_EA_INFO:
1457 /* Get the 8.3 name - used if NT SMB was negotiated. */
1458 case SMB_QUERY_FILE_ALT_NAME_INFO:
1461 pstrcpy(short_name,p);
1462 /* Mangle if not already 8.3 */
1463 if(!is_8_3(short_name, True))
1465 if(!name_map_mangle(short_name,True,True,SNUM(conn)))
1468 strupper(short_name);
1469 l = strlen(short_name);
1470 dos_PutUniCode(pdata + 4, unix_to_dos(short_name,False),sizeof(pstring), False);
1471 data_size = 4 + (2*l);
1476 case SMB_QUERY_FILE_NAME_INFO:
1478 * The first part of this code is essential
1479 * to get security descriptors to work on mapped
1480 * drives. Don't ask how I discovered this unless
1481 * you like hearing about me suffering.... :-). JRA.
1483 if(strequal(".", fname) && (global_client_caps & CAP_UNICODE)) {
1485 SSVAL(outbuf,smb_flg2,SVAL(outbuf,smb_flg2)|FLAGS2_UNICODE_STRINGS);
1486 dos_PutUniCode(pdata + 4, unix_to_dos("\\",False),sizeof(pstring), False);
1488 pstrcpy(pdata+4,fname);
1494 case SMB_QUERY_FILE_ALLOCATION_INFO:
1495 case SMB_QUERY_FILE_END_OF_FILEINFO:
1497 SOFF_T(pdata,0,size);
1500 case SMB_QUERY_FILE_ALL_INFO:
1501 put_long_date(pdata,get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(conn))));
1502 put_long_date(pdata+8,sbuf.st_atime);
1503 put_long_date(pdata+16,sbuf.st_mtime); /* write time */
1504 put_long_date(pdata+24,sbuf.st_mtime); /* change time */
1505 SIVAL(pdata,32,mode);
1507 SOFF_T(pdata,0,size);
1508 SOFF_T(pdata,8,size);
1509 SIVAL(pdata,16,sbuf.st_nlink);
1510 CVAL(pdata,20) = delete_pending;
1511 CVAL(pdata,21) = (mode&aDIR)?1:0;
1513 SINO_T(pdata,0,(SMB_INO_T)sbuf.st_ino);
1514 pdata += 8; /* index number */
1515 pdata += 4; /* EA info */
1517 SIVAL(pdata,0,0xA9);
1519 SIVAL(pdata,0,0xd01BF);
1521 SOFF_T(pdata,0,pos); /* current offset */
1523 SIVAL(pdata,0,mode); /* is this the right sort of mode info? */
1525 pdata += 4; /* alignment */
1527 pstrcpy(pdata+4,fname);
1529 data_size = PTR_DIFF(pdata,(*ppdata));
1533 /* NT4 server just returns "invalid query" to this - if we try to answer
1534 it then NTws gets a BSOD! (tridge) */
1535 case SMB_QUERY_FILE_STREAM_INFO:
1538 SIVAL(pdata,4,size);
1539 SIVAL(pdata,12,size);
1541 pstrcpy(pdata+24,fname);
1546 return(ERROR(ERRDOS,ERRunknownlevel));
1549 send_trans2_replies( outbuf, bufsize, params, 2, *ppdata, data_size);
1554 /****************************************************************************
1555 reply to a TRANS2_SETFILEINFO (set file info by fileid)
1556 ****************************************************************************/
1557 static int call_trans2setfilepathinfo(connection_struct *conn,
1558 char *inbuf, char *outbuf, int length,
1559 int bufsize, char **pparams,
1560 char **ppdata, int total_data)
1562 char *params = *pparams;
1563 char *pdata = *ppdata;
1564 uint16 tran_call = SVAL(inbuf, smb_setup0);
1573 BOOL bad_path = False;
1574 files_struct *fsp = NULL;
1576 if (!CAN_WRITE(conn))
1577 return(ERROR(ERRSRV,ERRaccess));
1579 if (tran_call == TRANSACT2_SETFILEINFO) {
1580 fsp = file_fsp(params,0);
1581 info_level = SVAL(params,2);
1583 if(fsp && (fsp->is_directory || fsp->stat_open)) {
1585 * This is actually a SETFILEINFO on a directory
1586 * handle (returned from an NT SMB). NT5.0 seems
1587 * to do this call. JRA.
1589 fname = fsp->fsp_name;
1590 unix_convert(fname,conn,0,&bad_path,&st);
1591 if (!check_name(fname,conn) ||
1592 (!VALID_STAT(st) && conn->vfs_ops.stat(dos_to_unix(fname,False),&st))) {
1593 DEBUG(3,("fileinfo of %s failed (%s)\n",fname,strerror(errno)));
1594 if((errno == ENOENT) && bad_path)
1596 unix_ERR_class = ERRDOS;
1597 unix_ERR_code = ERRbadpath;
1599 return(UNIXERROR(ERRDOS,ERRbadpath));
1603 * Original code - this is an open file.
1605 CHECK_FSP(fsp,conn);
1608 fname = fsp->fsp_name;
1611 if (fsp->conn->vfs_ops.fstat(fd,&st) != 0) {
1612 DEBUG(3,("fstat of fnum %d failed (%s)\n",fsp->fnum, strerror(errno)));
1613 return(UNIXERROR(ERRDOS,ERRbadfid));
1618 info_level = SVAL(params,0);
1620 pstrcpy(fname,¶ms[6]);
1621 unix_convert(fname,conn,0,&bad_path,&st);
1622 if(!check_name(fname, conn))
1624 if((errno == ENOENT) && bad_path)
1626 unix_ERR_class = ERRDOS;
1627 unix_ERR_code = ERRbadpath;
1629 return(UNIXERROR(ERRDOS,ERRbadpath));
1632 if(!VALID_STAT(st) && conn->vfs_ops.stat(dos_to_unix(fname,False),&st)!=0) {
1633 DEBUG(3,("stat of %s failed (%s)\n", fname, strerror(errno)));
1634 if((errno == ENOENT) && bad_path)
1636 unix_ERR_class = ERRDOS;
1637 unix_ERR_code = ERRbadpath;
1639 return(UNIXERROR(ERRDOS,ERRbadpath));
1643 DEBUG(3,("call_trans2setfilepathinfo(%d) %s info_level=%d totdata=%d\n",
1644 tran_call,fname,info_level,total_data));
1646 /* Realloc the parameter and data sizes */
1647 params = *pparams = Realloc(*pparams,2);
1649 return(ERROR(ERRDOS,ERRnomem));
1654 tvs.modtime = st.st_mtime;
1655 tvs.actime = st.st_atime;
1656 mode = dos_mode(conn,fname,&st);
1658 if (total_data > 0 && IVAL(pdata,0) == total_data) {
1659 /* uggh, EAs for OS2 */
1660 DEBUG(4,("Rejecting EA request with total_data=%d\n",total_data));
1661 return(ERROR(ERRDOS,ERROR_EAS_NOT_SUPPORTED));
1666 case SMB_INFO_STANDARD:
1667 case SMB_INFO_QUERY_EA_SIZE:
1670 tvs.actime = make_unix_date2(pdata+l1_fdateLastAccess);
1673 tvs.modtime = make_unix_date2(pdata+l1_fdateLastWrite);
1675 mode = SVAL(pdata,l1_attrFile);
1676 size = IVAL(pdata,l1_cbFile);
1680 /* XXXX um, i don't think this is right.
1681 it's also not in the cifs6.txt spec.
1683 case SMB_INFO_QUERY_EAS_FROM_LIST:
1684 tvs.actime = make_unix_date2(pdata+8);
1685 tvs.modtime = make_unix_date2(pdata+12);
1686 size = IVAL(pdata,16);
1687 mode = IVAL(pdata,24);
1690 /* XXXX nor this. not in cifs6.txt, either. */
1691 case SMB_INFO_QUERY_ALL_EAS:
1692 tvs.actime = make_unix_date2(pdata+8);
1693 tvs.modtime = make_unix_date2(pdata+12);
1694 size = IVAL(pdata,16);
1695 mode = IVAL(pdata,24);
1698 case SMB_SET_FILE_BASIC_INFO:
1700 /* Patch to do this correctly from Paul Eggert <eggert@twinsun.com>. */
1702 time_t changed_time;
1704 /* Ignore create time at offset pdata. */
1707 tvs.actime = interpret_long_date(pdata+8);
1709 write_time = interpret_long_date(pdata+16);
1710 changed_time = interpret_long_date(pdata+24);
1712 tvs.modtime = MIN(write_time, changed_time);
1714 /* Prefer a defined time to an undefined one. */
1715 if (tvs.modtime == (time_t)0 || tvs.modtime == (time_t)-1)
1716 tvs.modtime = (write_time == (time_t)0 || write_time == (time_t)-1
1720 #if 0 /* Needs more testing... */
1721 /* Test from Luke to prevent Win95 from
1722 setting incorrect values here.
1724 if (tvs.actime < tvs.modtime)
1725 return(ERROR(ERRDOS,ERRnoaccess));
1726 #endif /* Needs more testing... */
1729 mode = IVAL(pdata,32);
1734 * NT seems to use this call with a size of zero
1735 * to mean truncate the file. JRA.
1738 case SMB_SET_FILE_ALLOCATION_INFO:
1740 SMB_OFF_T newsize = IVAL(pdata,0);
1741 #ifdef LARGE_SMB_OFF_T
1742 newsize |= (((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 file allocation info for file %s to %.0f\n", fname, (double)newsize ));
1753 case SMB_SET_FILE_END_OF_FILE_INFO:
1755 size = IVAL(pdata,0);
1756 #ifdef LARGE_SMB_OFF_T
1757 size |= (((SMB_OFF_T)IVAL(pdata,4)) << 32);
1758 #else /* LARGE_SMB_OFF_T */
1759 if (IVAL(pdata,4) != 0) /* more than 32 bits? */
1760 return(ERROR(ERRDOS,ERRunknownlevel));
1761 #endif /* LARGE_SMB_OFF_T */
1762 DEBUG(10,("call_trans2setfilepathinfo: Set end of file info for file %s to %.0f\n", fname, (double)size ));
1766 case SMB_SET_FILE_DISPOSITION_INFO: /* Set delete on close for open file. */
1768 if ((tran_call == TRANSACT2_SETFILEINFO) && (fsp != NULL))
1770 BOOL delete_on_close = (CVAL(pdata,0) ? True : False);
1772 if(fsp->is_directory)
1774 fsp->directory_delete_on_close = delete_on_close;
1775 DEBUG(10, ("call_trans2setfilepathinfo: %s delete on close flag for fnum = %d, directory %s\n",
1776 delete_on_close ? "Added" : "Removed", fsp->fnum, fsp->fsp_name ));
1779 else if(fsp->stat_open)
1781 DEBUG(10, ("call_trans2setfilepathinfo: %s delete on close flag for fnum = %d, stat open %s\n",
1782 delete_on_close ? "Added" : "Removed", fsp->fnum, fsp->fsp_name ));
1788 * We can only set the delete on close flag if
1789 * the share mode contained ALLOW_SHARE_DELETE
1792 if(!GET_ALLOW_SHARE_DELETE(fsp->share_mode))
1793 return(ERROR(ERRDOS,ERRnoaccess));
1796 * If the flag has been set then
1797 * modify the share mode entry for all files we have open
1798 * on this device and inode to tell other smbds we have
1799 * changed the delete on close flag.
1802 if(delete_on_close && !GET_DELETE_ON_CLOSE_FLAG(fsp->share_mode))
1805 files_struct *iterate_fsp;
1806 SMB_DEV_T dev = fsp->dev;
1807 SMB_INO_T inode = fsp->inode;
1808 int num_share_modes;
1809 share_mode_entry *current_shares = NULL;
1811 if (lock_share_entry_fsp(fsp) == False)
1812 return(ERROR(ERRDOS,ERRnoaccess));
1815 * Before we allow this we need to ensure that all current opens
1816 * on the file have the GET_ALLOW_SHARE_DELETE flag set. If they
1817 * do not then we deny this (as we are essentially deleting the
1818 * file at this point.
1821 num_share_modes = get_share_modes(conn, dev, inode, ¤t_shares);
1822 for(i = 0; i < num_share_modes; i++)
1824 if(!GET_ALLOW_SHARE_DELETE(current_shares[i].share_mode))
1826 DEBUG(5,("call_trans2setfilepathinfo: refusing to set delete on close flag for fnum = %d, \
1827 file %s as a share exists that was not opened with FILE_DELETE access.\n",
1828 fsp->fnum, fsp->fsp_name ));
1833 unlock_share_entry_fsp(fsp);
1836 * current_shares was malloced by get_share_modes - free it here.
1839 free((char *)current_shares);
1842 * Even though share violation would be more appropriate here,
1843 * return ERRnoaccess as that's what NT does.
1846 return(ERROR(ERRDOS,ERRnoaccess));
1851 * current_shares was malloced by get_share_modes - free it here.
1854 free((char *)current_shares);
1856 DEBUG(10,("call_trans2setfilepathinfo: %s delete on close flag for fnum = %d, file %s\n",
1857 delete_on_close ? "Adding" : "Removing", fsp->fnum, fsp->fsp_name ));
1860 * Go through all files we have open on the same device and
1861 * inode (hanging off the same hash bucket) and set the DELETE_ON_CLOSE_FLAG.
1862 * Other smbd's that have this file open will have to fend for themselves. We
1863 * take care of this (rare) case in close_file(). See the comment there.
1866 for(iterate_fsp = file_find_di_first(dev, inode); iterate_fsp;
1867 iterate_fsp = file_find_di_next(iterate_fsp))
1869 int new_share_mode = (delete_on_close ?
1870 (iterate_fsp->share_mode | DELETE_ON_CLOSE_FLAG) :
1871 (iterate_fsp->share_mode & ~DELETE_ON_CLOSE_FLAG) );
1873 DEBUG(10,("call_trans2setfilepathinfo: Changing share mode for fnum %d, file %s \
1874 dev = %x, inode = %.0f from %x to %x\n",
1875 iterate_fsp->fnum, iterate_fsp->fsp_name, (unsigned int)dev,
1876 (double)inode, iterate_fsp->share_mode, new_share_mode ));
1878 if(modify_share_mode(iterate_fsp, new_share_mode, iterate_fsp->oplock_type)==False)
1879 DEBUG(0,("call_trans2setfilepathinfo: failed to change delete on close for fnum %d, \
1880 dev = %x, inode = %.0f\n", iterate_fsp->fnum, (unsigned int)dev, (double)inode));
1884 * Set the delete on close flag in the reference
1885 * counted struct. Delete when the last reference
1888 fsp->delete_on_close = delete_on_close;
1890 unlock_share_entry_fsp(fsp);
1892 DEBUG(10, ("call_trans2setfilepathinfo: %s delete on close flag for fnum = %d, file %s\n",
1893 delete_on_close ? "Added" : "Removed", fsp->fnum, fsp->fsp_name ));
1895 } /* end if(delete_on_close && !GET_DELETE_ON_CLOSE_FLAG(fsp->share_mode)) */
1896 } /* end if is_directory. */
1898 return(ERROR(ERRDOS,ERRunknownlevel));
1904 return(ERROR(ERRDOS,ERRunknownlevel));
1908 /* get some defaults (no modifications) if any info is zero or -1. */
1909 if (tvs.actime == (time_t)0 || tvs.actime == (time_t)-1)
1910 tvs.actime = st.st_atime;
1912 if (tvs.modtime == (time_t)0 || tvs.modtime == (time_t)-1)
1913 tvs.modtime = st.st_mtime;
1915 DEBUG(6,("actime: %s " , ctime(&tvs.actime)));
1916 DEBUG(6,("modtime: %s ", ctime(&tvs.modtime)));
1917 DEBUG(6,("size: %.0f ", (double)size));
1918 DEBUG(6,("mode: %x\n" , mode));
1920 if(!((info_level == SMB_SET_FILE_END_OF_FILE_INFO) ||
1921 (info_level == SMB_SET_FILE_ALLOCATION_INFO))) {
1923 * Only do this test if we are not explicitly
1924 * changing the size of a file.
1930 /* Try and set the times, size and mode of this file -
1931 if they are different from the current values
1933 if (st.st_mtime != tvs.modtime || st.st_atime != tvs.actime) {
1936 * This was a setfileinfo on an open file.
1937 * NT does this a lot. It's actually pointless
1938 * setting the time here, as it will be overwritten
1939 * on the next write, so we save the request
1940 * away and will set it on file code. JRA.
1943 if (tvs.modtime != (time_t)0 && tvs.modtime != (time_t)-1) {
1944 DEBUG(10,("call_trans2setfilepathinfo: setting pending modtime to %s\n",
1945 ctime(&tvs.modtime) ));
1946 fsp->pending_modtime = tvs.modtime;
1951 DEBUG(10,("call_trans2setfilepathinfo: setting utimes to modified values.\n"));
1953 if(file_utime(conn, fname, &tvs)!=0)
1954 return(UNIXERROR(ERRDOS,ERRnoaccess));
1958 /* check the mode isn't different, before changing it */
1959 if ((mode != 0) && (mode != dos_mode(conn, fname, &st))) {
1961 DEBUG(10,("call_trans2setfilepathinfo: file %s : setting dos mode %x\n",
1964 if(file_chmod(conn, fname, mode, NULL)) {
1965 DEBUG(2,("chmod of %s failed (%s)\n", fname, strerror(errno)));
1966 return(UNIXERROR(ERRDOS,ERRnoaccess));
1970 if(size != st.st_size) {
1972 DEBUG(10,("call_trans2setfilepathinfo: file %s : setting new size to %.0f\n",
1973 fname, (double)size ));
1976 fd = conn->vfs_ops.open(dos_to_unix(fname,False),O_RDWR,0);
1978 return(UNIXERROR(ERRDOS,ERRbadpath));
1979 set_filelen(fd, size); /* tpot vfs */
1980 conn->vfs_ops.close(fd);
1982 set_filelen(fd, size); /* tpot vfs */
1986 set_filelen_write_cache(fsp, size);
1991 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
1996 /****************************************************************************
1997 reply to a TRANS2_MKDIR (make directory with extended attributes).
1998 ****************************************************************************/
1999 static int call_trans2mkdir(connection_struct *conn,
2000 char *inbuf, char *outbuf, int length, int bufsize,
2001 char **pparams, char **ppdata)
2003 char *params = *pparams;
2006 BOOL bad_path = False;
2008 if (!CAN_WRITE(conn))
2009 return(ERROR(ERRSRV,ERRaccess));
2011 pstrcpy(directory, ¶ms[4]);
2013 DEBUG(3,("call_trans2mkdir : name = %s\n", directory));
2015 unix_convert(directory,conn,0,&bad_path,NULL);
2016 if (check_name(directory,conn))
2017 ret = vfs_mkdir(conn,directory,unix_mode(conn,aDIR,directory));
2021 DEBUG(5,("call_trans2mkdir error (%s)\n", strerror(errno)));
2022 if((errno == ENOENT) && bad_path)
2024 unix_ERR_class = ERRDOS;
2025 unix_ERR_code = ERRbadpath;
2027 return(UNIXERROR(ERRDOS,ERRnoaccess));
2030 /* Realloc the parameter and data sizes */
2031 params = *pparams = Realloc(*pparams,2);
2033 return(ERROR(ERRDOS,ERRnomem));
2037 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
2042 /****************************************************************************
2043 reply to a TRANS2_FINDNOTIFYFIRST (start monitoring a directory for changes)
2044 We don't actually do this - we just send a null response.
2045 ****************************************************************************/
2046 static int call_trans2findnotifyfirst(connection_struct *conn,
2047 char *inbuf, char *outbuf,
2048 int length, int bufsize,
2049 char **pparams, char **ppdata)
2051 static uint16 fnf_handle = 257;
2052 char *params = *pparams;
2053 uint16 info_level = SVAL(params,4);
2055 DEBUG(3,("call_trans2findnotifyfirst - info_level %d\n", info_level));
2063 return(ERROR(ERRDOS,ERRunknownlevel));
2066 /* Realloc the parameter and data sizes */
2067 params = *pparams = Realloc(*pparams,6);
2069 return(ERROR(ERRDOS,ERRnomem));
2071 SSVAL(params,0,fnf_handle);
2072 SSVAL(params,2,0); /* No changes */
2073 SSVAL(params,4,0); /* No EA errors */
2080 send_trans2_replies(outbuf, bufsize, params, 6, *ppdata, 0);
2085 /****************************************************************************
2086 reply to a TRANS2_FINDNOTIFYNEXT (continue monitoring a directory for
2087 changes). Currently this does nothing.
2088 ****************************************************************************/
2089 static int call_trans2findnotifynext(connection_struct *conn,
2090 char *inbuf, char *outbuf,
2091 int length, int bufsize,
2092 char **pparams, char **ppdata)
2094 char *params = *pparams;
2096 DEBUG(3,("call_trans2findnotifynext\n"));
2098 /* Realloc the parameter and data sizes */
2099 params = *pparams = Realloc(*pparams,4);
2101 return(ERROR(ERRDOS,ERRnomem));
2103 SSVAL(params,0,0); /* No changes */
2104 SSVAL(params,2,0); /* No EA errors */
2106 send_trans2_replies(outbuf, bufsize, params, 4, *ppdata, 0);
2111 /****************************************************************************
2112 reply to a TRANS2_GET_DFS_REFERRAL - Shirish Kalele <kalele@veritas.com>
2113 ****************************************************************************/
2114 static int call_trans2getdfsreferral(connection_struct *conn, char* inbuf,
2115 char* outbuf, int length, int bufsize,
2116 char** pparams, char** ppdata)
2118 char *params = *pparams;
2119 enum remote_arch_types ra_type = get_remote_arch();
2120 BOOL NT_arch = ((ra_type == RA_WINNT) || (ra_type == RA_WIN2K));
2123 int max_referral_level = SVAL(params,0);
2126 DEBUG(10,("call_trans2getdfsreferral\n"));
2128 if(!lp_host_msdfs())
2129 return(ERROR(ERRDOS,ERRbadfunc));
2131 /* if pathname is in UNICODE, convert to DOS */
2132 /* NT always sends in UNICODE, may not set UNICODE flag */
2133 if(NT_arch || (SVAL(inbuf,smb_flg2) & FLAGS2_UNICODE_STRINGS))
2135 unistr_to_dos(pathname, ¶ms[2], sizeof(pathname));
2136 DEBUG(10,("UNICODE referral for %s\n",pathname));
2139 pstrcpy(pathname,¶ms[2]);
2141 if((reply_size = setup_dfs_referral(pathname,max_referral_level,ppdata)) < 0)
2142 return(ERROR(ERRDOS,ERRbadfile));
2144 SSVAL(outbuf,smb_flg2,SVAL(outbuf,smb_flg2) | FLAGS2_UNICODE_STRINGS |
2145 FLAGS2_DFS_PATHNAMES);
2146 send_trans2_replies(outbuf,bufsize,0,0,*ppdata,reply_size);
2152 /****************************************************************************
2153 reply to a SMBfindclose (stop trans2 directory search)
2154 ****************************************************************************/
2155 int reply_findclose(connection_struct *conn,
2156 char *inbuf,char *outbuf,int length,int bufsize)
2159 int dptr_num=SVALS(inbuf,smb_vwv0);
2161 DEBUG(3,("reply_findclose, dptr_num = %d\n", dptr_num));
2163 dptr_close(&dptr_num);
2165 outsize = set_message(outbuf,0,0,True);
2167 DEBUG(3,("SMBfindclose dptr_num = %d\n", dptr_num));
2172 /****************************************************************************
2173 reply to a SMBfindnclose (stop FINDNOTIFYFIRST directory search)
2174 ****************************************************************************/
2175 int reply_findnclose(connection_struct *conn,
2176 char *inbuf,char *outbuf,int length,int bufsize)
2181 dptr_num = SVAL(inbuf,smb_vwv0);
2183 DEBUG(3,("reply_findnclose, dptr_num = %d\n", dptr_num));
2185 /* We never give out valid handles for a
2186 findnotifyfirst - so any dptr_num is ok here.
2189 outsize = set_message(outbuf,0,0,True);
2191 DEBUG(3,("SMB_findnclose dptr_num = %d\n", dptr_num));
2197 /****************************************************************************
2198 reply to a SMBtranss2 - just ignore it!
2199 ****************************************************************************/
2200 int reply_transs2(connection_struct *conn,
2201 char *inbuf,char *outbuf,int length,int bufsize)
2203 DEBUG(4,("Ignoring transs2 of length %d\n",length));
2207 /****************************************************************************
2208 reply to a SMBtrans2
2209 ****************************************************************************/
2210 int reply_trans2(connection_struct *conn,
2211 char *inbuf,char *outbuf,int length,int bufsize)
2214 unsigned int total_params = SVAL(inbuf, smb_tpscnt);
2215 unsigned int total_data =SVAL(inbuf, smb_tdscnt);
2217 unsigned int max_param_reply = SVAL(inbuf, smb_mprcnt);
2218 unsigned int max_data_reply = SVAL(inbuf, smb_mdrcnt);
2219 unsigned int max_setup_fields = SVAL(inbuf, smb_msrcnt);
2220 BOOL close_tid = BITSETW(inbuf+smb_flags,0);
2221 BOOL no_final_response = BITSETW(inbuf+smb_flags,1);
2222 int32 timeout = IVALS(inbuf,smb_timeout);
2224 unsigned int suwcnt = SVAL(inbuf, smb_suwcnt);
2225 unsigned int tran_call = SVAL(inbuf, smb_setup0);
2226 char *params = NULL, *data = NULL;
2227 int num_params, num_params_sofar, num_data, num_data_sofar;
2229 if(global_oplock_break && (tran_call == TRANSACT2_OPEN)) {
2230 /* Queue this open message as we are the process of an
2233 DEBUG(2,("reply_trans2: queueing message trans2open due to being "));
2234 DEBUGADD(2,( "in oplock break state.\n"));
2236 push_oplock_pending_smb_message(inbuf, length);
2240 if (IS_IPC(conn) && (tran_call != TRANSACT2_OPEN)
2241 && (tran_call != TRANSACT2_GET_DFS_REFERRAL))
2242 return(ERROR(ERRSRV,ERRaccess));
2244 outsize = set_message(outbuf,0,0,True);
2246 /* All trans2 messages we handle have smb_sucnt == 1 - ensure this
2247 is so as a sanity check */
2249 DEBUG(2,("Invalid smb_sucnt in trans2 call\n"));
2250 return(ERROR(ERRSRV,ERRerror));
2253 /* Allocate the space for the maximum needed parameters and data */
2254 if (total_params > 0)
2255 params = (char *)malloc(total_params);
2257 data = (char *)malloc(total_data);
2259 if ((total_params && !params) || (total_data && !data)) {
2260 DEBUG(2,("Out of memory in reply_trans2\n"));
2265 return(ERROR(ERRDOS,ERRnomem));
2268 /* Copy the param and data bytes sent with this request into
2269 the params buffer */
2270 num_params = num_params_sofar = SVAL(inbuf,smb_pscnt);
2271 num_data = num_data_sofar = SVAL(inbuf, smb_dscnt);
2273 if (num_params > total_params || num_data > total_data)
2274 exit_server("invalid params in reply_trans2");
2277 memcpy( params, smb_base(inbuf) + SVAL(inbuf, smb_psoff), num_params);
2279 memcpy( data, smb_base(inbuf) + SVAL(inbuf, smb_dsoff), num_data);
2281 if(num_data_sofar < total_data || num_params_sofar < total_params) {
2282 /* We need to send an interim response then receive the rest
2283 of the parameter/data bytes */
2284 outsize = set_message(outbuf,0,0,True);
2285 send_smb(smbd_server_fd(),outbuf);
2287 while (num_data_sofar < total_data ||
2288 num_params_sofar < total_params) {
2291 ret = receive_next_smb(inbuf,bufsize,SMB_SECONDARY_WAIT);
2294 (CVAL(inbuf, smb_com) != SMBtranss2)) || !ret) {
2295 outsize = set_message(outbuf,0,0,True);
2297 DEBUG(0,("reply_trans2: Invalid secondary trans2 packet\n"));
2299 DEBUG(0,("reply_trans2: %s in getting secondary trans2 response.\n",
2300 (smb_read_error == READ_ERROR) ? "error" : "timeout" ));
2305 return(ERROR(ERRSRV,ERRerror));
2308 /* Revise total_params and total_data in case
2309 they have changed downwards */
2310 total_params = SVAL(inbuf, smb_tpscnt);
2311 total_data = SVAL(inbuf, smb_tdscnt);
2312 num_params_sofar += (num_params = SVAL(inbuf,smb_spscnt));
2313 num_data_sofar += ( num_data = SVAL(inbuf, smb_sdscnt));
2314 if (num_params_sofar > total_params || num_data_sofar > total_data)
2315 exit_server("data overflow in trans2");
2317 memcpy( ¶ms[ SVAL(inbuf, smb_spsdisp)],
2318 smb_base(inbuf) + SVAL(inbuf, smb_spsoff), num_params);
2319 memcpy( &data[SVAL(inbuf, smb_sdsdisp)],
2320 smb_base(inbuf)+ SVAL(inbuf, smb_sdsoff), num_data);
2324 if (Protocol >= PROTOCOL_NT1) {
2325 uint16 flg2 = SVAL(outbuf,smb_flg2);
2326 SSVAL(outbuf,smb_flg2,flg2 | 0x40); /* IS_LONG_NAME */
2329 /* Now we must call the relevant TRANS2 function */
2331 case TRANSACT2_OPEN:
2332 outsize = call_trans2open(conn,
2333 inbuf, outbuf, bufsize,
2337 case TRANSACT2_FINDFIRST:
2338 outsize = call_trans2findfirst(conn, inbuf, outbuf,
2339 bufsize, ¶ms, &data);
2342 case TRANSACT2_FINDNEXT:
2343 outsize = call_trans2findnext(conn, inbuf, outbuf,
2348 case TRANSACT2_QFSINFO:
2349 outsize = call_trans2qfsinfo(conn, inbuf, outbuf,
2350 length, bufsize, ¶ms,
2354 case TRANSACT2_SETFSINFO:
2355 outsize = call_trans2setfsinfo(conn, inbuf, outbuf,
2360 case TRANSACT2_QPATHINFO:
2361 case TRANSACT2_QFILEINFO:
2362 outsize = call_trans2qfilepathinfo(conn, inbuf, outbuf,
2364 ¶ms, &data, total_data);
2366 case TRANSACT2_SETPATHINFO:
2367 case TRANSACT2_SETFILEINFO:
2368 outsize = call_trans2setfilepathinfo(conn, inbuf, outbuf,
2374 case TRANSACT2_FINDNOTIFYFIRST:
2375 outsize = call_trans2findnotifyfirst(conn, inbuf, outbuf,
2380 case TRANSACT2_FINDNOTIFYNEXT:
2381 outsize = call_trans2findnotifynext(conn, inbuf, outbuf,
2385 case TRANSACT2_MKDIR:
2386 outsize = call_trans2mkdir(conn, inbuf, outbuf, length,
2387 bufsize, ¶ms, &data);
2390 case TRANSACT2_GET_DFS_REFERRAL:
2391 outsize = call_trans2getdfsreferral(conn,inbuf,outbuf,length,
2392 bufsize, ¶ms, &data);
2395 /* Error in request */
2396 DEBUG(2,("Unknown request %d in trans2 call\n", tran_call));
2401 return (ERROR(ERRSRV,ERRerror));
2404 /* As we do not know how many data packets will need to be
2405 returned here the various call_trans2xxxx calls
2406 must send their own. Thus a call_trans2xxx routine only
2407 returns a value other than -1 when it wants to send
2415 return outsize; /* If a correct response was needed the
2416 call_trans2xxx calls have already sent
2417 it. If outsize != -1 then it is returning */