4 Unix SMB/Netbios implementation.
6 SMB transaction2 handling
7 Copyright (C) Jeremy Allison 1994-1998
9 Extensively modified by Andrew Tridgell, 1995
11 This program is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation; either version 2 of the License, or
14 (at your option) any later version.
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU General Public License for more details.
21 You should have received a copy of the GNU General Public License
22 along with this program; if not, write to the Free Software
23 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
28 extern int DEBUGLEVEL;
30 extern BOOL case_sensitive;
31 extern int smb_read_error;
32 extern fstring local_machine;
33 extern int global_oplock_break;
34 extern uint32 global_client_caps;
36 /****************************************************************************
37 Send the required number of replies back.
38 We assume all fields other than the data fields are
39 set correctly for the type of call.
40 HACK ! Always assumes smb_setup field is zero.
41 ****************************************************************************/
42 static int send_trans2_replies(char *outbuf, int bufsize, char *params,
43 int paramsize, char *pdata, int datasize)
45 /* As we are using a protocol > LANMAN1 then the max_send
46 variable must have been set in the sessetupX call.
47 This takes precedence over the max_xmit field in the
48 global struct. These different max_xmit variables should
49 be merged as this is now too confusing */
52 int data_to_send = datasize;
53 int params_to_send = paramsize;
57 int params_sent_thistime, data_sent_thistime, total_sent_thistime;
58 int alignment_offset = 3;
59 int data_alignment_offset = 0;
61 /* Initially set the wcnt area to be 10 - this is true for all
63 set_message(outbuf,10,0,True);
65 /* If there genuinely are no parameters or data to send just send
67 if(params_to_send == 0 && data_to_send == 0)
69 send_smb(smbd_server_fd(),outbuf);
73 /* When sending params and data ensure that both are nicely aligned */
74 /* Only do this alignment when there is also data to send - else
75 can cause NT redirector problems. */
76 if (((params_to_send % 4) != 0) && (data_to_send != 0))
77 data_alignment_offset = 4 - (params_to_send % 4);
79 /* Space is bufsize minus Netbios over TCP header minus SMB header */
80 /* The alignment_offset is to align the param bytes on an even byte
81 boundary. NT 4.0 Beta needs this to work correctly. */
82 useable_space = bufsize - ((smb_buf(outbuf)+
83 alignment_offset+data_alignment_offset) -
86 /* useable_space can never be more than max_send minus the
88 useable_space = MIN(useable_space,
89 max_send - (alignment_offset+data_alignment_offset));
92 while (params_to_send || data_to_send)
94 /* Calculate whether we will totally or partially fill this packet */
95 total_sent_thistime = params_to_send + data_to_send +
96 alignment_offset + data_alignment_offset;
97 /* We can never send more than useable_space */
99 * Note that 'useable_space' does not include the alignment offsets,
100 * but we must include the alignment offsets in the calculation of
101 * the length of the data we send over the wire, as the alignment offsets
102 * are sent here. Fix from Marc_Jacobsen@hp.com.
104 total_sent_thistime = MIN(total_sent_thistime, useable_space+
105 alignment_offset + data_alignment_offset);
107 set_message(outbuf, 10, total_sent_thistime, True);
109 /* Set total params and data to be sent */
110 SSVAL(outbuf,smb_tprcnt,paramsize);
111 SSVAL(outbuf,smb_tdrcnt,datasize);
113 /* Calculate how many parameters and data we can fit into
114 this packet. Parameters get precedence */
116 params_sent_thistime = MIN(params_to_send,useable_space);
117 data_sent_thistime = useable_space - params_sent_thistime;
118 data_sent_thistime = MIN(data_sent_thistime,data_to_send);
120 SSVAL(outbuf,smb_prcnt, params_sent_thistime);
122 /* smb_proff is the offset from the start of the SMB header to the
123 parameter bytes, however the first 4 bytes of outbuf are
124 the Netbios over TCP header. Thus use smb_base() to subtract
125 them from the calculation */
127 SSVAL(outbuf,smb_proff,((smb_buf(outbuf)+alignment_offset) - smb_base(outbuf)));
129 if(params_sent_thistime == 0)
130 SSVAL(outbuf,smb_prdisp,0);
132 /* Absolute displacement of param bytes sent in this packet */
133 SSVAL(outbuf,smb_prdisp,pp - params);
135 SSVAL(outbuf,smb_drcnt, data_sent_thistime);
136 if(data_sent_thistime == 0)
138 SSVAL(outbuf,smb_droff,0);
139 SSVAL(outbuf,smb_drdisp, 0);
143 /* The offset of the data bytes is the offset of the
144 parameter bytes plus the number of parameters being sent this time */
145 SSVAL(outbuf,smb_droff,((smb_buf(outbuf)+alignment_offset) -
146 smb_base(outbuf)) + params_sent_thistime + data_alignment_offset);
147 SSVAL(outbuf,smb_drdisp, pd - pdata);
150 /* Copy the param bytes into the packet */
151 if(params_sent_thistime)
152 memcpy((smb_buf(outbuf)+alignment_offset),pp,params_sent_thistime);
153 /* Copy in the data bytes */
154 if(data_sent_thistime)
155 memcpy(smb_buf(outbuf)+alignment_offset+params_sent_thistime+
156 data_alignment_offset,pd,data_sent_thistime);
158 DEBUG(9,("t2_rep: params_sent_thistime = %d, data_sent_thistime = %d, useable_space = %d\n",
159 params_sent_thistime, data_sent_thistime, useable_space));
160 DEBUG(9,("t2_rep: params_to_send = %d, data_to_send = %d, paramsize = %d, datasize = %d\n",
161 params_to_send, data_to_send, paramsize, datasize));
163 /* Send the packet */
164 send_smb(smbd_server_fd(),outbuf);
166 pp += params_sent_thistime;
167 pd += data_sent_thistime;
169 params_to_send -= params_sent_thistime;
170 data_to_send -= data_sent_thistime;
173 if(params_to_send < 0 || data_to_send < 0)
175 DEBUG(0,("send_trans2_replies failed sanity check pts = %d, dts = %d\n!!!",
176 params_to_send, data_to_send));
185 /****************************************************************************
186 reply to a TRANSACT2_OPEN
187 ****************************************************************************/
188 static int call_trans2open(connection_struct *conn, char *inbuf, char *outbuf,
190 char **pparams, char **ppdata)
192 char *params = *pparams;
193 int16 open_mode = SVAL(params, 2);
194 int16 open_attr = SVAL(params,6);
195 BOOL oplock_request = (((SVAL(params,0)|(1<<1))>>1) | ((SVAL(params,0)|(1<<2))>>1));
197 BOOL return_additional_info = BITSETW(params,0);
198 int16 open_sattr = SVAL(params, 4);
199 time_t open_time = make_unix_date3(params+8);
201 int16 open_ofun = SVAL(params,12);
202 int32 open_size = IVAL(params,14);
203 char *pname = ¶ms[28];
204 int16 namelen = strlen(pname)+1;
209 int fmode=0,mtime=0,rmode;
211 SMB_STRUCT_STAT sbuf;
213 BOOL bad_path = False;
216 StrnCpy(fname,pname,namelen);
218 DEBUG(3,("trans2open %s mode=%d attr=%d ofun=%d size=%d\n",
219 fname,open_mode, open_attr, open_ofun, open_size));
221 /* XXXX we need to handle passed times, sattr and flags */
223 unix_convert(fname,conn,0,&bad_path,NULL);
225 if (!check_name(fname,conn))
227 if((errno == ENOENT) && bad_path)
229 unix_ERR_class = ERRDOS;
230 unix_ERR_code = ERRbadpath;
232 return(UNIXERROR(ERRDOS,ERRnoaccess));
235 unixmode = unix_mode(conn,open_attr | aARCH, fname);
237 fsp = open_file_shared(conn,fname,open_mode,open_ofun,unixmode,
238 oplock_request, &rmode,&smb_action);
242 if((errno == ENOENT) && bad_path)
244 unix_ERR_class = ERRDOS;
245 unix_ERR_code = ERRbadpath;
247 return(UNIXERROR(ERRDOS,ERRnoaccess));
250 if (fsp->conn->vfs_ops.fstat(fsp->fd,&sbuf) != 0) {
251 close_file(fsp,False);
252 return(UNIXERROR(ERRDOS,ERRnoaccess));
256 fmode = dos_mode(conn,fname,&sbuf);
257 mtime = sbuf.st_mtime;
260 close_file(fsp,False);
261 return(ERROR(ERRDOS,ERRnoaccess));
264 /* Realloc the size of parameters and data we will return */
265 params = *pparams = Realloc(*pparams, 28);
267 return(ERROR(ERRDOS,ERRnomem));
269 memset((char *)params,'\0',28);
270 SSVAL(params,0,fsp->fnum);
271 SSVAL(params,2,fmode);
272 put_dos_date2(params,4, mtime);
273 SIVAL(params,8, (uint32)size);
274 SSVAL(params,12,rmode);
276 if (oplock_request && lp_fake_oplocks(SNUM(conn))) {
277 smb_action |= EXTENDED_OPLOCK_GRANTED;
280 SSVAL(params,18,smb_action);
282 * WARNING - this may need to be changed if SMB_INO_T <> 4 bytes.
284 SIVAL(params,20,inode);
286 /* Send the required number of replies */
287 send_trans2_replies(outbuf, bufsize, params, 28, *ppdata, 0);
292 /*********************************************************
293 * Routine to check if a given string matches exactly.
294 * as a special case a mask of "." does NOT match. That
295 * is required for correct wildcard semantics
296 * Case can be significant or not.
297 **********************************************************/
298 static BOOL exact_match(char *str,char *mask, BOOL case_sig)
300 if (mask[0] == '.' && mask[1] == 0) return False;
301 if (case_sig) return strcmp(str,mask)==0;
302 return strcasecmp(str,mask) == 0;
305 /****************************************************************************
306 get a level dependent lanman2 dir entry.
307 ****************************************************************************/
308 static BOOL get_lanman2_dir_entry(connection_struct *conn,
309 char *path_mask,int dirtype,int info_level,
310 int requires_resume_key,
311 BOOL dont_descend,char **ppdata,
312 char *base_data, int space_remaining,
313 BOOL *out_of_space, BOOL *got_exact_match,
318 SMB_STRUCT_STAT sbuf;
322 char *p, *pdata = *ppdata;
328 time_t mdate=0, adate=0, cdate=0;
331 int nt_extmode; /* Used for NT connections instead of mode */
332 BOOL needslash = ( conn->dirpath[strlen(conn->dirpath) -1] != '/');
335 *out_of_space = False;
336 *got_exact_match = False;
341 p = strrchr(path_mask,'/');
350 pstrcpy(mask, path_mask);
356 /* Needed if we run out of space */
357 prev_dirpos = TellDir(conn->dirptr);
358 dname = ReadDirName(conn->dirptr);
361 * Due to bugs in NT client redirectors we are not using
362 * resume keys any more - set them to zero.
363 * Check out the related comments in findfirst/findnext.
369 DEBUG(8,("get_lanman2_dir_entry:readdir on dirptr 0x%lx now at offset %d\n",
370 (long)conn->dirptr,TellDir(conn->dirptr)));
375 pstrcpy(fname,dname);
377 if(!(got_match = *got_exact_match = exact_match(fname, mask, case_sensitive)))
378 got_match = mask_match(fname, mask, case_sensitive);
380 if(!got_match && !is_8_3(fname, False)) {
383 * It turns out that NT matches wildcards against
384 * both long *and* short names. This may explain some
385 * of the wildcard wierdness from old DOS clients
386 * that some people have been seeing.... JRA.
390 pstrcpy( newname, fname);
391 name_map_mangle( newname, True, False, SNUM(conn));
392 if(!(got_match = *got_exact_match = exact_match(newname, mask, case_sensitive)))
393 got_match = mask_match(newname, mask, case_sensitive);
398 BOOL isdots = (strequal(fname,"..") || strequal(fname,"."));
399 if (dont_descend && !isdots)
402 pstrcpy(pathreal,conn->dirpath);
404 pstrcat(pathreal,"/");
405 pstrcat(pathreal,dname);
406 if (conn->vfs_ops.stat(dos_to_unix(pathreal,False),&sbuf) != 0)
408 /* Needed to show the msdfs symlinks as directories */
409 if(!lp_host_msdfs() || !lp_msdfs_root(SNUM(conn))
410 || !is_msdfs_volume(conn, pathreal))
412 DEBUG(5,("get_lanman2_dir_entry:Couldn't stat [%s] (%s)\n",
413 pathreal,strerror(errno)));
418 DEBUG(5,("get_lanman2_dir_entry: Masquerading msdfs link %s as a directory\n", pathreal));
419 sbuf.st_mode = (sbuf.st_mode & 0xFFF) | S_IFDIR;
423 mode = dos_mode(conn,pathreal,&sbuf);
425 if (!dir_check_ftype(conn,mode,&sbuf,dirtype)) {
426 DEBUG(5,("[%s] attribs didn't match %x\n",fname,dirtype));
431 mdate = sbuf.st_mtime;
432 adate = sbuf.st_atime;
433 cdate = get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(conn)));
437 DEBUG(5,("get_lanman2_dir_entry found %s fname=%s\n",pathreal,fname));
443 name_map_mangle(fname,False,True,SNUM(conn));
448 nt_extmode = mode ? mode : FILE_ATTRIBUTE_NORMAL;
453 if(requires_resume_key) {
457 put_dos_date2(p,l1_fdateCreation,cdate);
458 put_dos_date2(p,l1_fdateLastAccess,adate);
459 put_dos_date2(p,l1_fdateLastWrite,mdate);
460 SIVAL(p,l1_cbFile,(uint32)size);
461 SIVAL(p,l1_cbFileAlloc,SMB_ROUNDUP(size,1024));
462 SSVAL(p,l1_attrFile,mode);
463 SCVAL(p,l1_cchName,strlen(fname));
464 pstrcpy(p + l1_achName, fname);
465 nameptr = p + l1_achName;
466 p += l1_achName + strlen(fname) + 1;
471 if(requires_resume_key) {
475 put_dos_date2(p,l2_fdateCreation,cdate);
476 put_dos_date2(p,l2_fdateLastAccess,adate);
477 put_dos_date2(p,l2_fdateLastWrite,mdate);
478 SIVAL(p,l2_cbFile,(uint32)size);
479 SIVAL(p,l2_cbFileAlloc,SMB_ROUNDUP(size,1024));
480 SSVAL(p,l2_attrFile,mode);
481 SIVAL(p,l2_cbList,0); /* No extended attributes */
482 SCVAL(p,l2_cchName,strlen(fname));
483 pstrcpy(p + l2_achName, fname);
484 nameptr = p + l2_achName;
485 p += l2_achName + strlen(fname) + 1;
490 put_dos_date2(p,4,cdate);
491 put_dos_date2(p,8,adate);
492 put_dos_date2(p,12,mdate);
493 SIVAL(p,16,(uint32)size);
494 SIVAL(p,20,SMB_ROUNDUP(size,1024));
497 CVAL(p,30) = strlen(fname);
498 pstrcpy(p+31, fname);
500 p += 31 + strlen(fname) + 1;
504 if(requires_resume_key) {
508 SIVAL(p,0,33+strlen(fname)+1);
509 put_dos_date2(p,4,cdate);
510 put_dos_date2(p,8,adate);
511 put_dos_date2(p,12,mdate);
512 SIVAL(p,16,(uint32)size);
513 SIVAL(p,20,SMB_ROUNDUP(size,1024));
515 CVAL(p,32) = strlen(fname);
516 pstrcpy(p + 33, fname);
518 p += 33 + strlen(fname) + 1;
521 case SMB_FIND_FILE_BOTH_DIRECTORY_INFO:
522 was_8_3 = is_8_3(fname, True);
523 len = 94+strlen(fname);
524 len = (len + 3) & ~3;
525 SIVAL(p,0,len); p += 4;
526 SIVAL(p,0,reskey); p += 4;
527 put_long_date(p,cdate); p += 8;
528 put_long_date(p,adate); p += 8;
529 put_long_date(p,mdate); p += 8;
530 put_long_date(p,mdate); p += 8;
534 SIVAL(p,0,nt_extmode); p += 4;
535 SIVAL(p,0,strlen(fname)); p += 4;
536 SIVAL(p,0,0); p += 4;
539 name_map_mangle(p+2,True,True,SNUM(conn));
541 SSVAL(p, 0, strlen(p+2));
548 pstrcpy(p,fname); p += strlen(p);
552 case SMB_FIND_FILE_DIRECTORY_INFO:
553 len = 64+strlen(fname);
554 len = (len + 3) & ~3;
555 SIVAL(p,0,len); p += 4;
556 SIVAL(p,0,reskey); p += 4;
557 put_long_date(p,cdate); p += 8;
558 put_long_date(p,adate); p += 8;
559 put_long_date(p,mdate); p += 8;
560 put_long_date(p,mdate); p += 8;
564 SIVAL(p,0,nt_extmode); p += 4;
565 SIVAL(p,0,strlen(fname)); p += 4;
571 case SMB_FIND_FILE_FULL_DIRECTORY_INFO:
572 len = 68+strlen(fname);
573 len = (len + 3) & ~3;
574 SIVAL(p,0,len); p += 4;
575 SIVAL(p,0,reskey); p += 4;
576 put_long_date(p,cdate); p += 8;
577 put_long_date(p,adate); p += 8;
578 put_long_date(p,mdate); p += 8;
579 put_long_date(p,mdate); p += 8;
583 SIVAL(p,0,nt_extmode); p += 4;
584 SIVAL(p,0,strlen(fname)); p += 4;
585 SIVAL(p,0,0); p += 4;
590 case SMB_FIND_FILE_NAMES_INFO:
591 len = 12+strlen(fname);
592 len = (len + 3) & ~3;
593 SIVAL(p,0,len); p += 4;
594 SIVAL(p,0,reskey); p += 4;
595 SIVAL(p,0,strlen(fname)); p += 4;
605 if (PTR_DIFF(p,pdata) > space_remaining) {
606 /* Move the dirptr back to prev_dirpos */
607 SeekDir(conn->dirptr, prev_dirpos);
608 *out_of_space = True;
609 DEBUG(9,("get_lanman2_dir_entry: out of space\n"));
610 return False; /* Not finished - just out of space */
613 /* Setup the last_filename pointer, as an offset from base_data */
614 *last_name_off = PTR_DIFF(nameptr,base_data);
615 /* Advance the data pointer to the next slot */
622 /****************************************************************************
623 Reply to a TRANS2_FINDFIRST.
624 ****************************************************************************/
626 static int call_trans2findfirst(connection_struct *conn,
627 char *inbuf, char *outbuf, int bufsize,
628 char **pparams, char **ppdata)
630 /* We must be careful here that we don't return more than the
631 allowed number of data bytes. If this means returning fewer than
632 maxentries then so be it. We assume that the redirector has
633 enough room for the fixed number of parameter bytes it has
635 uint32 max_data_bytes = SVAL(inbuf, smb_mdrcnt);
636 char *params = *pparams;
637 char *pdata = *ppdata;
638 int dirtype = SVAL(params,0);
639 int maxentries = SVAL(params,2);
640 BOOL close_after_first = BITSETW(params+4,0);
641 BOOL close_if_end = BITSETW(params+4,1);
642 BOOL requires_resume_key = BITSETW(params+4,2);
643 int info_level = SVAL(params,6);
651 BOOL finished = False;
652 BOOL dont_descend = False;
653 BOOL out_of_space = False;
655 BOOL bad_path = False;
657 *directory = *mask = 0;
659 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",
660 dirtype, maxentries, close_after_first, close_if_end, requires_resume_key,
661 info_level, max_data_bytes));
669 case SMB_FIND_FILE_DIRECTORY_INFO:
670 case SMB_FIND_FILE_FULL_DIRECTORY_INFO:
671 case SMB_FIND_FILE_NAMES_INFO:
672 case SMB_FIND_FILE_BOTH_DIRECTORY_INFO:
675 return(ERROR(ERRDOS,ERRunknownlevel));
678 pstrcpy(directory, params + 12); /* Complete directory path with
679 wildcard mask appended */
681 RESOLVE_FINDFIRST_DFSPATH(directory, conn, inbuf, outbuf);
683 DEBUG(5,("path=%s\n",directory));
685 unix_convert(directory,conn,0,&bad_path,NULL);
686 if(!check_name(directory,conn)) {
687 if((errno == ENOENT) && bad_path)
689 unix_ERR_class = ERRDOS;
690 unix_ERR_code = ERRbadpath;
694 /* Ugly - NT specific hack - maybe not needed ? (JRA) */
695 if((errno == ENOTDIR) && (Protocol >= PROTOCOL_NT1) &&
696 (get_remote_arch() == RA_WINNT))
698 unix_ERR_class = ERRDOS;
699 unix_ERR_code = ERRbaddirectory;
703 return(UNIXERROR(ERRDOS,ERRbadpath));
706 p = strrchr(directory,'/');
708 pstrcpy(mask,directory);
709 pstrcpy(directory,"./");
715 DEBUG(5,("dir=%s, mask = %s\n",directory, mask));
717 pdata = *ppdata = Realloc(*ppdata, max_data_bytes + 1024);
719 return(ERROR(ERRDOS,ERRnomem));
720 memset((char *)pdata,'\0',max_data_bytes + 1024);
722 /* Realloc the params space */
723 params = *pparams = Realloc(*pparams, 10);
725 return(ERROR(ERRDOS,ERRnomem));
727 dptr_num = dptr_create(conn,directory, False, True ,SVAL(inbuf,smb_pid));
729 return(UNIXERROR(ERRDOS,ERRbadfile));
731 /* Save the wildcard match and attribs we are using on this directory -
732 needed as lanman2 assumes these are being saved between calls */
734 if(!(wcard = strdup(mask))) {
735 dptr_close(&dptr_num);
736 return(ERROR(ERRDOS,ERRnomem));
739 dptr_set_wcard(dptr_num, wcard);
740 dptr_set_attr(dptr_num, dirtype);
742 DEBUG(4,("dptr_num is %d, wcard = %s, attr = %d\n",dptr_num, wcard, dirtype));
744 /* We don't need to check for VOL here as this is returned by
745 a different TRANS2 call. */
747 DEBUG(8,("dirpath=<%s> dontdescend=<%s>\n",
748 conn->dirpath,lp_dontdescend(SNUM(conn))));
749 if (in_list(conn->dirpath,lp_dontdescend(SNUM(conn)),case_sensitive))
753 space_remaining = max_data_bytes;
754 out_of_space = False;
756 for (i=0;(i<maxentries) && !finished && !out_of_space;i++)
758 BOOL got_exact_match = False;
760 /* this is a heuristic to avoid seeking the dirptr except when
761 absolutely necessary. It allows for a filename of about 40 chars */
762 if (space_remaining < DIRLEN_GUESS && numentries > 0)
769 finished = !get_lanman2_dir_entry(conn,mask,dirtype,info_level,
770 requires_resume_key,dont_descend,
771 &p,pdata,space_remaining, &out_of_space, &got_exact_match,
775 if (finished && out_of_space)
778 if (!finished && !out_of_space)
782 * As an optimisation if we know we aren't looking
783 * for a wildcard name (ie. the name matches the wildcard exactly)
784 * then we can finish on any (first) match.
785 * This speeds up large directory searches. JRA.
791 space_remaining = max_data_bytes - PTR_DIFF(p,pdata);
794 /* Check if we can close the dirptr */
795 if(close_after_first || (finished && close_if_end))
797 DEBUG(5,("call_trans2findfirst - (2) closing dptr_num %d\n", dptr_num));
798 dptr_close(&dptr_num);
802 * If there are no matching entries we must return ERRDOS/ERRbadfile -
803 * from observation of NT.
808 dptr_close(&dptr_num);
809 return(ERROR(ERRDOS,ERRbadfile));
812 /* At this point pdata points to numentries directory entries. */
814 /* Set up the return parameter block */
815 SSVAL(params,0,dptr_num);
816 SSVAL(params,2,numentries);
817 SSVAL(params,4,finished);
818 SSVAL(params,6,0); /* Never an EA error */
819 SSVAL(params,8,last_name_off);
821 send_trans2_replies( outbuf, bufsize, params, 10, pdata, PTR_DIFF(p,pdata));
823 if ((! *directory) && dptr_path(dptr_num))
824 slprintf(directory,sizeof(directory)-1, "(%s)",dptr_path(dptr_num));
826 DEBUG( 4, ( "%s mask=%s directory=%s dirtype=%d numentries=%d\n",
827 smb_fn_name(CVAL(inbuf,smb_com)),
828 mask, directory, dirtype, numentries ) );
831 * Force a name mangle here to ensure that the
832 * mask as an 8.3 name is top of the mangled cache.
833 * The reasons for this are subtle. Don't remove
834 * this code unless you know what you are doing
835 * (see PR#13758). JRA.
838 if(!is_8_3( mask, False))
839 name_map_mangle(mask, True, True, SNUM(conn));
845 /****************************************************************************
846 reply to a TRANS2_FINDNEXT
847 ****************************************************************************/
848 static int call_trans2findnext(connection_struct *conn,
849 char *inbuf, char *outbuf,
850 int length, int bufsize,
851 char **pparams, char **ppdata)
853 /* We must be careful here that we don't return more than the
854 allowed number of data bytes. If this means returning fewer than
855 maxentries then so be it. We assume that the redirector has
856 enough room for the fixed number of parameter bytes it has
858 int max_data_bytes = SVAL(inbuf, smb_mdrcnt);
859 char *params = *pparams;
860 char *pdata = *ppdata;
861 int dptr_num = SVAL(params,0);
862 int maxentries = SVAL(params,2);
863 uint16 info_level = SVAL(params,4);
864 uint32 resume_key = IVAL(params,6);
865 BOOL close_after_request = BITSETW(params+10,0);
866 BOOL close_if_end = BITSETW(params+10,1);
867 BOOL requires_resume_key = BITSETW(params+10,2);
868 BOOL continue_bit = BITSETW(params+10,3);
875 int i, last_name_off=0;
876 BOOL finished = False;
877 BOOL dont_descend = False;
878 BOOL out_of_space = False;
881 *mask = *directory = *resume_name = 0;
883 pstrcpy( resume_name, params+12);
885 DEBUG(3,("call_trans2findnext: dirhandle = %d, max_data_bytes = %d, maxentries = %d, \
886 close_after_request=%d, close_if_end = %d requires_resume_key = %d \
887 resume_key = %d resume name = %s continue=%d level = %d\n",
888 dptr_num, max_data_bytes, maxentries, close_after_request, close_if_end,
889 requires_resume_key, resume_key, resume_name, continue_bit, info_level));
897 case SMB_FIND_FILE_DIRECTORY_INFO:
898 case SMB_FIND_FILE_FULL_DIRECTORY_INFO:
899 case SMB_FIND_FILE_NAMES_INFO:
900 case SMB_FIND_FILE_BOTH_DIRECTORY_INFO:
903 return(ERROR(ERRDOS,ERRunknownlevel));
906 pdata = *ppdata = Realloc( *ppdata, max_data_bytes + 1024);
908 return(ERROR(ERRDOS,ERRnomem));
909 memset((char *)pdata,'\0',max_data_bytes + 1024);
911 /* Realloc the params space */
912 params = *pparams = Realloc(*pparams, 6*SIZEOFWORD);
914 return(ERROR(ERRDOS,ERRnomem));
916 /* Check that the dptr is valid */
917 if(!(conn->dirptr = dptr_fetch_lanman2(dptr_num)))
918 return(ERROR(ERRDOS,ERRnofiles));
920 string_set(&conn->dirpath,dptr_path(dptr_num));
922 /* Get the wildcard mask from the dptr */
923 if((p = dptr_wcard(dptr_num))== NULL) {
924 DEBUG(2,("dptr_num %d has no wildcard\n", dptr_num));
925 return (ERROR(ERRDOS,ERRnofiles));
928 pstrcpy(directory,conn->dirpath);
930 /* Get the attr mask from the dptr */
931 dirtype = dptr_attr(dptr_num);
933 DEBUG(3,("dptr_num is %d, mask = %s, attr = %x, dirptr=(0x%lX,%d)\n",
934 dptr_num, mask, dirtype,
936 TellDir(conn->dirptr)));
938 /* We don't need to check for VOL here as this is returned by
939 a different TRANS2 call. */
941 DEBUG(8,("dirpath=<%s> dontdescend=<%s>\n",conn->dirpath,lp_dontdescend(SNUM(conn))));
942 if (in_list(conn->dirpath,lp_dontdescend(SNUM(conn)),case_sensitive))
946 space_remaining = max_data_bytes;
947 out_of_space = False;
950 * Seek to the correct position. We no longer use the resume key but
951 * depend on the last file name instead.
953 if(requires_resume_key && *resume_name && !continue_bit)
956 * Fix for NT redirector problem triggered by resume key indexes
957 * changing between directory scans. We now return a resume key of 0
958 * and instead look for the filename to continue from (also given
959 * to us by NT/95/smbfs/smbclient). If no other scans have been done between the
960 * findfirst/findnext (as is usual) then the directory pointer
961 * should already be at the correct place. Check this by scanning
962 * backwards looking for an exact (ie. case sensitive) filename match.
963 * If we get to the beginning of the directory and haven't found it then scan
964 * forwards again looking for a match. JRA.
967 int current_pos, start_pos;
969 void *dirptr = conn->dirptr;
970 start_pos = TellDir(dirptr);
971 for(current_pos = start_pos; current_pos >= 0; current_pos--)
973 DEBUG(7,("call_trans2findnext: seeking to pos %d\n", current_pos));
975 SeekDir(dirptr, current_pos);
976 dname = ReadDirName(dirptr);
979 * Remember, name_map_mangle is called by
980 * get_lanman2_dir_entry(), so the resume name
981 * could be mangled. Ensure we do the same
986 name_map_mangle( dname, False, True, SNUM(conn));
988 if(dname && strcsequal( resume_name, dname))
990 SeekDir(dirptr, current_pos+1);
991 DEBUG(7,("call_trans2findnext: got match at pos %d\n", current_pos+1 ));
997 * Scan forward from start if not found going backwards.
1002 DEBUG(7,("call_trans2findnext: notfound: seeking to pos %d\n", start_pos));
1003 SeekDir(dirptr, start_pos);
1004 for(current_pos = start_pos; (dname = ReadDirName(dirptr)) != NULL; SeekDir(dirptr,++current_pos))
1007 * Remember, name_map_mangle is called by
1008 * get_lanman2_dir_entry(), so the resume name
1009 * could be mangled. Ensure we do the same
1014 name_map_mangle( dname, False, True, SNUM(conn));
1016 if(dname && strcsequal( resume_name, dname))
1018 SeekDir(dirptr, current_pos+1);
1019 DEBUG(7,("call_trans2findnext: got match at pos %d\n", current_pos+1 ));
1023 } /* end if current_pos */
1024 } /* end if requires_resume_key && !continue_bit */
1026 for (i=0;(i<(int)maxentries) && !finished && !out_of_space ;i++)
1028 BOOL got_exact_match = False;
1030 /* this is a heuristic to avoid seeking the dirptr except when
1031 absolutely necessary. It allows for a filename of about 40 chars */
1032 if (space_remaining < DIRLEN_GUESS && numentries > 0)
1034 out_of_space = True;
1039 finished = !get_lanman2_dir_entry(conn,mask,dirtype,info_level,
1040 requires_resume_key,dont_descend,
1041 &p,pdata,space_remaining, &out_of_space, &got_exact_match,
1045 if (finished && out_of_space)
1048 if (!finished && !out_of_space)
1052 * As an optimisation if we know we aren't looking
1053 * for a wildcard name (ie. the name matches the wildcard exactly)
1054 * then we can finish on any (first) match.
1055 * This speeds up large directory searches. JRA.
1061 space_remaining = max_data_bytes - PTR_DIFF(p,pdata);
1064 /* Check if we can close the dirptr */
1065 if(close_after_request || (finished && close_if_end))
1067 DEBUG(5,("call_trans2findnext: closing dptr_num = %d\n", dptr_num));
1068 dptr_close(&dptr_num); /* This frees up the saved mask */
1072 /* Set up the return parameter block */
1073 SSVAL(params,0,numentries);
1074 SSVAL(params,2,finished);
1075 SSVAL(params,4,0); /* Never an EA error */
1076 SSVAL(params,6,last_name_off);
1078 send_trans2_replies( outbuf, bufsize, params, 8, pdata, PTR_DIFF(p,pdata));
1080 if ((! *directory) && dptr_path(dptr_num))
1081 slprintf(directory,sizeof(directory)-1, "(%s)",dptr_path(dptr_num));
1083 DEBUG( 3, ( "%s mask=%s directory=%s dirtype=%d numentries=%d\n",
1084 smb_fn_name(CVAL(inbuf,smb_com)),
1085 mask, directory, dirtype, numentries ) );
1090 /****************************************************************************
1091 reply to a TRANS2_QFSINFO (query filesystem info)
1092 ****************************************************************************/
1094 static int call_trans2qfsinfo(connection_struct *conn,
1095 char *inbuf, char *outbuf,
1096 int length, int bufsize,
1097 char **pparams, char **ppdata)
1099 int max_data_bytes = SVAL(inbuf, smb_mdrcnt);
1100 char *pdata = *ppdata;
1101 char *params = *pparams;
1102 uint16 info_level = SVAL(params,0);
1105 char *vname = volume_label(SNUM(conn));
1106 int snum = SNUM(conn);
1107 char *fstype = lp_fstype(SNUM(conn));
1109 DEBUG(3,("call_trans2qfsinfo: level = %d\n", info_level));
1111 if(conn->vfs_ops.stat(".",&st)!=0) {
1112 DEBUG(2,("call_trans2qfsinfo: stat of . failed (%s)\n", strerror(errno)));
1113 return (ERROR(ERRSRV,ERRinvdevice));
1116 pdata = *ppdata = Realloc(*ppdata, max_data_bytes + 1024);
1117 memset((char *)pdata,'\0',max_data_bytes + 1024);
1123 SMB_BIG_UINT dfree,dsize,bsize;
1125 conn->vfs_ops.disk_free(".",False,&bsize,&dfree,&dsize);
1126 SIVAL(pdata,l1_idFileSystem,st.st_dev);
1127 SIVAL(pdata,l1_cSectorUnit,bsize/512);
1128 SIVAL(pdata,l1_cUnit,dsize);
1129 SIVAL(pdata,l1_cUnitAvail,dfree);
1130 SSVAL(pdata,l1_cbSector,512);
1131 DEBUG(5,("call_trans2qfsinfo : bsize=%u, id=%x, cSectorUnit=%u, cUnit=%u, cUnitAvail=%u, cbSector=%d\n",
1132 (unsigned int)bsize, (unsigned int)st.st_dev, ((unsigned int)bsize)/512, (unsigned int)dsize,
1133 (unsigned int)dfree, 512));
1138 /* Return volume name */
1139 int volname_len = MIN(strlen(vname),11);
1140 data_len = l2_vol_szVolLabel + volname_len + 1;
1142 * Add volume serial number - hash of a combination of
1143 * the called hostname and the service name.
1145 SIVAL(pdata,0,str_checksum(lp_servicename(snum)) ^ (str_checksum(local_machine)<<16) );
1146 SCVAL(pdata,l2_vol_cch,volname_len);
1147 StrnCpy(pdata+l2_vol_szVolLabel,vname,volname_len);
1148 DEBUG(5,("call_trans2qfsinfo : time = %x, namelen = %d, name = %s\n",
1149 (unsigned)st.st_ctime, volname_len,
1150 pdata+l2_vol_szVolLabel));
1153 case SMB_QUERY_FS_ATTRIBUTE_INFO:
1156 SIVAL(pdata,0,FILE_CASE_PRESERVED_NAMES|FILE_CASE_SENSITIVE_SEARCH|
1157 FILE_DEVICE_IS_MOUNTED|
1158 (lp_nt_acl_support() ? FILE_PERSISTENT_ACLS : 0)); /* FS ATTRIBUTES */
1159 #if 0 /* Old code. JRA. */
1160 SIVAL(pdata,0,0x4006); /* FS ATTRIBUTES == long filenames supported? */
1161 #endif /* Old code. */
1163 SIVAL(pdata,4,128); /* Max filename component length */
1164 fstype_len = dos_PutUniCode(pdata+12,unix_to_dos(fstype,False),sizeof(pstring), False);
1165 SIVAL(pdata,8,fstype_len);
1166 data_len = 12 + fstype_len;
1167 SSVAL(outbuf,smb_flg2,SVAL(outbuf,smb_flg2)|FLAGS2_UNICODE_STRINGS);
1170 case SMB_QUERY_FS_LABEL_INFO:
1171 data_len = 4 + strlen(vname);
1172 SIVAL(pdata,0,strlen(vname));
1173 pstrcpy(pdata+4,vname);
1175 case SMB_QUERY_FS_VOLUME_INFO:
1178 * Add volume serial number - hash of a combination of
1179 * the called hostname and the service name.
1181 SIVAL(pdata,8,str_checksum(lp_servicename(snum)) ^
1182 (str_checksum(local_machine)<<16));
1184 /* NT4 always serves this up as unicode but expects it to be
1185 * delivered as ascii! (tridge && JRA)
1187 if ((get_remote_arch() != RA_WIN2K) && (global_client_caps & CAP_NT_SMBS)) {
1188 data_len = 18 + strlen(vname);
1189 SIVAL(pdata,12,strlen(vname));
1190 pstrcpy(pdata+18,vname);
1192 data_len = 18 + 2*strlen(vname);
1193 SIVAL(pdata,12,strlen(vname)*2);
1194 dos_PutUniCode(pdata+18,unix_to_dos(vname,False),sizeof(pstring), False);
1195 SSVAL(outbuf,smb_flg2,SVAL(outbuf,smb_flg2)|FLAGS2_UNICODE_STRINGS);
1198 DEBUG(5,("call_trans2qfsinfo : SMB_QUERY_FS_VOLUME_INFO namelen = %d, vol = %s\n",
1199 (int)strlen(vname),vname));
1201 case SMB_QUERY_FS_SIZE_INFO:
1203 SMB_BIG_UINT dfree,dsize,bsize;
1205 conn->vfs_ops.disk_free(".",False,&bsize,&dfree,&dsize);
1206 SBIG_UINT(pdata,0,dsize);
1207 SBIG_UINT(pdata,8,dfree);
1208 SIVAL(pdata,16,bsize/512);
1209 SIVAL(pdata,20,512);
1212 case SMB_QUERY_FS_DEVICE_INFO:
1214 SIVAL(pdata,0,0); /* dev type */
1215 SIVAL(pdata,4,0); /* characteristics */
1217 case SMB_MAC_QUERY_FS_INFO:
1219 * Thursby MAC extension... ONLY on NTFS filesystems
1220 * once we do streams then we don't need this
1222 if (strequal(lp_fstype(SNUM(conn)),"NTFS")) {
1224 SIVAL(pdata,84,0x100); /* Don't support mac... */
1229 return(ERROR(ERRDOS,ERRunknownlevel));
1233 send_trans2_replies( outbuf, bufsize, params, 0, pdata, data_len);
1235 DEBUG( 4, ( "%s info_level = %d\n",
1236 smb_fn_name(CVAL(inbuf,smb_com)), info_level) );
1241 /****************************************************************************
1242 reply to a TRANS2_SETFSINFO (set filesystem info)
1243 ****************************************************************************/
1244 static int call_trans2setfsinfo(connection_struct *conn,
1245 char *inbuf, char *outbuf, int length,
1247 char **pparams, char **ppdata)
1249 /* Just say yes we did it - there is nothing that
1250 can be set here so it doesn't matter. */
1252 DEBUG(3,("call_trans2setfsinfo\n"));
1254 if (!CAN_WRITE(conn))
1255 return(ERROR(ERRSRV,ERRaccess));
1257 outsize = set_message(outbuf,10,0,True);
1262 /****************************************************************************
1263 Reply to a TRANS2_QFILEPATHINFO or TRANSACT2_QFILEINFO (query file info by
1264 file name or file id).
1265 ****************************************************************************/
1267 static int call_trans2qfilepathinfo(connection_struct *conn,
1268 char *inbuf, char *outbuf, int length,
1270 char **pparams,char **ppdata,
1273 int max_data_bytes = SVAL(inbuf, smb_mdrcnt);
1274 char *params = *pparams;
1275 char *pdata = *ppdata;
1276 uint16 tran_call = SVAL(inbuf, smb_setup0);
1280 unsigned int data_size;
1281 SMB_STRUCT_STAT sbuf;
1287 BOOL bad_path = False;
1288 BOOL delete_pending = False;
1290 if (tran_call == TRANSACT2_QFILEINFO) {
1291 files_struct *fsp = file_fsp(params,0);
1292 info_level = SVAL(params,2);
1294 DEBUG(3,("call_trans2qfilepathinfo: TRANSACT2_QFILEINFO: level = %d\n", info_level));
1296 if(fsp && (fsp->is_directory || fsp->stat_open)) {
1298 * This is actually a QFILEINFO on a directory
1299 * handle (returned from an NT SMB). NT5.0 seems
1300 * to do this call. JRA.
1302 fname = fsp->fsp_name;
1303 unix_convert(fname,conn,0,&bad_path,&sbuf);
1304 if (!check_name(fname,conn) ||
1305 (!VALID_STAT(sbuf) && conn->vfs_ops.stat(dos_to_unix(fname,False),&sbuf))) {
1306 DEBUG(3,("fileinfo of %s failed (%s)\n",fname,strerror(errno)));
1307 if((errno == ENOENT) && bad_path)
1309 unix_ERR_class = ERRDOS;
1310 unix_ERR_code = ERRbadpath;
1312 return(UNIXERROR(ERRDOS,ERRbadpath));
1315 delete_pending = fsp->directory_delete_on_close;
1319 * Original code - this is an open file.
1321 CHECK_FSP(fsp,conn);
1324 fname = fsp->fsp_name;
1325 if (fsp->conn->vfs_ops.fstat(fsp->fd,&sbuf) != 0) {
1326 DEBUG(3,("fstat of fnum %d failed (%s)\n",fsp->fnum, strerror(errno)));
1327 return(UNIXERROR(ERRDOS,ERRbadfid));
1329 if((pos = fsp->conn->vfs_ops.lseek(fsp->fd,0,SEEK_CUR)) == -1)
1330 return(UNIXERROR(ERRDOS,ERRnoaccess));
1332 delete_pending = fsp->delete_on_close;
1336 info_level = SVAL(params,0);
1338 DEBUG(3,("call_trans2qfilepathinfo: TRANSACT2_QPATHINFO: level = %d\n", info_level));
1341 pstrcpy(fname,¶ms[6]);
1343 RESOLVE_DFSPATH(fname, conn, inbuf, outbuf);
1345 unix_convert(fname,conn,0,&bad_path,&sbuf);
1346 if (!check_name(fname,conn) ||
1347 (!VALID_STAT(sbuf) && conn->vfs_ops.stat(dos_to_unix(fname,False),&sbuf))) {
1348 DEBUG(3,("fileinfo of %s failed (%s)\n",fname,strerror(errno)));
1349 if((errno == ENOENT) && bad_path)
1351 unix_ERR_class = ERRDOS;
1352 unix_ERR_code = ERRbadpath;
1354 return(UNIXERROR(ERRDOS,ERRbadpath));
1359 DEBUG(3,("call_trans2qfilepathinfo %s level=%d call=%d total_data=%d\n",
1360 fname,info_level,tran_call,total_data));
1362 p = strrchr(fname,'/');
1368 mode = dos_mode(conn,fname,&sbuf);
1369 size = sbuf.st_size;
1370 if (mode & aDIR) size = 0;
1372 /* from now on we only want the part after the / */
1375 params = *pparams = Realloc(*pparams,2);
1376 memset((char *)params,'\0',2);
1377 data_size = max_data_bytes + 1024;
1378 pdata = *ppdata = Realloc(*ppdata, data_size);
1380 if (total_data > 0 && IVAL(pdata,0) == total_data) {
1381 /* uggh, EAs for OS2 */
1382 DEBUG(4,("Rejecting EA request with total_data=%d\n",total_data));
1383 return(ERROR(ERRDOS,ERROR_EAS_NOT_SUPPORTED));
1386 memset((char *)pdata,'\0',data_size);
1390 case SMB_INFO_STANDARD:
1391 case SMB_INFO_QUERY_EA_SIZE:
1392 data_size = (info_level==1?22:26);
1393 put_dos_date2(pdata,l1_fdateCreation,get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(conn))));
1394 put_dos_date2(pdata,l1_fdateLastAccess,sbuf.st_atime);
1395 put_dos_date2(pdata,l1_fdateLastWrite,sbuf.st_mtime); /* write time */
1396 SIVAL(pdata,l1_cbFile,(uint32)size);
1397 SIVAL(pdata,l1_cbFileAlloc,SMB_ROUNDUP(size,1024));
1398 SSVAL(pdata,l1_attrFile,mode);
1399 SIVAL(pdata,l1_attrFile+2,4); /* this is what OS2 does */
1402 case SMB_INFO_QUERY_EAS_FROM_LIST:
1404 put_dos_date2(pdata,0,get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(conn))));
1405 put_dos_date2(pdata,4,sbuf.st_atime);
1406 put_dos_date2(pdata,8,sbuf.st_mtime);
1407 SIVAL(pdata,12,(uint32)size);
1408 SIVAL(pdata,16,SMB_ROUNDUP(size,1024));
1409 SIVAL(pdata,20,mode);
1412 case SMB_INFO_QUERY_ALL_EAS:
1414 SIVAL(pdata,0,data_size);
1418 return(ERROR(ERRDOS,ERRbadfunc)); /* os/2 needs this */
1420 case SMB_QUERY_FILE_BASIC_INFO:
1421 data_size = 36; /* w95 returns 40 bytes not 36 - why ?. */
1422 put_long_date(pdata,get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(conn))));
1423 put_long_date(pdata+8,sbuf.st_atime);
1424 put_long_date(pdata+16,sbuf.st_mtime); /* write time */
1425 put_long_date(pdata+24,sbuf.st_mtime); /* change time */
1426 SIVAL(pdata,32,mode);
1428 DEBUG(5,("SMB_QFBI - "));
1430 time_t create_time = get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(conn)));
1431 DEBUG(5,("create: %s ", ctime(&create_time)));
1433 DEBUG(5,("access: %s ", ctime(&sbuf.st_atime)));
1434 DEBUG(5,("write: %s ", ctime(&sbuf.st_mtime)));
1435 DEBUG(5,("change: %s ", ctime(&sbuf.st_mtime)));
1436 DEBUG(5,("mode: %x\n", mode));
1440 case SMB_QUERY_FILE_STANDARD_INFO:
1442 SOFF_T(pdata,0,size);
1443 SOFF_T(pdata,8,size);
1444 SIVAL(pdata,16,sbuf.st_nlink);
1446 CVAL(pdata,21) = (mode&aDIR)?1:0;
1449 case SMB_QUERY_FILE_EA_INFO:
1453 /* Get the 8.3 name - used if NT SMB was negotiated. */
1454 case SMB_QUERY_FILE_ALT_NAME_INFO:
1457 pstrcpy(short_name,p);
1458 /* Mangle if not already 8.3 */
1459 if(!is_8_3(short_name, True))
1461 if(!name_map_mangle(short_name,True,True,SNUM(conn)))
1464 strupper(short_name);
1465 l = strlen(short_name);
1466 dos_PutUniCode(pdata + 4, unix_to_dos(short_name,False),sizeof(pstring), False);
1467 data_size = 4 + (2*l);
1472 case SMB_QUERY_FILE_NAME_INFO:
1474 * The first part of this code is essential
1475 * to get security descriptors to work on mapped
1476 * drives. Don't ask how I discovered this unless
1477 * you like hearing about me suffering.... :-). JRA.
1479 if(strequal(".", fname) && (global_client_caps & CAP_UNICODE)) {
1481 SSVAL(outbuf,smb_flg2,SVAL(outbuf,smb_flg2)|FLAGS2_UNICODE_STRINGS);
1482 dos_PutUniCode(pdata + 4, unix_to_dos("\\",False),sizeof(pstring), False);
1484 pstrcpy(pdata+4,fname);
1490 case SMB_QUERY_FILE_ALLOCATION_INFO:
1491 case SMB_QUERY_FILE_END_OF_FILEINFO:
1493 SOFF_T(pdata,0,size);
1496 case SMB_QUERY_FILE_ALL_INFO:
1497 put_long_date(pdata,get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(conn))));
1498 put_long_date(pdata+8,sbuf.st_atime);
1499 put_long_date(pdata+16,sbuf.st_mtime); /* write time */
1500 put_long_date(pdata+24,sbuf.st_mtime); /* change time */
1501 SIVAL(pdata,32,mode);
1503 SOFF_T(pdata,0,size);
1504 SOFF_T(pdata,8,size);
1505 SIVAL(pdata,16,sbuf.st_nlink);
1506 CVAL(pdata,20) = delete_pending;
1507 CVAL(pdata,21) = (mode&aDIR)?1:0;
1509 SINO_T(pdata,0,(SMB_INO_T)sbuf.st_ino);
1510 pdata += 8; /* index number */
1511 pdata += 4; /* EA info */
1513 SIVAL(pdata,0,0xA9);
1515 SIVAL(pdata,0,0xd01BF);
1517 SOFF_T(pdata,0,pos); /* current offset */
1519 SIVAL(pdata,0,mode); /* is this the right sort of mode info? */
1521 pdata += 4; /* alignment */
1523 pstrcpy(pdata+4,fname);
1525 data_size = PTR_DIFF(pdata,(*ppdata));
1529 /* NT4 server just returns "invalid query" to this - if we try to answer
1530 it then NTws gets a BSOD! (tridge) */
1531 case SMB_QUERY_FILE_STREAM_INFO:
1534 SIVAL(pdata,4,size);
1535 SIVAL(pdata,12,size);
1537 pstrcpy(pdata+24,fname);
1542 return(ERROR(ERRDOS,ERRunknownlevel));
1545 send_trans2_replies( outbuf, bufsize, params, 2, *ppdata, data_size);
1550 /****************************************************************************
1551 reply to a TRANS2_SETFILEINFO (set file info by fileid)
1552 ****************************************************************************/
1553 static int call_trans2setfilepathinfo(connection_struct *conn,
1554 char *inbuf, char *outbuf, int length,
1555 int bufsize, char **pparams,
1556 char **ppdata, int total_data)
1558 char *params = *pparams;
1559 char *pdata = *ppdata;
1560 uint16 tran_call = SVAL(inbuf, smb_setup0);
1569 BOOL bad_path = False;
1570 files_struct *fsp = NULL;
1572 if (!CAN_WRITE(conn))
1573 return(ERROR(ERRSRV,ERRaccess));
1575 if (tran_call == TRANSACT2_SETFILEINFO) {
1576 fsp = file_fsp(params,0);
1577 info_level = SVAL(params,2);
1579 if(fsp && (fsp->is_directory || fsp->stat_open)) {
1581 * This is actually a SETFILEINFO on a directory
1582 * handle (returned from an NT SMB). NT5.0 seems
1583 * to do this call. JRA.
1585 fname = fsp->fsp_name;
1586 unix_convert(fname,conn,0,&bad_path,&st);
1587 if (!check_name(fname,conn) ||
1588 (!VALID_STAT(st) && conn->vfs_ops.stat(dos_to_unix(fname,False),&st))) {
1589 DEBUG(3,("fileinfo of %s failed (%s)\n",fname,strerror(errno)));
1590 if((errno == ENOENT) && bad_path)
1592 unix_ERR_class = ERRDOS;
1593 unix_ERR_code = ERRbadpath;
1595 return(UNIXERROR(ERRDOS,ERRbadpath));
1599 * Original code - this is an open file.
1601 CHECK_FSP(fsp,conn);
1604 fname = fsp->fsp_name;
1607 if (fsp->conn->vfs_ops.fstat(fd,&st) != 0) {
1608 DEBUG(3,("fstat of fnum %d failed (%s)\n",fsp->fnum, strerror(errno)));
1609 return(UNIXERROR(ERRDOS,ERRbadfid));
1614 info_level = SVAL(params,0);
1616 pstrcpy(fname,¶ms[6]);
1617 unix_convert(fname,conn,0,&bad_path,&st);
1618 if(!check_name(fname, conn))
1620 if((errno == ENOENT) && bad_path)
1622 unix_ERR_class = ERRDOS;
1623 unix_ERR_code = ERRbadpath;
1625 return(UNIXERROR(ERRDOS,ERRbadpath));
1628 if(!VALID_STAT(st) && conn->vfs_ops.stat(dos_to_unix(fname,False),&st)!=0) {
1629 DEBUG(3,("stat of %s failed (%s)\n", fname, strerror(errno)));
1630 if((errno == ENOENT) && bad_path)
1632 unix_ERR_class = ERRDOS;
1633 unix_ERR_code = ERRbadpath;
1635 return(UNIXERROR(ERRDOS,ERRbadpath));
1639 DEBUG(3,("call_trans2setfilepathinfo(%d) %s info_level=%d totdata=%d\n",
1640 tran_call,fname,info_level,total_data));
1642 /* Realloc the parameter and data sizes */
1643 params = *pparams = Realloc(*pparams,2);
1645 return(ERROR(ERRDOS,ERRnomem));
1650 tvs.modtime = st.st_mtime;
1651 tvs.actime = st.st_atime;
1652 mode = dos_mode(conn,fname,&st);
1654 if (total_data > 0 && IVAL(pdata,0) == total_data) {
1655 /* uggh, EAs for OS2 */
1656 DEBUG(4,("Rejecting EA request with total_data=%d\n",total_data));
1657 return(ERROR(ERRDOS,ERROR_EAS_NOT_SUPPORTED));
1662 case SMB_INFO_STANDARD:
1663 case SMB_INFO_QUERY_EA_SIZE:
1666 tvs.actime = make_unix_date2(pdata+l1_fdateLastAccess);
1669 tvs.modtime = make_unix_date2(pdata+l1_fdateLastWrite);
1671 mode = SVAL(pdata,l1_attrFile);
1672 size = IVAL(pdata,l1_cbFile);
1676 /* XXXX um, i don't think this is right.
1677 it's also not in the cifs6.txt spec.
1679 case SMB_INFO_QUERY_EAS_FROM_LIST:
1680 tvs.actime = make_unix_date2(pdata+8);
1681 tvs.modtime = make_unix_date2(pdata+12);
1682 size = IVAL(pdata,16);
1683 mode = IVAL(pdata,24);
1686 /* XXXX nor this. not in cifs6.txt, either. */
1687 case SMB_INFO_QUERY_ALL_EAS:
1688 tvs.actime = make_unix_date2(pdata+8);
1689 tvs.modtime = make_unix_date2(pdata+12);
1690 size = IVAL(pdata,16);
1691 mode = IVAL(pdata,24);
1694 case SMB_SET_FILE_BASIC_INFO:
1696 /* Patch to do this correctly from Paul Eggert <eggert@twinsun.com>. */
1698 time_t changed_time;
1700 /* Ignore create time at offset pdata. */
1703 tvs.actime = interpret_long_date(pdata+8);
1705 write_time = interpret_long_date(pdata+16);
1706 changed_time = interpret_long_date(pdata+24);
1708 tvs.modtime = MIN(write_time, changed_time);
1710 /* Prefer a defined time to an undefined one. */
1711 if (tvs.modtime == (time_t)0 || tvs.modtime == (time_t)-1)
1712 tvs.modtime = (write_time == (time_t)0 || write_time == (time_t)-1
1716 #if 0 /* Needs more testing... */
1717 /* Test from Luke to prevent Win95 from
1718 setting incorrect values here.
1720 if (tvs.actime < tvs.modtime)
1721 return(ERROR(ERRDOS,ERRnoaccess));
1722 #endif /* Needs more testing... */
1725 mode = IVAL(pdata,32);
1730 * NT seems to use this call with a size of zero
1731 * to mean truncate the file. JRA.
1734 case SMB_SET_FILE_ALLOCATION_INFO:
1736 SMB_OFF_T newsize = IVAL(pdata,0);
1737 #ifdef LARGE_SMB_OFF_T
1738 newsize |= (((SMB_OFF_T)IVAL(pdata,4)) << 32);
1739 #else /* LARGE_SMB_OFF_T */
1740 if (IVAL(pdata,4) != 0) /* more than 32 bits? */
1741 return(ERROR(ERRDOS,ERRunknownlevel));
1742 #endif /* LARGE_SMB_OFF_T */
1743 DEBUG(10,("call_trans2setfilepathinfo: Set file allocation info for file %s to %.0f\n", fname, (double)newsize ));
1749 case SMB_SET_FILE_END_OF_FILE_INFO:
1751 size = IVAL(pdata,0);
1752 #ifdef LARGE_SMB_OFF_T
1753 size |= (((SMB_OFF_T)IVAL(pdata,4)) << 32);
1754 #else /* LARGE_SMB_OFF_T */
1755 if (IVAL(pdata,4) != 0) /* more than 32 bits? */
1756 return(ERROR(ERRDOS,ERRunknownlevel));
1757 #endif /* LARGE_SMB_OFF_T */
1758 DEBUG(10,("call_trans2setfilepathinfo: Set end of file info for file %s to %.0f\n", fname, (double)size ));
1762 case SMB_SET_FILE_DISPOSITION_INFO: /* Set delete on close for open file. */
1764 if ((tran_call == TRANSACT2_SETFILEINFO) && (fsp != NULL))
1766 BOOL delete_on_close = (CVAL(pdata,0) ? True : False);
1768 if(fsp->is_directory)
1770 fsp->directory_delete_on_close = delete_on_close;
1771 DEBUG(10, ("call_trans2setfilepathinfo: %s delete on close flag for fnum = %d, directory %s\n",
1772 delete_on_close ? "Added" : "Removed", fsp->fnum, fsp->fsp_name ));
1775 else if(fsp->stat_open)
1777 DEBUG(10, ("call_trans2setfilepathinfo: %s delete on close flag for fnum = %d, stat open %s\n",
1778 delete_on_close ? "Added" : "Removed", fsp->fnum, fsp->fsp_name ));
1784 * We can only set the delete on close flag if
1785 * the share mode contained ALLOW_SHARE_DELETE
1788 if(!GET_ALLOW_SHARE_DELETE(fsp->share_mode))
1789 return(ERROR(ERRDOS,ERRnoaccess));
1792 * If the flag has been set then
1793 * modify the share mode entry for all files we have open
1794 * on this device and inode to tell other smbds we have
1795 * changed the delete on close flag.
1798 if(delete_on_close && !GET_DELETE_ON_CLOSE_FLAG(fsp->share_mode))
1801 files_struct *iterate_fsp;
1802 SMB_DEV_T dev = fsp->dev;
1803 SMB_INO_T inode = fsp->inode;
1804 int num_share_modes;
1805 share_mode_entry *current_shares = NULL;
1807 if (lock_share_entry_fsp(fsp) == False)
1808 return(ERROR(ERRDOS,ERRnoaccess));
1811 * Before we allow this we need to ensure that all current opens
1812 * on the file have the GET_ALLOW_SHARE_DELETE flag set. If they
1813 * do not then we deny this (as we are essentially deleting the
1814 * file at this point.
1817 num_share_modes = get_share_modes(conn, dev, inode, ¤t_shares);
1818 for(i = 0; i < num_share_modes; i++)
1820 if(!GET_ALLOW_SHARE_DELETE(current_shares[i].share_mode))
1822 DEBUG(5,("call_trans2setfilepathinfo: refusing to set delete on close flag for fnum = %d, \
1823 file %s as a share exists that was not opened with FILE_DELETE access.\n",
1824 fsp->fnum, fsp->fsp_name ));
1829 unlock_share_entry_fsp(fsp);
1832 * current_shares was malloced by get_share_modes - free it here.
1835 free((char *)current_shares);
1838 * Even though share violation would be more appropriate here,
1839 * return ERRnoaccess as that's what NT does.
1842 return(ERROR(ERRDOS,ERRnoaccess));
1847 * current_shares was malloced by get_share_modes - free it here.
1850 free((char *)current_shares);
1852 DEBUG(10,("call_trans2setfilepathinfo: %s delete on close flag for fnum = %d, file %s\n",
1853 delete_on_close ? "Adding" : "Removing", fsp->fnum, fsp->fsp_name ));
1856 * Go through all files we have open on the same device and
1857 * inode (hanging off the same hash bucket) and set the DELETE_ON_CLOSE_FLAG.
1858 * Other smbd's that have this file open will have to fend for themselves. We
1859 * take care of this (rare) case in close_file(). See the comment there.
1862 for(iterate_fsp = file_find_di_first(dev, inode); iterate_fsp;
1863 iterate_fsp = file_find_di_next(iterate_fsp))
1865 int new_share_mode = (delete_on_close ?
1866 (iterate_fsp->share_mode | DELETE_ON_CLOSE_FLAG) :
1867 (iterate_fsp->share_mode & ~DELETE_ON_CLOSE_FLAG) );
1869 DEBUG(10,("call_trans2setfilepathinfo: Changing share mode for fnum %d, file %s \
1870 dev = %x, inode = %.0f from %x to %x\n",
1871 iterate_fsp->fnum, iterate_fsp->fsp_name, (unsigned int)dev,
1872 (double)inode, iterate_fsp->share_mode, new_share_mode ));
1874 if(modify_share_mode(iterate_fsp, new_share_mode, iterate_fsp->oplock_type)==False)
1875 DEBUG(0,("call_trans2setfilepathinfo: failed to change delete on close for fnum %d, \
1876 dev = %x, inode = %.0f\n", iterate_fsp->fnum, (unsigned int)dev, (double)inode));
1880 * Set the delete on close flag in the reference
1881 * counted struct. Delete when the last reference
1884 fsp->delete_on_close = delete_on_close;
1886 unlock_share_entry_fsp(fsp);
1888 DEBUG(10, ("call_trans2setfilepathinfo: %s delete on close flag for fnum = %d, file %s\n",
1889 delete_on_close ? "Added" : "Removed", fsp->fnum, fsp->fsp_name ));
1891 } /* end if(delete_on_close && !GET_DELETE_ON_CLOSE_FLAG(fsp->share_mode)) */
1892 } /* end if is_directory. */
1894 return(ERROR(ERRDOS,ERRunknownlevel));
1900 return(ERROR(ERRDOS,ERRunknownlevel));
1904 /* get some defaults (no modifications) if any info is zero or -1. */
1905 if (tvs.actime == (time_t)0 || tvs.actime == (time_t)-1)
1906 tvs.actime = st.st_atime;
1908 if (tvs.modtime == (time_t)0 || tvs.modtime == (time_t)-1)
1909 tvs.modtime = st.st_mtime;
1911 DEBUG(6,("actime: %s " , ctime(&tvs.actime)));
1912 DEBUG(6,("modtime: %s ", ctime(&tvs.modtime)));
1913 DEBUG(6,("size: %.0f ", (double)size));
1914 DEBUG(6,("mode: %x\n" , mode));
1916 if(!((info_level == SMB_SET_FILE_END_OF_FILE_INFO) ||
1917 (info_level == SMB_SET_FILE_ALLOCATION_INFO))) {
1919 * Only do this test if we are not explicitly
1920 * changing the size of a file.
1926 /* Try and set the times, size and mode of this file -
1927 if they are different from the current values
1929 if (st.st_mtime != tvs.modtime || st.st_atime != tvs.actime) {
1932 * This was a setfileinfo on an open file.
1933 * NT does this a lot. It's actually pointless
1934 * setting the time here, as it will be overwritten
1935 * on the next write, so we save the request
1936 * away and will set it on file code. JRA.
1939 if (tvs.modtime != (time_t)0 && tvs.modtime != (time_t)-1) {
1940 DEBUG(10,("call_trans2setfilepathinfo: setting pending modtime to %s\n",
1941 ctime(&tvs.modtime) ));
1942 fsp->pending_modtime = tvs.modtime;
1947 DEBUG(10,("call_trans2setfilepathinfo: setting utimes to modified values.\n"));
1949 if(file_utime(conn, fname, &tvs)!=0)
1950 return(UNIXERROR(ERRDOS,ERRnoaccess));
1954 /* check the mode isn't different, before changing it */
1955 if ((mode != 0) && (mode != dos_mode(conn, fname, &st))) {
1957 DEBUG(10,("call_trans2setfilepathinfo: file %s : setting dos mode %x\n",
1960 if(file_chmod(conn, fname, mode, NULL)) {
1961 DEBUG(2,("chmod of %s failed (%s)\n", fname, strerror(errno)));
1962 return(UNIXERROR(ERRDOS,ERRnoaccess));
1966 if(size != st.st_size) {
1968 DEBUG(10,("call_trans2setfilepathinfo: file %s : setting new size to %.0f\n",
1969 fname, (double)size ));
1972 fd = conn->vfs_ops.open(dos_to_unix(fname,False),O_RDWR,0);
1974 return(UNIXERROR(ERRDOS,ERRbadpath));
1975 set_filelen(fd, size); /* tpot vfs */
1976 conn->vfs_ops.close(fd);
1978 set_filelen(fd, size); /* tpot vfs */
1982 set_filelen_write_cache(fsp, size);
1987 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
1992 /****************************************************************************
1993 reply to a TRANS2_MKDIR (make directory with extended attributes).
1994 ****************************************************************************/
1995 static int call_trans2mkdir(connection_struct *conn,
1996 char *inbuf, char *outbuf, int length, int bufsize,
1997 char **pparams, char **ppdata)
1999 char *params = *pparams;
2002 BOOL bad_path = False;
2004 if (!CAN_WRITE(conn))
2005 return(ERROR(ERRSRV,ERRaccess));
2007 pstrcpy(directory, ¶ms[4]);
2009 DEBUG(3,("call_trans2mkdir : name = %s\n", directory));
2011 unix_convert(directory,conn,0,&bad_path,NULL);
2012 if (check_name(directory,conn))
2013 ret = conn->vfs_ops.mkdir(dos_to_unix(directory,False),
2014 unix_mode(conn,aDIR,directory));
2018 DEBUG(5,("call_trans2mkdir error (%s)\n", strerror(errno)));
2019 if((errno == ENOENT) && bad_path)
2021 unix_ERR_class = ERRDOS;
2022 unix_ERR_code = ERRbadpath;
2024 return(UNIXERROR(ERRDOS,ERRnoaccess));
2027 /* Realloc the parameter and data sizes */
2028 params = *pparams = Realloc(*pparams,2);
2030 return(ERROR(ERRDOS,ERRnomem));
2034 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
2039 /****************************************************************************
2040 reply to a TRANS2_FINDNOTIFYFIRST (start monitoring a directory for changes)
2041 We don't actually do this - we just send a null response.
2042 ****************************************************************************/
2043 static int call_trans2findnotifyfirst(connection_struct *conn,
2044 char *inbuf, char *outbuf,
2045 int length, int bufsize,
2046 char **pparams, char **ppdata)
2048 static uint16 fnf_handle = 257;
2049 char *params = *pparams;
2050 uint16 info_level = SVAL(params,4);
2052 DEBUG(3,("call_trans2findnotifyfirst - info_level %d\n", info_level));
2060 return(ERROR(ERRDOS,ERRunknownlevel));
2063 /* Realloc the parameter and data sizes */
2064 params = *pparams = Realloc(*pparams,6);
2066 return(ERROR(ERRDOS,ERRnomem));
2068 SSVAL(params,0,fnf_handle);
2069 SSVAL(params,2,0); /* No changes */
2070 SSVAL(params,4,0); /* No EA errors */
2077 send_trans2_replies(outbuf, bufsize, params, 6, *ppdata, 0);
2082 /****************************************************************************
2083 reply to a TRANS2_FINDNOTIFYNEXT (continue monitoring a directory for
2084 changes). Currently this does nothing.
2085 ****************************************************************************/
2086 static int call_trans2findnotifynext(connection_struct *conn,
2087 char *inbuf, char *outbuf,
2088 int length, int bufsize,
2089 char **pparams, char **ppdata)
2091 char *params = *pparams;
2093 DEBUG(3,("call_trans2findnotifynext\n"));
2095 /* Realloc the parameter and data sizes */
2096 params = *pparams = Realloc(*pparams,4);
2098 return(ERROR(ERRDOS,ERRnomem));
2100 SSVAL(params,0,0); /* No changes */
2101 SSVAL(params,2,0); /* No EA errors */
2103 send_trans2_replies(outbuf, bufsize, params, 4, *ppdata, 0);
2108 /****************************************************************************
2109 reply to a TRANS2_GET_DFS_REFERRAL - Shirish Kalele <kalele@veritas.com>
2110 ****************************************************************************/
2111 static int call_trans2getdfsreferral(connection_struct *conn, char* inbuf,
2112 char* outbuf, int length, int bufsize,
2113 char** pparams, char** ppdata)
2115 char *params = *pparams;
2116 enum remote_arch_types ra_type = get_remote_arch();
2117 BOOL NT_arch = ((ra_type == RA_WINNT) || (ra_type == RA_WIN2K));
2120 int max_referral_level = SVAL(params,0);
2123 DEBUG(10,("call_trans2getdfsreferral\n"));
2125 if(!lp_host_msdfs())
2126 return(ERROR(ERRDOS,ERRbadfunc));
2128 /* if pathname is in UNICODE, convert to DOS */
2129 /* NT always sends in UNICODE, may not set UNICODE flag */
2130 if(NT_arch || (SVAL(inbuf,smb_flg2) & FLAGS2_UNICODE_STRINGS))
2132 unistr_to_dos(pathname, ¶ms[2], sizeof(pathname));
2133 DEBUG(10,("UNICODE referral for %s\n",pathname));
2136 pstrcpy(pathname,¶ms[2]);
2138 if((reply_size = setup_dfs_referral(pathname,max_referral_level,ppdata)) < 0)
2139 return(ERROR(ERRDOS,ERRbadfile));
2141 SSVAL(outbuf,smb_flg2,SVAL(outbuf,smb_flg2) | FLAGS2_UNICODE_STRINGS |
2142 FLAGS2_DFS_PATHNAMES);
2143 send_trans2_replies(outbuf,bufsize,0,0,*ppdata,reply_size);
2149 /****************************************************************************
2150 reply to a SMBfindclose (stop trans2 directory search)
2151 ****************************************************************************/
2152 int reply_findclose(connection_struct *conn,
2153 char *inbuf,char *outbuf,int length,int bufsize)
2156 int dptr_num=SVALS(inbuf,smb_vwv0);
2158 DEBUG(3,("reply_findclose, dptr_num = %d\n", dptr_num));
2160 dptr_close(&dptr_num);
2162 outsize = set_message(outbuf,0,0,True);
2164 DEBUG(3,("SMBfindclose dptr_num = %d\n", dptr_num));
2169 /****************************************************************************
2170 reply to a SMBfindnclose (stop FINDNOTIFYFIRST directory search)
2171 ****************************************************************************/
2172 int reply_findnclose(connection_struct *conn,
2173 char *inbuf,char *outbuf,int length,int bufsize)
2178 dptr_num = SVAL(inbuf,smb_vwv0);
2180 DEBUG(3,("reply_findnclose, dptr_num = %d\n", dptr_num));
2182 /* We never give out valid handles for a
2183 findnotifyfirst - so any dptr_num is ok here.
2186 outsize = set_message(outbuf,0,0,True);
2188 DEBUG(3,("SMB_findnclose dptr_num = %d\n", dptr_num));
2194 /****************************************************************************
2195 reply to a SMBtranss2 - just ignore it!
2196 ****************************************************************************/
2197 int reply_transs2(connection_struct *conn,
2198 char *inbuf,char *outbuf,int length,int bufsize)
2200 DEBUG(4,("Ignoring transs2 of length %d\n",length));
2204 /****************************************************************************
2205 reply to a SMBtrans2
2206 ****************************************************************************/
2207 int reply_trans2(connection_struct *conn,
2208 char *inbuf,char *outbuf,int length,int bufsize)
2211 unsigned int total_params = SVAL(inbuf, smb_tpscnt);
2212 unsigned int total_data =SVAL(inbuf, smb_tdscnt);
2214 unsigned int max_param_reply = SVAL(inbuf, smb_mprcnt);
2215 unsigned int max_data_reply = SVAL(inbuf, smb_mdrcnt);
2216 unsigned int max_setup_fields = SVAL(inbuf, smb_msrcnt);
2217 BOOL close_tid = BITSETW(inbuf+smb_flags,0);
2218 BOOL no_final_response = BITSETW(inbuf+smb_flags,1);
2219 int32 timeout = IVALS(inbuf,smb_timeout);
2221 unsigned int suwcnt = SVAL(inbuf, smb_suwcnt);
2222 unsigned int tran_call = SVAL(inbuf, smb_setup0);
2223 char *params = NULL, *data = NULL;
2224 int num_params, num_params_sofar, num_data, num_data_sofar;
2226 if(global_oplock_break && (tran_call == TRANSACT2_OPEN)) {
2227 /* Queue this open message as we are the process of an
2230 DEBUG(2,("reply_trans2: queueing message trans2open due to being "));
2231 DEBUGADD(2,( "in oplock break state.\n"));
2233 push_oplock_pending_smb_message(inbuf, length);
2237 outsize = set_message(outbuf,0,0,True);
2239 /* All trans2 messages we handle have smb_sucnt == 1 - ensure this
2240 is so as a sanity check */
2242 DEBUG(2,("Invalid smb_sucnt in trans2 call\n"));
2243 return(ERROR(ERRSRV,ERRerror));
2246 /* Allocate the space for the maximum needed parameters and data */
2247 if (total_params > 0)
2248 params = (char *)malloc(total_params);
2250 data = (char *)malloc(total_data);
2252 if ((total_params && !params) || (total_data && !data)) {
2253 DEBUG(2,("Out of memory in reply_trans2\n"));
2258 return(ERROR(ERRDOS,ERRnomem));
2261 /* Copy the param and data bytes sent with this request into
2262 the params buffer */
2263 num_params = num_params_sofar = SVAL(inbuf,smb_pscnt);
2264 num_data = num_data_sofar = SVAL(inbuf, smb_dscnt);
2266 if (num_params > total_params || num_data > total_data)
2267 exit_server("invalid params in reply_trans2");
2270 memcpy( params, smb_base(inbuf) + SVAL(inbuf, smb_psoff), num_params);
2272 memcpy( data, smb_base(inbuf) + SVAL(inbuf, smb_dsoff), num_data);
2274 if(num_data_sofar < total_data || num_params_sofar < total_params) {
2275 /* We need to send an interim response then receive the rest
2276 of the parameter/data bytes */
2277 outsize = set_message(outbuf,0,0,True);
2278 send_smb(smbd_server_fd(),outbuf);
2280 while (num_data_sofar < total_data ||
2281 num_params_sofar < total_params) {
2284 ret = receive_next_smb(inbuf,bufsize,SMB_SECONDARY_WAIT);
2287 (CVAL(inbuf, smb_com) != SMBtranss2)) || !ret) {
2288 outsize = set_message(outbuf,0,0,True);
2290 DEBUG(0,("reply_trans2: Invalid secondary trans2 packet\n"));
2292 DEBUG(0,("reply_trans2: %s in getting secondary trans2 response.\n",
2293 (smb_read_error == READ_ERROR) ? "error" : "timeout" ));
2298 return(ERROR(ERRSRV,ERRerror));
2301 /* Revise total_params and total_data in case
2302 they have changed downwards */
2303 total_params = SVAL(inbuf, smb_tpscnt);
2304 total_data = SVAL(inbuf, smb_tdscnt);
2305 num_params_sofar += (num_params = SVAL(inbuf,smb_spscnt));
2306 num_data_sofar += ( num_data = SVAL(inbuf, smb_sdscnt));
2307 if (num_params_sofar > total_params || num_data_sofar > total_data)
2308 exit_server("data overflow in trans2");
2310 memcpy( ¶ms[ SVAL(inbuf, smb_spsdisp)],
2311 smb_base(inbuf) + SVAL(inbuf, smb_spsoff), num_params);
2312 memcpy( &data[SVAL(inbuf, smb_sdsdisp)],
2313 smb_base(inbuf)+ SVAL(inbuf, smb_sdsoff), num_data);
2317 if (Protocol >= PROTOCOL_NT1) {
2318 uint16 flg2 = SVAL(outbuf,smb_flg2);
2319 SSVAL(outbuf,smb_flg2,flg2 | 0x40); /* IS_LONG_NAME */
2322 /* Now we must call the relevant TRANS2 function */
2324 case TRANSACT2_OPEN:
2325 outsize = call_trans2open(conn,
2326 inbuf, outbuf, bufsize,
2330 case TRANSACT2_FINDFIRST:
2331 outsize = call_trans2findfirst(conn, inbuf, outbuf,
2332 bufsize, ¶ms, &data);
2335 case TRANSACT2_FINDNEXT:
2336 outsize = call_trans2findnext(conn, inbuf, outbuf,
2341 case TRANSACT2_QFSINFO:
2342 outsize = call_trans2qfsinfo(conn, inbuf, outbuf,
2343 length, bufsize, ¶ms,
2347 case TRANSACT2_SETFSINFO:
2348 outsize = call_trans2setfsinfo(conn, inbuf, outbuf,
2353 case TRANSACT2_QPATHINFO:
2354 case TRANSACT2_QFILEINFO:
2355 outsize = call_trans2qfilepathinfo(conn, inbuf, outbuf,
2357 ¶ms, &data, total_data);
2359 case TRANSACT2_SETPATHINFO:
2360 case TRANSACT2_SETFILEINFO:
2361 outsize = call_trans2setfilepathinfo(conn, inbuf, outbuf,
2367 case TRANSACT2_FINDNOTIFYFIRST:
2368 outsize = call_trans2findnotifyfirst(conn, inbuf, outbuf,
2373 case TRANSACT2_FINDNOTIFYNEXT:
2374 outsize = call_trans2findnotifynext(conn, inbuf, outbuf,
2378 case TRANSACT2_MKDIR:
2379 outsize = call_trans2mkdir(conn, inbuf, outbuf, length,
2380 bufsize, ¶ms, &data);
2383 case TRANSACT2_GET_DFS_REFERRAL:
2384 outsize = call_trans2getdfsreferral(conn,inbuf,outbuf,length,
2385 bufsize, ¶ms, &data);
2388 /* Error in request */
2389 DEBUG(2,("Unknown request %d in trans2 call\n", tran_call));
2394 return (ERROR(ERRSRV,ERRerror));
2397 /* As we do not know how many data packets will need to be
2398 returned here the various call_trans2xxxx calls
2399 must send their own. Thus a call_trans2xxx routine only
2400 returns a value other than -1 when it wants to send
2408 return outsize; /* If a correct response was needed the
2409 call_trans2xxx calls have already sent
2410 it. If outsize != -1 then it is returning */