2 Unix SMB/Netbios implementation.
4 SMB transaction2 handling
5 Copyright (C) Jeremy Allison 1994-1998
7 Extensively modified by Andrew Tridgell, 1995
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26 extern int DEBUGLEVEL;
28 extern BOOL case_sensitive;
29 extern int smb_read_error;
30 extern fstring local_machine;
31 extern int global_oplock_break;
32 extern uint32 global_client_caps;
33 extern pstring global_myname;
35 /****************************************************************************
36 Send the required number of replies back.
37 We assume all fields other than the data fields are
38 set correctly for the type of call.
39 HACK ! Always assumes smb_setup field is zero.
40 ****************************************************************************/
41 static int send_trans2_replies(char *outbuf, int bufsize, char *params,
42 int paramsize, char *pdata, int datasize)
44 /* As we are using a protocol > LANMAN1 then the max_send
45 variable must have been set in the sessetupX call.
46 This takes precedence over the max_xmit field in the
47 global struct. These different max_xmit variables should
48 be merged as this is now too confusing */
51 int data_to_send = datasize;
52 int params_to_send = paramsize;
56 int params_sent_thistime, data_sent_thistime, total_sent_thistime;
57 int alignment_offset = 3;
58 int data_alignment_offset = 0;
60 /* Initially set the wcnt area to be 10 - this is true for all
62 set_message(outbuf,10,0,True);
64 /* If there genuinely are no parameters or data to send just send
66 if(params_to_send == 0 && data_to_send == 0)
68 if (!send_smb(smbd_server_fd(),outbuf))
69 exit_server("send_trans2_replies: send_smb failed.\n");
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 if (!send_smb(smbd_server_fd(),outbuf))
165 exit_server("send_trans2_replies: send_smb failed.\n");
167 pp += params_sent_thistime;
168 pd += data_sent_thistime;
170 params_to_send -= params_sent_thistime;
171 data_to_send -= data_sent_thistime;
174 if(params_to_send < 0 || data_to_send < 0)
176 DEBUG(0,("send_trans2_replies failed sanity check pts = %d, dts = %d\n!!!",
177 params_to_send, data_to_send));
186 /****************************************************************************
187 reply to a TRANSACT2_OPEN
188 ****************************************************************************/
189 static int call_trans2open(connection_struct *conn, char *inbuf, char *outbuf,
191 char **pparams, char **ppdata)
193 char *params = *pparams;
194 int16 open_mode = SVAL(params, 2);
195 int16 open_attr = SVAL(params,6);
196 BOOL oplock_request = (((SVAL(params,0)|(1<<1))>>1) | ((SVAL(params,0)|(1<<2))>>1));
198 BOOL return_additional_info = BITSETW(params,0);
199 int16 open_sattr = SVAL(params, 4);
200 time_t open_time = make_unix_date3(params+8);
202 int16 open_ofun = SVAL(params,12);
203 int32 open_size = IVAL(params,14);
204 char *pname = ¶ms[28];
208 int fmode=0,mtime=0,rmode;
210 SMB_STRUCT_STAT sbuf;
212 BOOL bad_path = False;
215 srvstr_pull(inbuf, fname, pname, sizeof(fname), -1, STR_TERMINATE);
217 DEBUG(3,("trans2open %s mode=%d attr=%d ofun=%d size=%d\n",
218 fname,open_mode, open_attr, open_ofun, open_size));
221 return(ERROR(ERRSRV,ERRaccess));
224 /* XXXX we need to handle passed times, sattr and flags */
226 unix_convert(fname,conn,0,&bad_path,&sbuf);
228 if (!check_name(fname,conn))
230 if((errno == ENOENT) && bad_path)
232 unix_ERR_class = ERRDOS;
233 unix_ERR_code = ERRbadpath;
235 return(UNIXERROR(ERRDOS,ERRnoaccess));
238 unixmode = unix_mode(conn,open_attr | aARCH, fname);
240 fsp = open_file_shared(conn,fname,&sbuf,open_mode,open_ofun,unixmode,
241 oplock_request, &rmode,&smb_action);
245 if((errno == ENOENT) && bad_path)
247 unix_ERR_class = ERRDOS;
248 unix_ERR_code = ERRbadpath;
250 return(UNIXERROR(ERRDOS,ERRnoaccess));
254 fmode = dos_mode(conn,fname,&sbuf);
255 mtime = sbuf.st_mtime;
258 close_file(fsp,False);
259 return(ERROR(ERRDOS,ERRnoaccess));
262 /* Realloc the size of parameters and data we will return */
263 params = Realloc(*pparams, 28);
264 if( params == NULL ) {
265 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 void *inbuf, void *outbuf,
310 char *path_mask,int dirtype,int info_level,
311 int requires_resume_key,
312 BOOL dont_descend,char **ppdata,
313 char *base_data, int space_remaining,
314 BOOL *out_of_space, BOOL *got_exact_match,
319 SMB_STRUCT_STAT sbuf;
323 char *p, *q, *pdata = *ppdata;
329 time_t mdate=0, adate=0, cdate=0;
332 int nt_extmode; /* Used for NT connections instead of mode */
333 BOOL needslash = ( conn->dirpath[strlen(conn->dirpath) -1] != '/');
336 *out_of_space = False;
337 *got_exact_match = False;
342 p = strrchr_m(path_mask,'/');
351 pstrcpy(mask, path_mask);
357 /* Needed if we run out of space */
358 prev_dirpos = TellDir(conn->dirptr);
359 dname = ReadDirName(conn->dirptr);
362 * Due to bugs in NT client redirectors we are not using
363 * resume keys any more - set them to zero.
364 * Check out the related comments in findfirst/findnext.
370 DEBUG(8,("get_lanman2_dir_entry:readdir on dirptr 0x%lx now at offset %d\n",
371 (long)conn->dirptr,TellDir(conn->dirptr)));
376 pstrcpy(fname,dname);
378 if(!(got_match = *got_exact_match = exact_match(fname, mask, case_sensitive))) {
379 got_match = mask_match(fname, mask, case_sensitive);
382 if(!got_match && !is_8_3(fname, False)) {
385 * It turns out that NT matches wildcards against
386 * both long *and* short names. This may explain some
387 * of the wildcard wierdness from old DOS clients
388 * that some people have been seeing.... JRA.
392 pstrcpy( newname, fname);
393 name_map_mangle( newname, True, False, SNUM(conn));
394 if(!(got_match = *got_exact_match = exact_match(newname, mask, case_sensitive)))
395 got_match = mask_match(newname, mask, case_sensitive);
400 BOOL isdots = (strequal(fname,"..") || strequal(fname,"."));
401 if (dont_descend && !isdots)
404 pstrcpy(pathreal,conn->dirpath);
406 pstrcat(pathreal,"/");
407 pstrcat(pathreal,dname);
408 if (vfs_stat(conn,pathreal,&sbuf) != 0)
410 /* Needed to show the msdfs symlinks as directories */
411 if(!lp_host_msdfs() || !lp_msdfs_root(SNUM(conn))
412 || !is_msdfs_link(conn, pathreal))
414 DEBUG(5,("get_lanman2_dir_entry:Couldn't stat [%s] (%s)\n",
415 pathreal,strerror(errno)));
420 DEBUG(5,("get_lanman2_dir_entry: Masquerading msdfs link %s as a directory\n", pathreal));
421 sbuf.st_mode = (sbuf.st_mode & 0xFFF) | S_IFDIR;
425 mode = dos_mode(conn,pathreal,&sbuf);
427 if (!dir_check_ftype(conn,mode,&sbuf,dirtype)) {
428 DEBUG(5,("[%s] attribs didn't match %x\n",fname,dirtype));
433 mdate = sbuf.st_mtime;
434 adate = sbuf.st_atime;
435 cdate = get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(conn)));
437 if (lp_dos_filetime_resolution(SNUM(conn))) {
446 DEBUG(5,("get_lanman2_dir_entry found %s fname=%s\n",pathreal,fname));
452 name_map_mangle(fname,False,True,SNUM(conn));
457 nt_extmode = mode ? mode : FILE_ATTRIBUTE_NORMAL;
462 if(requires_resume_key) {
466 put_dos_date2(p,l1_fdateCreation,cdate);
467 put_dos_date2(p,l1_fdateLastAccess,adate);
468 put_dos_date2(p,l1_fdateLastWrite,mdate);
469 SIVAL(p,l1_cbFile,(uint32)size);
470 SIVAL(p,l1_cbFileAlloc,SMB_ROUNDUP(size,1024));
471 SSVAL(p,l1_attrFile,mode);
474 len = srvstr_push(outbuf, p, fname, -1, STR_TERMINATE);
481 if(requires_resume_key) {
485 put_dos_date2(p,l2_fdateCreation,cdate);
486 put_dos_date2(p,l2_fdateLastAccess,adate);
487 put_dos_date2(p,l2_fdateLastWrite,mdate);
488 SIVAL(p,l2_cbFile,(uint32)size);
489 SIVAL(p,l2_cbFileAlloc,SMB_ROUNDUP(size,1024));
490 SSVAL(p,l2_attrFile,mode);
491 SIVAL(p,l2_cbList,0); /* No extended attributes */
494 len = srvstr_push(outbuf, p, fname, -1,
502 put_dos_date2(p,4,cdate);
503 put_dos_date2(p,8,adate);
504 put_dos_date2(p,12,mdate);
505 SIVAL(p,16,(uint32)size);
506 SIVAL(p,20,SMB_ROUNDUP(size,1024));
511 len = srvstr_push(outbuf, p, fname, -1, STR_TERMINATE);
517 if(requires_resume_key) {
522 put_dos_date2(p,4,cdate);
523 put_dos_date2(p,8,adate);
524 put_dos_date2(p,12,mdate);
525 SIVAL(p,16,(uint32)size);
526 SIVAL(p,20,SMB_ROUNDUP(size,1024));
530 len = srvstr_push(outbuf, p, fname, -1, STR_TERMINATE);
533 SIVAL(q,4,PTR_DIFF(p, q));
537 case SMB_FIND_FILE_BOTH_DIRECTORY_INFO:
538 was_8_3 = is_8_3(fname, True);
540 SIVAL(p,0,reskey); p += 4;
541 put_long_date(p,cdate); p += 8;
542 put_long_date(p,adate); p += 8;
543 put_long_date(p,mdate); p += 8;
544 put_long_date(p,mdate); p += 8;
548 SIVAL(p,0,nt_extmode); p += 4;
550 SIVAL(p,0,0); p += 4;
552 pstring mangled_name;
553 pstrcpy(mangled_name, fname);
554 name_map_mangle(mangled_name,True,True,SNUM(conn));
555 mangled_name[12] = 0;
556 len = srvstr_push(outbuf, p+2, mangled_name, 24, STR_UPPER);
563 len = srvstr_push(outbuf, p, fname, -1, STR_TERMINATE);
566 len = PTR_DIFF(p, pdata);
567 len = (len + 3) & ~3;
572 case SMB_FIND_FILE_DIRECTORY_INFO:
574 SIVAL(p,0,reskey); p += 4;
575 put_long_date(p,cdate); p += 8;
576 put_long_date(p,adate); p += 8;
577 put_long_date(p,mdate); p += 8;
578 put_long_date(p,mdate); p += 8;
582 SIVAL(p,0,nt_extmode); p += 4;
584 len = srvstr_push(outbuf, p, fname, -1, STR_TERMINATE);
587 len = PTR_DIFF(p, pdata);
588 len = (len + 3) & ~3;
594 case SMB_FIND_FILE_FULL_DIRECTORY_INFO:
596 SIVAL(p,0,reskey); p += 4;
597 put_long_date(p,cdate); p += 8;
598 put_long_date(p,adate); p += 8;
599 put_long_date(p,mdate); p += 8;
600 put_long_date(p,mdate); p += 8;
604 SIVAL(p,0,nt_extmode); p += 4;
606 SIVAL(p,0,0); p += 4;
608 len = srvstr_push(outbuf, p, fname, -1, STR_TERMINATE);
612 len = PTR_DIFF(p, pdata);
613 len = (len + 3) & ~3;
618 case SMB_FIND_FILE_NAMES_INFO:
620 SIVAL(p,0,reskey); p += 4;
622 len = srvstr_push(outbuf, p, fname, -1, STR_TERMINATE);
625 len = PTR_DIFF(p, pdata);
626 len = (len + 3) & ~3;
636 if (PTR_DIFF(p,pdata) > space_remaining) {
637 /* Move the dirptr back to prev_dirpos */
638 SeekDir(conn->dirptr, prev_dirpos);
639 *out_of_space = True;
640 DEBUG(9,("get_lanman2_dir_entry: out of space\n"));
641 return False; /* Not finished - just out of space */
644 /* Setup the last_filename pointer, as an offset from base_data */
645 *last_name_off = PTR_DIFF(nameptr,base_data);
646 /* Advance the data pointer to the next slot */
653 /****************************************************************************
654 Reply to a TRANS2_FINDFIRST.
655 ****************************************************************************/
657 static int call_trans2findfirst(connection_struct *conn,
658 char *inbuf, char *outbuf, int bufsize,
659 char **pparams, char **ppdata)
661 /* We must be careful here that we don't return more than the
662 allowed number of data bytes. If this means returning fewer than
663 maxentries then so be it. We assume that the redirector has
664 enough room for the fixed number of parameter bytes it has
666 uint32 max_data_bytes = SVAL(inbuf, smb_mdrcnt);
667 char *params = *pparams;
668 char *pdata = *ppdata;
669 int dirtype = SVAL(params,0);
670 int maxentries = SVAL(params,2);
671 BOOL close_after_first = BITSETW(params+4,0);
672 BOOL close_if_end = BITSETW(params+4,1);
673 BOOL requires_resume_key = BITSETW(params+4,2);
674 int info_level = SVAL(params,6);
682 BOOL finished = False;
683 BOOL dont_descend = False;
684 BOOL out_of_space = False;
686 BOOL bad_path = False;
687 SMB_STRUCT_STAT sbuf;
689 *directory = *mask = 0;
691 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",
692 dirtype, maxentries, close_after_first, close_if_end, requires_resume_key,
693 info_level, max_data_bytes));
701 case SMB_FIND_FILE_DIRECTORY_INFO:
702 case SMB_FIND_FILE_FULL_DIRECTORY_INFO:
703 case SMB_FIND_FILE_NAMES_INFO:
704 case SMB_FIND_FILE_BOTH_DIRECTORY_INFO:
707 return(ERROR(ERRDOS,ERRunknownlevel));
710 srvstr_pull(inbuf, directory, params+12, sizeof(directory), -1, STR_TERMINATE);
712 RESOLVE_FINDFIRST_DFSPATH(directory, conn, inbuf, outbuf);
714 unix_convert(directory,conn,0,&bad_path,&sbuf);
715 if(!check_name(directory,conn)) {
716 if((errno == ENOENT) && bad_path)
718 unix_ERR_class = ERRDOS;
719 unix_ERR_code = ERRbadpath;
723 /* Ugly - NT specific hack - maybe not needed ? (JRA) */
724 if((errno == ENOTDIR) && (Protocol >= PROTOCOL_NT1) &&
725 (get_remote_arch() == RA_WINNT))
727 unix_ERR_class = ERRDOS;
728 unix_ERR_code = ERRbaddirectory;
732 return(UNIXERROR(ERRDOS,ERRbadpath));
735 p = strrchr_m(directory,'/');
737 pstrcpy(mask,directory);
738 pstrcpy(directory,"./");
744 DEBUG(5,("dir=%s, mask = %s\n",directory, mask));
746 pdata = Realloc(*ppdata, max_data_bytes + 1024);
747 if( pdata == NULL ) {
748 return(ERROR(ERRDOS,ERRnomem));
751 memset((char *)pdata,'\0',max_data_bytes + 1024);
753 /* Realloc the params space */
754 params = Realloc(*pparams, 10);
755 if( params == NULL ) {
756 return(ERROR(ERRDOS,ERRnomem));
760 dptr_num = dptr_create(conn,directory, False, True ,SVAL(inbuf,smb_pid));
762 return(UNIXERROR(ERRDOS,ERRbadfile));
764 /* Save the wildcard match and attribs we are using on this directory -
765 needed as lanman2 assumes these are being saved between calls */
767 if(!(wcard = strdup(mask))) {
768 dptr_close(&dptr_num);
769 return(ERROR(ERRDOS,ERRnomem));
772 dptr_set_wcard(dptr_num, wcard);
773 dptr_set_attr(dptr_num, dirtype);
775 DEBUG(4,("dptr_num is %d, wcard = %s, attr = %d\n",dptr_num, wcard, dirtype));
777 /* We don't need to check for VOL here as this is returned by
778 a different TRANS2 call. */
780 DEBUG(8,("dirpath=<%s> dontdescend=<%s>\n",
781 conn->dirpath,lp_dontdescend(SNUM(conn))));
782 if (in_list(conn->dirpath,lp_dontdescend(SNUM(conn)),case_sensitive))
786 space_remaining = max_data_bytes;
787 out_of_space = False;
789 for (i=0;(i<maxentries) && !finished && !out_of_space;i++)
791 BOOL got_exact_match = False;
793 /* this is a heuristic to avoid seeking the dirptr except when
794 absolutely necessary. It allows for a filename of about 40 chars */
795 if (space_remaining < DIRLEN_GUESS && numentries > 0)
802 finished = !get_lanman2_dir_entry(conn,
804 mask,dirtype,info_level,
805 requires_resume_key,dont_descend,
806 &p,pdata,space_remaining, &out_of_space, &got_exact_match,
810 if (finished && out_of_space)
813 if (!finished && !out_of_space)
817 * As an optimisation if we know we aren't looking
818 * for a wildcard name (ie. the name matches the wildcard exactly)
819 * then we can finish on any (first) match.
820 * This speeds up large directory searches. JRA.
826 space_remaining = max_data_bytes - PTR_DIFF(p,pdata);
829 /* Check if we can close the dirptr */
830 if(close_after_first || (finished && close_if_end))
832 DEBUG(5,("call_trans2findfirst - (2) closing dptr_num %d\n", dptr_num));
833 dptr_close(&dptr_num);
837 * If there are no matching entries we must return ERRDOS/ERRbadfile -
838 * from observation of NT.
843 dptr_close(&dptr_num);
844 return(ERROR(ERRDOS,ERRbadfile));
847 /* At this point pdata points to numentries directory entries. */
849 /* Set up the return parameter block */
850 SSVAL(params,0,dptr_num);
851 SSVAL(params,2,numentries);
852 SSVAL(params,4,finished);
853 SSVAL(params,6,0); /* Never an EA error */
854 SSVAL(params,8,last_name_off);
856 send_trans2_replies( outbuf, bufsize, params, 10, pdata, PTR_DIFF(p,pdata));
858 if ((! *directory) && dptr_path(dptr_num))
859 slprintf(directory,sizeof(directory)-1, "(%s)",dptr_path(dptr_num));
861 DEBUG( 4, ( "%s mask=%s directory=%s dirtype=%d numentries=%d\n",
862 smb_fn_name(CVAL(inbuf,smb_com)),
863 mask, directory, dirtype, numentries ) );
866 * Force a name mangle here to ensure that the
867 * mask as an 8.3 name is top of the mangled cache.
868 * The reasons for this are subtle. Don't remove
869 * this code unless you know what you are doing
870 * (see PR#13758). JRA.
873 if(!is_8_3( mask, False))
874 name_map_mangle(mask, True, True, SNUM(conn));
880 /****************************************************************************
881 reply to a TRANS2_FINDNEXT
882 ****************************************************************************/
883 static int call_trans2findnext(connection_struct *conn,
884 char *inbuf, char *outbuf,
885 int length, int bufsize,
886 char **pparams, char **ppdata)
888 /* We must be careful here that we don't return more than the
889 allowed number of data bytes. If this means returning fewer than
890 maxentries then so be it. We assume that the redirector has
891 enough room for the fixed number of parameter bytes it has
893 int max_data_bytes = SVAL(inbuf, smb_mdrcnt);
894 char *params = *pparams;
895 char *pdata = *ppdata;
896 int dptr_num = SVAL(params,0);
897 int maxentries = SVAL(params,2);
898 uint16 info_level = SVAL(params,4);
899 uint32 resume_key = IVAL(params,6);
900 BOOL close_after_request = BITSETW(params+10,0);
901 BOOL close_if_end = BITSETW(params+10,1);
902 BOOL requires_resume_key = BITSETW(params+10,2);
903 BOOL continue_bit = BITSETW(params+10,3);
910 int i, last_name_off=0;
911 BOOL finished = False;
912 BOOL dont_descend = False;
913 BOOL out_of_space = False;
916 *mask = *directory = *resume_name = 0;
918 srvstr_pull(inbuf, resume_name, params+12, sizeof(resume_name), -1, STR_TERMINATE);
920 DEBUG(3,("call_trans2findnext: dirhandle = %d, max_data_bytes = %d, maxentries = %d, \
921 close_after_request=%d, close_if_end = %d requires_resume_key = %d \
922 resume_key = %d resume name = %s continue=%d level = %d\n",
923 dptr_num, max_data_bytes, maxentries, close_after_request, close_if_end,
924 requires_resume_key, resume_key, resume_name, continue_bit, info_level));
932 case SMB_FIND_FILE_DIRECTORY_INFO:
933 case SMB_FIND_FILE_FULL_DIRECTORY_INFO:
934 case SMB_FIND_FILE_NAMES_INFO:
935 case SMB_FIND_FILE_BOTH_DIRECTORY_INFO:
938 return(ERROR(ERRDOS,ERRunknownlevel));
941 pdata = Realloc( *ppdata, max_data_bytes + 1024);
943 return(ERROR(ERRDOS,ERRnomem));
946 memset((char *)pdata,'\0',max_data_bytes + 1024);
948 /* Realloc the params space */
949 params = Realloc(*pparams, 6*SIZEOFWORD);
950 if( params == NULL ) {
951 return(ERROR(ERRDOS,ERRnomem));
955 /* Check that the dptr is valid */
956 if(!(conn->dirptr = dptr_fetch_lanman2(dptr_num)))
957 return(ERROR(ERRDOS,ERRnofiles));
959 string_set(&conn->dirpath,dptr_path(dptr_num));
961 /* Get the wildcard mask from the dptr */
962 if((p = dptr_wcard(dptr_num))== NULL) {
963 DEBUG(2,("dptr_num %d has no wildcard\n", dptr_num));
964 return (ERROR(ERRDOS,ERRnofiles));
967 pstrcpy(directory,conn->dirpath);
969 /* Get the attr mask from the dptr */
970 dirtype = dptr_attr(dptr_num);
972 DEBUG(3,("dptr_num is %d, mask = %s, attr = %x, dirptr=(0x%lX,%d)\n",
973 dptr_num, mask, dirtype,
975 TellDir(conn->dirptr)));
977 /* We don't need to check for VOL here as this is returned by
978 a different TRANS2 call. */
980 DEBUG(8,("dirpath=<%s> dontdescend=<%s>\n",conn->dirpath,lp_dontdescend(SNUM(conn))));
981 if (in_list(conn->dirpath,lp_dontdescend(SNUM(conn)),case_sensitive))
985 space_remaining = max_data_bytes;
986 out_of_space = False;
989 * Seek to the correct position. We no longer use the resume key but
990 * depend on the last file name instead.
992 if(requires_resume_key && *resume_name && !continue_bit)
995 * Fix for NT redirector problem triggered by resume key indexes
996 * changing between directory scans. We now return a resume key of 0
997 * and instead look for the filename to continue from (also given
998 * to us by NT/95/smbfs/smbclient). If no other scans have been done between the
999 * findfirst/findnext (as is usual) then the directory pointer
1000 * should already be at the correct place. Check this by scanning
1001 * backwards looking for an exact (ie. case sensitive) filename match.
1002 * If we get to the beginning of the directory and haven't found it then scan
1003 * forwards again looking for a match. JRA.
1006 int current_pos, start_pos;
1008 void *dirptr = conn->dirptr;
1009 start_pos = TellDir(dirptr);
1010 for(current_pos = start_pos; current_pos >= 0; current_pos--)
1012 DEBUG(7,("call_trans2findnext: seeking to pos %d\n", current_pos));
1014 SeekDir(dirptr, current_pos);
1015 dname = ReadDirName(dirptr);
1018 * Remember, name_map_mangle is called by
1019 * get_lanman2_dir_entry(), so the resume name
1020 * could be mangled. Ensure we do the same
1025 name_map_mangle( dname, False, True, SNUM(conn));
1027 if(dname && strcsequal( resume_name, dname))
1029 SeekDir(dirptr, current_pos+1);
1030 DEBUG(7,("call_trans2findnext: got match at pos %d\n", current_pos+1 ));
1036 * Scan forward from start if not found going backwards.
1041 DEBUG(7,("call_trans2findnext: notfound: seeking to pos %d\n", start_pos));
1042 SeekDir(dirptr, start_pos);
1043 for(current_pos = start_pos; (dname = ReadDirName(dirptr)) != NULL; SeekDir(dirptr,++current_pos))
1046 * Remember, name_map_mangle is called by
1047 * get_lanman2_dir_entry(), so the resume name
1048 * could be mangled. Ensure we do the same
1053 name_map_mangle( dname, False, True, SNUM(conn));
1055 if(dname && strcsequal( resume_name, dname))
1057 SeekDir(dirptr, current_pos+1);
1058 DEBUG(7,("call_trans2findnext: got match at pos %d\n", current_pos+1 ));
1062 } /* end if current_pos */
1063 } /* end if requires_resume_key && !continue_bit */
1065 for (i=0;(i<(int)maxentries) && !finished && !out_of_space ;i++)
1067 BOOL got_exact_match = False;
1069 /* this is a heuristic to avoid seeking the dirptr except when
1070 absolutely necessary. It allows for a filename of about 40 chars */
1071 if (space_remaining < DIRLEN_GUESS && numentries > 0)
1073 out_of_space = True;
1078 finished = !get_lanman2_dir_entry(conn,
1080 mask,dirtype,info_level,
1081 requires_resume_key,dont_descend,
1082 &p,pdata,space_remaining, &out_of_space, &got_exact_match,
1086 if (finished && out_of_space)
1089 if (!finished && !out_of_space)
1093 * As an optimisation if we know we aren't looking
1094 * for a wildcard name (ie. the name matches the wildcard exactly)
1095 * then we can finish on any (first) match.
1096 * This speeds up large directory searches. JRA.
1102 space_remaining = max_data_bytes - PTR_DIFF(p,pdata);
1105 /* Check if we can close the dirptr */
1106 if(close_after_request || (finished && close_if_end))
1108 DEBUG(5,("call_trans2findnext: closing dptr_num = %d\n", dptr_num));
1109 dptr_close(&dptr_num); /* This frees up the saved mask */
1113 /* Set up the return parameter block */
1114 SSVAL(params,0,numentries);
1115 SSVAL(params,2,finished);
1116 SSVAL(params,4,0); /* Never an EA error */
1117 SSVAL(params,6,last_name_off);
1119 send_trans2_replies( outbuf, bufsize, params, 8, pdata, PTR_DIFF(p,pdata));
1121 if ((! *directory) && dptr_path(dptr_num))
1122 slprintf(directory,sizeof(directory)-1, "(%s)",dptr_path(dptr_num));
1124 DEBUG( 3, ( "%s mask=%s directory=%s dirtype=%d numentries=%d\n",
1125 smb_fn_name(CVAL(inbuf,smb_com)),
1126 mask, directory, dirtype, numentries ) );
1131 /****************************************************************************
1132 reply to a TRANS2_QFSINFO (query filesystem info)
1133 ****************************************************************************/
1135 static int call_trans2qfsinfo(connection_struct *conn,
1136 char *inbuf, char *outbuf,
1137 int length, int bufsize,
1138 char **pparams, char **ppdata)
1140 int max_data_bytes = SVAL(inbuf, smb_mdrcnt);
1141 char *pdata = *ppdata;
1142 char *params = *pparams;
1143 uint16 info_level = SVAL(params,0);
1146 char *vname = volume_label(SNUM(conn));
1147 int snum = SNUM(conn);
1148 char *fstype = lp_fstype(SNUM(conn));
1150 DEBUG(3,("call_trans2qfsinfo: level = %d\n", info_level));
1152 if(vfs_stat(conn,".",&st)!=0) {
1153 DEBUG(2,("call_trans2qfsinfo: stat of . failed (%s)\n", strerror(errno)));
1154 return (ERROR(ERRSRV,ERRinvdevice));
1157 pdata = Realloc(*ppdata, max_data_bytes + 1024);
1158 if ( pdata == NULL ) {
1159 return(ERROR(ERRDOS,ERRnomem));
1162 memset((char *)pdata,'\0',max_data_bytes + 1024);
1168 SMB_BIG_UINT dfree,dsize,bsize;
1170 conn->vfs_ops.disk_free(conn,".",False,&bsize,&dfree,&dsize);
1171 SIVAL(pdata,l1_idFileSystem,st.st_dev);
1172 SIVAL(pdata,l1_cSectorUnit,bsize/512);
1173 SIVAL(pdata,l1_cUnit,dsize);
1174 SIVAL(pdata,l1_cUnitAvail,dfree);
1175 SSVAL(pdata,l1_cbSector,512);
1176 DEBUG(5,("call_trans2qfsinfo : bsize=%u, id=%x, cSectorUnit=%u, cUnit=%u, cUnitAvail=%u, cbSector=%d\n",
1177 (unsigned int)bsize, (unsigned int)st.st_dev, ((unsigned int)bsize)/512, (unsigned int)dsize,
1178 (unsigned int)dfree, 512));
1182 /* Return volume name */
1184 * Add volume serial number - hash of a combination of
1185 * the called hostname and the service name.
1187 SIVAL(pdata,0,str_checksum(lp_servicename(snum)) ^ (str_checksum(local_machine)<<16) );
1188 len = srvstr_push(outbuf, pdata+l2_vol_szVolLabel, vname, -1,
1190 SCVAL(pdata,l2_vol_cch,len);
1191 data_len = l2_vol_szVolLabel + len;
1192 DEBUG(5,("call_trans2qfsinfo : time = %x, namelen = %d, name = %s\n",
1193 (unsigned)st.st_ctime, len, vname));
1196 case SMB_QUERY_FS_ATTRIBUTE_INFO:
1197 SIVAL(pdata,0,FILE_CASE_PRESERVED_NAMES|FILE_CASE_SENSITIVE_SEARCH|
1198 FILE_DEVICE_IS_MOUNTED|
1199 (lp_nt_acl_support() ? FILE_PERSISTENT_ACLS : 0)); /* FS ATTRIBUTES */
1200 SIVAL(pdata,4,255); /* Max filename component length */
1201 len = srvstr_push(outbuf, pdata+12, fstype, -1, STR_TERMINATE);
1203 data_len = 12 + len;
1206 case SMB_QUERY_FS_LABEL_INFO:
1207 len = srvstr_push(outbuf, pdata+4, vname, -1, STR_TERMINATE);
1211 case SMB_QUERY_FS_VOLUME_INFO:
1213 * Add volume serial number - hash of a combination of
1214 * the called hostname and the service name.
1216 SIVAL(pdata,8,str_checksum(lp_servicename(snum)) ^
1217 (str_checksum(local_machine)<<16));
1219 len = srvstr_push(outbuf, pdata+18, vname, -1, STR_TERMINATE);
1220 SIVAL(pdata,12,len);
1222 DEBUG(5,("call_trans2qfsinfo : SMB_QUERY_FS_VOLUME_INFO namelen = %d, vol=%s serv=%s\n",
1223 (int)strlen(vname),vname, lp_servicename(snum)));
1225 case SMB_QUERY_FS_SIZE_INFO:
1227 SMB_BIG_UINT dfree,dsize,bsize;
1229 conn->vfs_ops.disk_free(conn,".",False,&bsize,&dfree,&dsize);
1230 SBIG_UINT(pdata,0,dsize);
1231 SBIG_UINT(pdata,8,dfree);
1232 SIVAL(pdata,16,bsize/512);
1233 SIVAL(pdata,20,512);
1236 case SMB_QUERY_FS_DEVICE_INFO:
1238 SIVAL(pdata,0,0); /* dev type */
1239 SIVAL(pdata,4,0); /* characteristics */
1241 case SMB_MAC_QUERY_FS_INFO:
1243 * Thursby MAC extension... ONLY on NTFS filesystems
1244 * once we do streams then we don't need this
1246 if (strequal(lp_fstype(SNUM(conn)),"NTFS")) {
1248 SIVAL(pdata,84,0x100); /* Don't support mac... */
1253 return(ERROR(ERRDOS,ERRunknownlevel));
1257 send_trans2_replies( outbuf, bufsize, params, 0, pdata, data_len);
1259 DEBUG( 4, ( "%s info_level = %d\n",
1260 smb_fn_name(CVAL(inbuf,smb_com)), info_level) );
1265 /****************************************************************************
1266 reply to a TRANS2_SETFSINFO (set filesystem info)
1267 ****************************************************************************/
1268 static int call_trans2setfsinfo(connection_struct *conn,
1269 char *inbuf, char *outbuf, int length,
1271 char **pparams, char **ppdata)
1273 /* Just say yes we did it - there is nothing that
1274 can be set here so it doesn't matter. */
1276 DEBUG(3,("call_trans2setfsinfo\n"));
1278 if (!CAN_WRITE(conn))
1279 return(ERROR(ERRSRV,ERRaccess));
1281 outsize = set_message(outbuf,10,0,True);
1286 /****************************************************************************
1287 Reply to a TRANS2_QFILEPATHINFO or TRANSACT2_QFILEINFO (query file info by
1288 file name or file id).
1289 ****************************************************************************/
1291 static int call_trans2qfilepathinfo(connection_struct *conn,
1292 char *inbuf, char *outbuf, int length,
1294 char **pparams,char **ppdata,
1297 int max_data_bytes = SVAL(inbuf, smb_mdrcnt);
1298 char *params = *pparams;
1299 char *pdata = *ppdata;
1300 uint16 tran_call = SVAL(inbuf, smb_setup0);
1304 unsigned int data_size;
1305 SMB_STRUCT_STAT sbuf;
1310 BOOL bad_path = False;
1311 BOOL delete_pending = False;
1315 if (tran_call == TRANSACT2_QFILEINFO) {
1316 files_struct *fsp = file_fsp(params,0);
1317 info_level = SVAL(params,2);
1319 DEBUG(3,("call_trans2qfilepathinfo: TRANSACT2_QFILEINFO: level = %d\n",
1322 if(fsp && (fsp->is_directory || fsp->stat_open)) {
1324 * This is actually a QFILEINFO on a directory
1325 * handle (returned from an NT SMB). NT5.0 seems
1326 * to do this call. JRA.
1328 pstrcpy(fname, fsp->fsp_name);
1329 unix_convert(fname,conn,0,&bad_path,&sbuf);
1330 if (!check_name(fname,conn) ||
1331 (!VALID_STAT(sbuf) && vfs_stat(conn,fname,&sbuf))) {
1332 DEBUG(3,("fileinfo of %s failed (%s)\n",fname,strerror(errno)));
1333 if((errno == ENOENT) && bad_path) {
1334 unix_ERR_class = ERRDOS;
1335 unix_ERR_code = ERRbadpath;
1337 return(UNIXERROR(ERRDOS,ERRbadpath));
1340 delete_pending = fsp->directory_delete_on_close;
1343 * Original code - this is an open file.
1345 CHECK_FSP(fsp,conn);
1348 pstrcpy(fname, fsp->fsp_name);
1349 if (vfs_fstat(fsp,fsp->fd,&sbuf) != 0) {
1350 DEBUG(3,("fstat of fnum %d failed (%s)\n",
1351 fsp->fnum, strerror(errno)));
1352 return(UNIXERROR(ERRDOS,ERRbadfid));
1354 if((pos = fsp->conn->vfs_ops.lseek(fsp,fsp->fd,0,SEEK_CUR)) == -1)
1355 return(UNIXERROR(ERRDOS,ERRnoaccess));
1357 delete_pending = fsp->delete_on_close;
1361 info_level = SVAL(params,0);
1363 DEBUG(3,("call_trans2qfilepathinfo: TRANSACT2_QPATHINFO: level = %d\n",
1366 srvstr_pull(inbuf, fname, ¶ms[6], sizeof(fname), -1, STR_TERMINATE);
1368 RESOLVE_DFSPATH(fname, conn, inbuf, outbuf);
1370 unix_convert(fname,conn,0,&bad_path,&sbuf);
1371 if (!check_name(fname,conn) ||
1372 (!VALID_STAT(sbuf) && vfs_stat(conn,fname,&sbuf))) {
1373 DEBUG(3,("fileinfo of %s failed (%s)\n",fname,strerror(errno)));
1374 if((errno == ENOENT) && bad_path) {
1375 unix_ERR_class = ERRDOS;
1376 unix_ERR_code = ERRbadpath;
1378 return(UNIXERROR(ERRDOS,ERRbadpath));
1383 DEBUG(3,("call_trans2qfilepathinfo %s level=%d call=%d total_data=%d\n",
1384 fname,info_level,tran_call,total_data));
1386 p = strrchr_m(fname,'/');
1393 mode = dos_mode(conn,fname,&sbuf);
1394 size = sbuf.st_size;
1395 if (mode & aDIR) size = 0;
1397 params = Realloc(*pparams,2);
1398 if (params == NULL) {
1399 return(ERROR(ERRDOS,ERRnomem));
1402 memset((char *)params,'\0',2);
1403 data_size = max_data_bytes + 1024;
1404 pdata = Realloc(*ppdata, data_size);
1405 if ( pdata == NULL ) {
1406 return(ERROR(ERRDOS,ERRnomem));
1410 if (total_data > 0 && IVAL(pdata,0) == total_data) {
1411 /* uggh, EAs for OS2 */
1412 DEBUG(4,("Rejecting EA request with total_data=%d\n",total_data));
1413 return(ERROR(ERRDOS,ERROR_EAS_NOT_SUPPORTED));
1416 memset((char *)pdata,'\0',data_size);
1418 c_time = get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(conn)));
1420 if (lp_dos_filetime_resolution(SNUM(conn))) {
1422 sbuf.st_atime &= ~1;
1423 sbuf.st_mtime &= ~1;
1424 sbuf.st_mtime &= ~1;
1429 case SMB_INFO_STANDARD:
1430 case SMB_INFO_QUERY_EA_SIZE:
1431 data_size = (info_level==1?22:26);
1432 put_dos_date2(pdata,l1_fdateCreation,c_time);
1433 put_dos_date2(pdata,l1_fdateLastAccess,sbuf.st_atime);
1434 put_dos_date2(pdata,l1_fdateLastWrite,sbuf.st_mtime); /* write time */
1435 SIVAL(pdata,l1_cbFile,(uint32)size);
1436 SIVAL(pdata,l1_cbFileAlloc,SMB_ROUNDUP(size,1024));
1437 SSVAL(pdata,l1_attrFile,mode);
1438 SIVAL(pdata,l1_attrFile+2,4); /* this is what OS2 does */
1441 case SMB_INFO_QUERY_EAS_FROM_LIST:
1443 put_dos_date2(pdata,0,c_time);
1444 put_dos_date2(pdata,4,sbuf.st_atime);
1445 put_dos_date2(pdata,8,sbuf.st_mtime);
1446 SIVAL(pdata,12,(uint32)size);
1447 SIVAL(pdata,16,SMB_ROUNDUP(size,1024));
1448 SIVAL(pdata,20,mode);
1451 case SMB_INFO_QUERY_ALL_EAS:
1453 SIVAL(pdata,0,data_size);
1457 return(ERROR(ERRDOS,ERRbadfunc)); /* os/2 needs this */
1459 case SMB_QUERY_FILE_BASIC_INFO:
1462 if (info_level == SMB_QUERY_FILE_BASIC_INFO)
1463 data_size = 36; /* w95 returns 40 bytes not 36 - why ?. */
1468 put_long_date(pdata,c_time);
1469 put_long_date(pdata+8,sbuf.st_atime);
1470 put_long_date(pdata+16,sbuf.st_mtime); /* write time */
1471 put_long_date(pdata+24,sbuf.st_mtime); /* change time */
1472 SIVAL(pdata,32,mode);
1474 DEBUG(5,("SMB_QFBI - "));
1476 time_t create_time = c_time;
1477 DEBUG(5,("create: %s ", ctime(&create_time)));
1479 DEBUG(5,("access: %s ", ctime(&sbuf.st_atime)));
1480 DEBUG(5,("write: %s ", ctime(&sbuf.st_mtime)));
1481 DEBUG(5,("change: %s ", ctime(&sbuf.st_mtime)));
1482 DEBUG(5,("mode: %x\n", mode));
1486 case SMB_QUERY_FILE_STANDARD_INFO:
1488 SOFF_T(pdata,0,size);
1489 SOFF_T(pdata,8,size);
1490 SIVAL(pdata,16,sbuf.st_nlink);
1492 CVAL(pdata,21) = (mode&aDIR)?1:0;
1495 case SMB_QUERY_FILE_EA_INFO:
1499 /* Get the 8.3 name - used if NT SMB was negotiated. */
1500 case SMB_QUERY_FILE_ALT_NAME_INFO:
1504 pstrcpy(short_name,base_name);
1505 /* Mangle if not already 8.3 */
1506 if(!is_8_3(short_name, True))
1508 if(!name_map_mangle(short_name,True,True,SNUM(conn)))
1511 len = srvstr_push(outbuf, pdata+4, short_name, -1,
1512 STR_TERMINATE|STR_UPPER);
1513 data_size = 4 + len;
1518 case SMB_QUERY_FILE_NAME_INFO:
1520 * The first part of this code is essential
1521 * to get security descriptors to work on mapped
1522 * drives. Don't ask how I discovered this unless
1523 * you like hearing about me suffering.... :-). JRA.
1525 if(strequal(".", fname)) {
1526 len = srvstr_push(outbuf, pdata+4, "\\", -1, STR_TERMINATE);
1528 len = srvstr_push(outbuf, pdata+4, fname, -1, STR_TERMINATE);
1530 data_size = 4 + len;
1534 case SMB_QUERY_FILE_ALLOCATION_INFO:
1535 case SMB_QUERY_FILE_END_OF_FILEINFO:
1537 SOFF_T(pdata,0,size);
1540 case SMB_QUERY_FILE_ALL_INFO:
1541 put_long_date(pdata,c_time);
1542 put_long_date(pdata+8,sbuf.st_atime);
1543 put_long_date(pdata+16,sbuf.st_mtime); /* write time */
1544 put_long_date(pdata+24,sbuf.st_mtime); /* change time */
1545 SIVAL(pdata,32,mode);
1547 SOFF_T(pdata,0,size);
1548 SOFF_T(pdata,8,size);
1549 SIVAL(pdata,16,sbuf.st_nlink);
1550 CVAL(pdata,20) = delete_pending;
1551 CVAL(pdata,21) = (mode&aDIR)?1:0;
1553 SINO_T(pdata,0,(SMB_INO_T)sbuf.st_ino);
1554 pdata += 8; /* index number */
1555 pdata += 4; /* EA info */
1557 SIVAL(pdata,0,0xA9);
1559 SIVAL(pdata,0,0xd01BF);
1561 SOFF_T(pdata,0,pos); /* current offset */
1563 SIVAL(pdata,0,mode); /* is this the right sort of mode info? */
1565 pdata += 4; /* alignment */
1566 len = srvstr_push(outbuf, pdata+4, fname, -1, STR_TERMINATE);
1569 data_size = PTR_DIFF(pdata,(*ppdata));
1573 * Windows 2000 completely undocumented new SMB info levels.
1574 * Thanks Microsoft.... sure you're working on making this
1575 * protocol a standard.... sure you are... :-).
1576 * Lying rat-bastards. JRA.
1580 SIVAL(pdata,0,mode);
1581 SIVAL(pdata,4,0); /* ??? */
1582 SOFF_T(pdata,8,size);
1583 SIVAL(pdata,16,1); /* ??? */
1584 SIVAL(pdata,20,0); /* ??? */
1589 SIVAL(pdata,0,0x907); /* ??? */
1590 SIVAL(pdata,4,0x690000); /* ??? */
1595 SIVAL(pdata,0,0); /* ??? */
1600 SIVAL(pdata,0,0x12019F); /* ??? */
1605 /* Pathname with leading '\'. */
1610 pstrcpy(new_fname, "\\");
1611 pstrcat(new_fname, fname);
1612 byte_len = dos_PutUniCode(pdata+4,new_fname,max_data_bytes,False);
1613 SIVAL(pdata,0,byte_len);
1614 data_size = 4 + byte_len;
1619 SIVAL(pdata,0,0); /* ??? */
1620 SIVAL(pdata,4,0); /* ??? */
1625 SIVAL(pdata,0,0); /* ??? */
1630 SIVAL(pdata,0,0); /* ??? */
1635 /* Not yet finished... JRA */
1641 put_long_date(pdata,c_time);
1642 put_long_date(pdata+8,sbuf.st_atime);
1643 put_long_date(pdata+16,sbuf.st_mtime); /* write time */
1644 put_long_date(pdata+24,sbuf.st_mtime); /* change time */
1645 SIVAL(pdata,32,mode);
1646 SIVAL(pdata,36,0); /* ??? */
1647 SIVAL(pdata,40,0x20); /* ??? */
1648 SIVAL(pdata,44,0); /* ??? */
1649 SOFF_T(pdata,48,size);
1650 SIVAL(pdata,56,0x1); /* ??? */
1651 SIVAL(pdata,60,0); /* ??? */
1652 SIVAL(pdata,64,0); /* ??? */
1653 SIVAL(pdata,68,length); /* Following string length in bytes. */
1654 dos_PutUniCode(pdata+72,,False);
1660 /* Last component of pathname. */
1662 size_t byte_len = dos_PutUniCode(pdata+4,fname,max_data_bytes,False);
1663 SIVAL(pdata,0,byte_len);
1664 data_size = 4 + byte_len;
1670 size_t byte_len = dos_PutUniCode(pdata+24,"::$DATA", 0xE, False);
1671 SIVAL(pdata,0,0); /* ??? */
1672 SIVAL(pdata,4,byte_len); /* Byte length of unicode string ::$DATA */
1673 SOFF_T(pdata,8,size);
1674 SIVAL(pdata,16,0x20); /* ??? */
1675 SIVAL(pdata,20,0); /* ??? */
1676 data_size = 24 + byte_len;
1681 SOFF_T(pdata,0,size);
1682 SIVAL(pdata,8,0); /* ??? */
1683 SIVAL(pdata,12,0); /* ??? */
1688 put_long_date(pdata,c_time);
1689 put_long_date(pdata+8,sbuf.st_atime);
1690 put_long_date(pdata+16,sbuf.st_mtime); /* write time */
1691 put_long_date(pdata+24,sbuf.st_mtime); /* change time */
1692 SIVAL(pdata,32,0x20); /* ??? */
1693 SIVAL(pdata,36,0); /* ??? */
1694 SOFF_T(pdata,40,size);
1695 SIVAL(pdata,48,mode);
1696 SIVAL(pdata,52,0); /* ??? */
1701 SIVAL(pdata,0,mode);
1707 * End new completely undocumented info levels... JRA.
1711 /* NT4 server just returns "invalid query" to this - if we try to answer
1712 it then NTws gets a BSOD! (tridge) */
1713 case SMB_QUERY_FILE_STREAM_INFO:
1715 SIVAL(pdata,4,size);
1716 SIVAL(pdata,12,size);
1717 len = srvstr_push(outbuf, pdata+24, fname, -1, STR_TERMINATE);
1718 SIVAL(pdata,20,len);
1719 data_size = 24 + len;
1724 return(ERROR(ERRDOS,ERRunknownlevel));
1727 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, data_size);
1732 /****************************************************************************
1733 reply to a TRANS2_SETFILEINFO (set file info by fileid)
1734 ****************************************************************************/
1735 static int call_trans2setfilepathinfo(connection_struct *conn,
1736 char *inbuf, char *outbuf, int length,
1737 int bufsize, char **pparams,
1738 char **ppdata, int total_data)
1740 char *params = *pparams;
1741 char *pdata = *ppdata;
1742 uint16 tran_call = SVAL(inbuf, smb_setup0);
1747 SMB_STRUCT_STAT sbuf;
1750 BOOL bad_path = False;
1751 files_struct *fsp = NULL;
1753 if (tran_call == TRANSACT2_SETFILEINFO) {
1754 fsp = file_fsp(params,0);
1755 info_level = SVAL(params,2);
1757 if(fsp && (fsp->is_directory || fsp->stat_open)) {
1759 * This is actually a SETFILEINFO on a directory
1760 * handle (returned from an NT SMB). NT5.0 seems
1761 * to do this call. JRA.
1763 pstrcpy(fname, fsp->fsp_name);
1764 unix_convert(fname,conn,0,&bad_path,&sbuf);
1765 if (!check_name(fname,conn) || (!VALID_STAT(sbuf))) {
1766 DEBUG(3,("fileinfo of %s failed (%s)\n",fname,strerror(errno)));
1767 if((errno == ENOENT) && bad_path)
1769 unix_ERR_class = ERRDOS;
1770 unix_ERR_code = ERRbadpath;
1772 return(UNIXERROR(ERRDOS,ERRbadpath));
1774 } else if (fsp->print_file) {
1776 * Doing a DELETE_ON_CLOSE should cancel a print job.
1778 if ((info_level == SMB_SET_FILE_DISPOSITION_INFO) && CVAL(pdata,0)) {
1779 fsp->share_mode = FILE_DELETE_ON_CLOSE;
1781 DEBUG(3,("call_trans2setfilepathinfo: Cancelling print job (%s)\n",
1785 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
1790 * Original code - this is an open file.
1792 CHECK_FSP(fsp,conn);
1795 pstrcpy(fname, fsp->fsp_name);
1798 if (vfs_fstat(fsp,fd,&sbuf) != 0) {
1799 DEBUG(3,("fstat of fnum %d failed (%s)\n",fsp->fnum, strerror(errno)));
1800 return(UNIXERROR(ERRDOS,ERRbadfid));
1805 info_level = SVAL(params,0);
1806 srvstr_pull(inbuf, fname, ¶ms[6], sizeof(fname), -1, STR_TERMINATE);
1807 unix_convert(fname,conn,0,&bad_path,&sbuf);
1808 if(!check_name(fname, conn))
1810 if((errno == ENOENT) && bad_path)
1812 unix_ERR_class = ERRDOS;
1813 unix_ERR_code = ERRbadpath;
1815 return(UNIXERROR(ERRDOS,ERRbadpath));
1818 if(!VALID_STAT(sbuf)) {
1819 DEBUG(3,("stat of %s failed (%s)\n", fname, strerror(errno)));
1820 if((errno == ENOENT) && bad_path)
1822 unix_ERR_class = ERRDOS;
1823 unix_ERR_code = ERRbadpath;
1825 return(UNIXERROR(ERRDOS,ERRbadpath));
1829 if (!CAN_WRITE(conn))
1830 return(ERROR(ERRSRV,ERRaccess));
1832 DEBUG(3,("call_trans2setfilepathinfo(%d) %s info_level=%d totdata=%d\n",
1833 tran_call,fname,info_level,total_data));
1835 /* Realloc the parameter and data sizes */
1836 params = Realloc(*pparams,2);
1837 if(params == NULL) {
1838 return(ERROR(ERRDOS,ERRnomem));
1844 size = sbuf.st_size;
1845 tvs.modtime = sbuf.st_mtime;
1846 tvs.actime = sbuf.st_atime;
1847 mode = dos_mode(conn,fname,&sbuf);
1849 if (total_data > 4 && IVAL(pdata,0) == total_data) {
1850 /* uggh, EAs for OS2 */
1851 DEBUG(4,("Rejecting EA request with total_data=%d\n",total_data));
1852 return(ERROR(ERRDOS,ERROR_EAS_NOT_SUPPORTED));
1857 case SMB_INFO_STANDARD:
1858 case SMB_INFO_QUERY_EA_SIZE:
1861 tvs.actime = make_unix_date2(pdata+l1_fdateLastAccess);
1864 tvs.modtime = make_unix_date2(pdata+l1_fdateLastWrite);
1866 mode = SVAL(pdata,l1_attrFile);
1867 size = IVAL(pdata,l1_cbFile);
1871 /* XXXX um, i don't think this is right.
1872 it's also not in the cifs6.txt spec.
1874 case SMB_INFO_QUERY_EAS_FROM_LIST:
1875 tvs.actime = make_unix_date2(pdata+8);
1876 tvs.modtime = make_unix_date2(pdata+12);
1877 size = IVAL(pdata,16);
1878 mode = IVAL(pdata,24);
1881 /* XXXX nor this. not in cifs6.txt, either. */
1882 case SMB_INFO_QUERY_ALL_EAS:
1883 tvs.actime = make_unix_date2(pdata+8);
1884 tvs.modtime = make_unix_date2(pdata+12);
1885 size = IVAL(pdata,16);
1886 mode = IVAL(pdata,24);
1889 case SMB_SET_FILE_BASIC_INFO:
1892 /* Patch to do this correctly from Paul Eggert <eggert@twinsun.com>. */
1894 time_t changed_time;
1896 /* Ignore create time at offset pdata. */
1899 tvs.actime = interpret_long_date(pdata+8);
1901 write_time = interpret_long_date(pdata+16);
1902 changed_time = interpret_long_date(pdata+24);
1904 tvs.modtime = MIN(write_time, changed_time);
1906 /* Prefer a defined time to an undefined one. */
1907 if (tvs.modtime == (time_t)0 || tvs.modtime == (time_t)-1)
1908 tvs.modtime = (write_time == (time_t)0 || write_time == (time_t)-1
1913 mode = IVAL(pdata,32);
1918 * NT seems to use this call with a size of zero
1919 * to mean truncate the file. JRA.
1924 case SMB_SET_FILE_ALLOCATION_INFO:
1926 SMB_OFF_T newsize = IVAL(pdata,0);
1927 #ifdef LARGE_SMB_OFF_T
1928 newsize |= (((SMB_OFF_T)IVAL(pdata,4)) << 32);
1929 #else /* LARGE_SMB_OFF_T */
1930 if (IVAL(pdata,4) != 0) /* more than 32 bits? */
1931 return(ERROR(ERRDOS,ERRunknownlevel));
1932 #endif /* LARGE_SMB_OFF_T */
1933 DEBUG(10,("call_trans2setfilepathinfo: Set file allocation info for file %s to %.0f\n", fname, (double)newsize ));
1939 case SMB_SET_FILE_END_OF_FILE_INFO:
1941 size = IVAL(pdata,0);
1942 #ifdef LARGE_SMB_OFF_T
1943 size |= (((SMB_OFF_T)IVAL(pdata,4)) << 32);
1944 #else /* LARGE_SMB_OFF_T */
1945 if (IVAL(pdata,4) != 0) /* more than 32 bits? */
1946 return(ERROR(ERRDOS,ERRunknownlevel));
1947 #endif /* LARGE_SMB_OFF_T */
1948 DEBUG(10,("call_trans2setfilepathinfo: Set end of file info for file %s to %.0f\n", fname, (double)size ));
1952 case SMB_SET_FILE_DISPOSITION_INFO: /* Set delete on close for open file. */
1954 BOOL delete_on_close = (CVAL(pdata,0) ? True : False);
1956 if (tran_call != TRANSACT2_SETFILEINFO)
1957 return(ERROR(ERRDOS,ERRunknownlevel));
1960 return(UNIXERROR(ERRDOS,ERRbadfid));
1963 * Only allow delete on close for files/directories opened with delete intent.
1966 if (delete_on_close && !GET_DELETE_ACCESS_REQUESTED(fsp->share_mode)) {
1967 DEBUG(10,("call_trans2setfilepathinfo: file %s delete on close flag set but delete access denied.\n",
1969 return(ERROR(ERRDOS,ERRnoaccess));
1972 if(fsp->is_directory) {
1973 fsp->directory_delete_on_close = delete_on_close;
1974 DEBUG(10, ("call_trans2setfilepathinfo: %s delete on close flag for fnum = %d, directory %s\n",
1975 delete_on_close ? "Added" : "Removed", fsp->fnum, fsp->fsp_name ));
1976 } else if(fsp->stat_open) {
1978 DEBUG(10, ("call_trans2setfilepathinfo: %s delete on close flag for fnum = %d, stat open %s\n",
1979 delete_on_close ? "Added" : "Removed", fsp->fnum, fsp->fsp_name ));
1983 files_struct *iterate_fsp;
1986 * Modify the share mode entry for all files open
1987 * on this device and inode to tell other smbds we have
1988 * changed the delete on close flag. This will be noticed
1989 * in the close code, the last closer will delete the file
1993 DEBUG(10,("call_trans2setfilepathinfo: %s delete on close flag for fnum = %d, file %s\n",
1994 delete_on_close ? "Adding" : "Removing", fsp->fnum, fsp->fsp_name ));
1996 if (lock_share_entry_fsp(fsp) == False)
1997 return(ERROR(ERRDOS,ERRnoaccess));
1999 if (!modify_delete_flag(fsp->dev, fsp->inode, delete_on_close)) {
2000 DEBUG(0,("call_trans2setfilepathinfo: failed to change delete on close flag for file %s\n",
2002 unlock_share_entry_fsp(fsp);
2003 return(ERROR(ERRDOS,ERRnoaccess));
2010 unlock_share_entry_fsp(fsp);
2013 * Go through all files we have open on the same device and
2014 * inode (hanging off the same hash bucket) and set the DELETE_ON_CLOSE_FLAG.
2015 * Other smbd's that have this file open will look in the share_mode on close.
2016 * take care of this (rare) case in close_file(). See the comment there.
2017 * NB. JRA. We don't really need to do this anymore - all should be taken
2018 * care of in the share_mode changes in the tdb.
2021 for(iterate_fsp = file_find_di_first(fsp->dev, fsp->inode);
2022 iterate_fsp; iterate_fsp = file_find_di_next(iterate_fsp))
2023 fsp->delete_on_close = delete_on_close;
2026 * Set the delete on close flag in the fsp.
2028 fsp->delete_on_close = delete_on_close;
2030 DEBUG(10, ("call_trans2setfilepathinfo: %s delete on close flag for fnum = %d, file %s\n",
2031 delete_on_close ? "Added" : "Removed", fsp->fnum, fsp->fsp_name ));
2040 return(ERROR(ERRDOS,ERRunknownlevel));
2044 /* get some defaults (no modifications) if any info is zero or -1. */
2045 if (tvs.actime == (time_t)0 || tvs.actime == (time_t)-1)
2046 tvs.actime = sbuf.st_atime;
2048 if (tvs.modtime == (time_t)0 || tvs.modtime == (time_t)-1)
2049 tvs.modtime = sbuf.st_mtime;
2051 DEBUG(6,("actime: %s " , ctime(&tvs.actime)));
2052 DEBUG(6,("modtime: %s ", ctime(&tvs.modtime)));
2053 DEBUG(6,("size: %.0f ", (double)size));
2054 DEBUG(6,("mode: %x\n" , mode));
2056 if(!((info_level == SMB_SET_FILE_END_OF_FILE_INFO) ||
2057 (info_level == SMB_SET_FILE_ALLOCATION_INFO) ||
2058 (info_level == 1019) ||
2059 (info_level == 1020))) {
2061 * Only do this test if we are not explicitly
2062 * changing the size of a file.
2065 size = sbuf.st_size;
2068 /* Try and set the times, size and mode of this file -
2069 if they are different from the current values
2071 if (sbuf.st_mtime != tvs.modtime || sbuf.st_atime != tvs.actime) {
2074 * This was a setfileinfo on an open file.
2075 * NT does this a lot. It's actually pointless
2076 * setting the time here, as it will be overwritten
2077 * on the next write, so we save the request
2078 * away and will set it on file code. JRA.
2081 if (tvs.modtime != (time_t)0 && tvs.modtime != (time_t)-1) {
2082 DEBUG(10,("call_trans2setfilepathinfo: setting pending modtime to %s\n",
2083 ctime(&tvs.modtime) ));
2084 fsp->pending_modtime = tvs.modtime;
2089 DEBUG(10,("call_trans2setfilepathinfo: setting utimes to modified values.\n"));
2091 if(file_utime(conn, fname, &tvs)!=0)
2092 return(UNIXERROR(ERRDOS,ERRnoaccess));
2096 /* check the mode isn't different, before changing it */
2097 if ((mode != 0) && (mode != dos_mode(conn, fname, &sbuf))) {
2099 DEBUG(10,("call_trans2setfilepathinfo: file %s : setting dos mode %x\n",
2102 if(file_chmod(conn, fname, mode, NULL)) {
2103 DEBUG(2,("chmod of %s failed (%s)\n", fname, strerror(errno)));
2104 return(UNIXERROR(ERRDOS,ERRnoaccess));
2108 if(size != sbuf.st_size) {
2110 DEBUG(10,("call_trans2setfilepathinfo: file %s : setting new size to %.0f\n",
2111 fname, (double)size ));
2114 files_struct *new_fsp = NULL;
2115 int access_mode = 0;
2118 if(global_oplock_break) {
2119 /* Queue this file modify as we are the process of an oplock break. */
2121 DEBUG(2,("call_trans2setfilepathinfo: queueing message due to being "));
2122 DEBUGADD(2,( "in oplock break state.\n"));
2124 push_oplock_pending_smb_message(inbuf, length);
2128 new_fsp = open_file_shared(conn, fname, &sbuf,
2129 SET_OPEN_MODE(DOS_OPEN_RDWR),
2130 (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN),
2131 0, 0, &access_mode, &action);
2133 if (new_fsp == NULL)
2134 return(UNIXERROR(ERRDOS,ERRbadpath));
2135 vfs_set_filelen(new_fsp, size);
2136 close_file(new_fsp,True);
2138 vfs_set_filelen(fsp, size);
2144 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
2149 /****************************************************************************
2150 reply to a TRANS2_MKDIR (make directory with extended attributes).
2151 ****************************************************************************/
2152 static int call_trans2mkdir(connection_struct *conn,
2153 char *inbuf, char *outbuf, int length, int bufsize,
2154 char **pparams, char **ppdata)
2156 char *params = *pparams;
2159 SMB_STRUCT_STAT sbuf;
2160 BOOL bad_path = False;
2162 if (!CAN_WRITE(conn))
2163 return(ERROR(ERRSRV,ERRaccess));
2165 srvstr_pull(inbuf, directory, ¶ms[4], sizeof(directory), -1, STR_TERMINATE);
2167 DEBUG(3,("call_trans2mkdir : name = %s\n", directory));
2169 unix_convert(directory,conn,0,&bad_path,&sbuf);
2170 if (check_name(directory,conn))
2171 ret = vfs_mkdir(conn,directory,unix_mode(conn,aDIR,directory));
2175 DEBUG(5,("call_trans2mkdir error (%s)\n", strerror(errno)));
2176 if((errno == ENOENT) && bad_path)
2178 unix_ERR_class = ERRDOS;
2179 unix_ERR_code = ERRbadpath;
2181 return(UNIXERROR(ERRDOS,ERRnoaccess));
2184 /* Realloc the parameter and data sizes */
2185 params = Realloc(*pparams,2);
2186 if(params == NULL) {
2187 return(ERROR(ERRDOS,ERRnomem));
2193 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
2198 /****************************************************************************
2199 reply to a TRANS2_FINDNOTIFYFIRST (start monitoring a directory for changes)
2200 We don't actually do this - we just send a null response.
2201 ****************************************************************************/
2202 static int call_trans2findnotifyfirst(connection_struct *conn,
2203 char *inbuf, char *outbuf,
2204 int length, int bufsize,
2205 char **pparams, char **ppdata)
2207 static uint16 fnf_handle = 257;
2208 char *params = *pparams;
2209 uint16 info_level = SVAL(params,4);
2211 DEBUG(3,("call_trans2findnotifyfirst - info_level %d\n", info_level));
2219 return(ERROR(ERRDOS,ERRunknownlevel));
2222 /* Realloc the parameter and data sizes */
2223 params = Realloc(*pparams,6);
2224 if(params == NULL) {
2225 return(ERROR(ERRDOS,ERRnomem));
2229 SSVAL(params,0,fnf_handle);
2230 SSVAL(params,2,0); /* No changes */
2231 SSVAL(params,4,0); /* No EA errors */
2238 send_trans2_replies(outbuf, bufsize, params, 6, *ppdata, 0);
2243 /****************************************************************************
2244 reply to a TRANS2_FINDNOTIFYNEXT (continue monitoring a directory for
2245 changes). Currently this does nothing.
2246 ****************************************************************************/
2247 static int call_trans2findnotifynext(connection_struct *conn,
2248 char *inbuf, char *outbuf,
2249 int length, int bufsize,
2250 char **pparams, char **ppdata)
2252 char *params = *pparams;
2254 DEBUG(3,("call_trans2findnotifynext\n"));
2256 /* Realloc the parameter and data sizes */
2257 params = Realloc(*pparams,4);
2258 if(params == NULL) {
2259 return(ERROR(ERRDOS,ERRnomem));
2263 SSVAL(params,0,0); /* No changes */
2264 SSVAL(params,2,0); /* No EA errors */
2266 send_trans2_replies(outbuf, bufsize, params, 4, *ppdata, 0);
2271 /****************************************************************************
2272 reply to a TRANS2_GET_DFS_REFERRAL - Shirish Kalele <kalele@veritas.com>
2273 ****************************************************************************/
2274 static int call_trans2getdfsreferral(connection_struct *conn, char* inbuf,
2275 char* outbuf, int length, int bufsize,
2276 char** pparams, char** ppdata)
2278 char *params = *pparams;
2281 int max_referral_level = SVAL(params,0);
2284 DEBUG(10,("call_trans2getdfsreferral\n"));
2286 if(!lp_host_msdfs())
2287 return(ERROR(ERRDOS,ERRbadfunc));
2289 srvstr_pull(inbuf, pathname, ¶ms[2], sizeof(pathname), -1, STR_TERMINATE);
2291 if((reply_size = setup_dfs_referral(pathname,max_referral_level,ppdata)) < 0)
2292 return(ERROR(ERRDOS,ERRbadfile));
2294 SSVAL(outbuf,smb_flg2,SVAL(outbuf,smb_flg2) | FLAGS2_DFS_PATHNAMES);
2295 send_trans2_replies(outbuf,bufsize,0,0,*ppdata,reply_size);
2300 #define LMCAT_SPL 0x53
2301 #define LMFUNC_GETJOBID 0x60
2303 /****************************************************************************
2304 reply to a TRANS2_IOCTL - used for OS/2 printing.
2305 ****************************************************************************/
2307 static int call_trans2ioctl(connection_struct *conn, char* inbuf,
2308 char* outbuf, int length, int bufsize,
2309 char** pparams, char** ppdata)
2311 char *pdata = *ppdata;
2312 files_struct *fsp = file_fsp(inbuf,smb_vwv15);
2314 if ((SVAL(inbuf,(smb_setup+4)) == LMCAT_SPL) &&
2315 (SVAL(inbuf,(smb_setup+6)) == LMFUNC_GETJOBID)) {
2316 pdata = Realloc(*ppdata, 32);
2318 return(ERROR(ERRDOS,ERRnomem));
2322 /* NOTE - THIS IS ASCII ONLY AT THE MOMENT - NOT SURE IF OS/2
2323 CAN ACCEPT THIS IN UNICODE. JRA. */
2325 SSVAL(pdata,0,fsp->print_jobid); /* Job number */
2326 srvstr_push( outbuf, pdata + 2, global_myname, 15, STR_ASCII|STR_TERMINATE); /* Our NetBIOS name */
2327 srvstr_push( outbuf, pdata+18, lp_servicename(SNUM(conn)), 13, STR_ASCII|STR_TERMINATE); /* Service name */
2328 send_trans2_replies(outbuf,bufsize,*pparams,0,*ppdata,32);
2331 DEBUG(2,("Unknown TRANS2_IOCTL\n"));
2332 return(ERROR(ERRSRV,ERRerror));
2336 /****************************************************************************
2337 reply to a SMBfindclose (stop trans2 directory search)
2338 ****************************************************************************/
2339 int reply_findclose(connection_struct *conn,
2340 char *inbuf,char *outbuf,int length,int bufsize)
2343 int dptr_num=SVALS(inbuf,smb_vwv0);
2344 START_PROFILE(SMBfindclose);
2346 DEBUG(3,("reply_findclose, dptr_num = %d\n", dptr_num));
2348 dptr_close(&dptr_num);
2350 outsize = set_message(outbuf,0,0,True);
2352 DEBUG(3,("SMBfindclose dptr_num = %d\n", dptr_num));
2354 END_PROFILE(SMBfindclose);
2358 /****************************************************************************
2359 reply to a SMBfindnclose (stop FINDNOTIFYFIRST directory search)
2360 ****************************************************************************/
2361 int reply_findnclose(connection_struct *conn,
2362 char *inbuf,char *outbuf,int length,int bufsize)
2366 START_PROFILE(SMBfindnclose);
2368 dptr_num = SVAL(inbuf,smb_vwv0);
2370 DEBUG(3,("reply_findnclose, dptr_num = %d\n", dptr_num));
2372 /* We never give out valid handles for a
2373 findnotifyfirst - so any dptr_num is ok here.
2376 outsize = set_message(outbuf,0,0,True);
2378 DEBUG(3,("SMB_findnclose dptr_num = %d\n", dptr_num));
2380 END_PROFILE(SMBfindnclose);
2385 /****************************************************************************
2386 reply to a SMBtranss2 - just ignore it!
2387 ****************************************************************************/
2388 int reply_transs2(connection_struct *conn,
2389 char *inbuf,char *outbuf,int length,int bufsize)
2391 START_PROFILE(SMBtranss2);
2392 DEBUG(4,("Ignoring transs2 of length %d\n",length));
2393 END_PROFILE(SMBtranss2);
2397 /****************************************************************************
2398 reply to a SMBtrans2
2399 ****************************************************************************/
2400 int reply_trans2(connection_struct *conn,
2401 char *inbuf,char *outbuf,int length,int bufsize)
2404 unsigned int total_params = SVAL(inbuf, smb_tpscnt);
2405 unsigned int total_data =SVAL(inbuf, smb_tdscnt);
2407 unsigned int max_param_reply = SVAL(inbuf, smb_mprcnt);
2408 unsigned int max_data_reply = SVAL(inbuf, smb_mdrcnt);
2409 unsigned int max_setup_fields = SVAL(inbuf, smb_msrcnt);
2410 BOOL close_tid = BITSETW(inbuf+smb_flags,0);
2411 BOOL no_final_response = BITSETW(inbuf+smb_flags,1);
2412 int32 timeout = IVALS(inbuf,smb_timeout);
2414 unsigned int suwcnt = SVAL(inbuf, smb_suwcnt);
2415 unsigned int tran_call = SVAL(inbuf, smb_setup0);
2416 char *params = NULL, *data = NULL;
2417 int num_params, num_params_sofar, num_data, num_data_sofar;
2418 START_PROFILE(SMBtrans2);
2420 if(global_oplock_break && (tran_call == TRANSACT2_OPEN)) {
2421 /* Queue this open message as we are the process of an
2424 DEBUG(2,("reply_trans2: queueing message trans2open due to being "));
2425 DEBUGADD(2,( "in oplock break state.\n"));
2427 push_oplock_pending_smb_message(inbuf, length);
2428 END_PROFILE(SMBtrans2);
2432 if (IS_IPC(conn) && (tran_call != TRANSACT2_OPEN)
2433 && (tran_call != TRANSACT2_GET_DFS_REFERRAL)) {
2434 END_PROFILE(SMBtrans2);
2435 return(ERROR(ERRSRV,ERRaccess));
2438 outsize = set_message(outbuf,0,0,True);
2440 /* All trans2 messages we handle have smb_sucnt == 1 - ensure this
2441 is so as a sanity check */
2444 * Need to have rc=0 for ioctl to get job id for OS/2.
2445 * Network printing will fail if function is not successful.
2446 * Similar function in reply.c will be used if protocol
2447 * is LANMAN1.0 instead of LM1.2X002.
2448 * Until DosPrintSetJobInfo with PRJINFO3 is supported,
2449 * outbuf doesn't have to be set(only job id is used).
2451 if ( (suwcnt == 4) && (tran_call == TRANSACT2_IOCTL) &&
2452 (SVAL(inbuf,(smb_setup+4)) == LMCAT_SPL) &&
2453 (SVAL(inbuf,(smb_setup+6)) == LMFUNC_GETJOBID)) {
2454 DEBUG(2,("Got Trans2 DevIOctl jobid\n"));
2456 DEBUG(2,("Invalid smb_sucnt in trans2 call(%d)\n",suwcnt));
2457 DEBUG(2,("Transaction is %d\n",tran_call));
2458 END_PROFILE(SMBtrans2);
2459 return(ERROR(ERRSRV,ERRerror));
2463 /* Allocate the space for the maximum needed parameters and data */
2464 if (total_params > 0)
2465 params = (char *)malloc(total_params);
2467 data = (char *)malloc(total_data);
2469 if ((total_params && !params) || (total_data && !data)) {
2470 DEBUG(2,("Out of memory in reply_trans2\n"));
2475 END_PROFILE(SMBtrans2);
2476 return(ERROR(ERRDOS,ERRnomem));
2479 /* Copy the param and data bytes sent with this request into
2480 the params buffer */
2481 num_params = num_params_sofar = SVAL(inbuf,smb_pscnt);
2482 num_data = num_data_sofar = SVAL(inbuf, smb_dscnt);
2484 if (num_params > total_params || num_data > total_data)
2485 exit_server("invalid params in reply_trans2");
2488 memcpy( params, smb_base(inbuf) + SVAL(inbuf, smb_psoff), num_params);
2490 memcpy( data, smb_base(inbuf) + SVAL(inbuf, smb_dsoff), num_data);
2492 if(num_data_sofar < total_data || num_params_sofar < total_params) {
2493 /* We need to send an interim response then receive the rest
2494 of the parameter/data bytes */
2495 outsize = set_message(outbuf,0,0,True);
2496 if (!send_smb(smbd_server_fd(),outbuf))
2497 exit_server("reply_trans2: send_smb failed.\n");
2499 while (num_data_sofar < total_data ||
2500 num_params_sofar < total_params) {
2503 ret = receive_next_smb(inbuf,bufsize,SMB_SECONDARY_WAIT);
2506 (CVAL(inbuf, smb_com) != SMBtranss2)) || !ret) {
2507 outsize = set_message(outbuf,0,0,True);
2509 DEBUG(0,("reply_trans2: Invalid secondary trans2 packet\n"));
2511 DEBUG(0,("reply_trans2: %s in getting secondary trans2 response.\n",
2512 (smb_read_error == READ_ERROR) ? "error" : "timeout" ));
2517 END_PROFILE(SMBtrans2);
2518 return(ERROR(ERRSRV,ERRerror));
2521 /* Revise total_params and total_data in case
2522 they have changed downwards */
2523 total_params = SVAL(inbuf, smb_tpscnt);
2524 total_data = SVAL(inbuf, smb_tdscnt);
2525 num_params_sofar += (num_params = SVAL(inbuf,smb_spscnt));
2526 num_data_sofar += ( num_data = SVAL(inbuf, smb_sdscnt));
2527 if (num_params_sofar > total_params || num_data_sofar > total_data)
2528 exit_server("data overflow in trans2");
2530 memcpy( ¶ms[ SVAL(inbuf, smb_spsdisp)],
2531 smb_base(inbuf) + SVAL(inbuf, smb_spsoff), num_params);
2532 memcpy( &data[SVAL(inbuf, smb_sdsdisp)],
2533 smb_base(inbuf)+ SVAL(inbuf, smb_sdsoff), num_data);
2537 if (Protocol >= PROTOCOL_NT1) {
2538 SSVAL(outbuf,smb_flg2,SVAL(outbuf,smb_flg2) | 0x40); /* IS_LONG_NAME */
2541 /* Now we must call the relevant TRANS2 function */
2543 case TRANSACT2_OPEN:
2544 START_PROFILE_NESTED(Trans2_open);
2545 outsize = call_trans2open(conn,
2546 inbuf, outbuf, bufsize,
2548 END_PROFILE_NESTED(Trans2_open);
2551 case TRANSACT2_FINDFIRST:
2552 START_PROFILE_NESTED(Trans2_findfirst);
2553 outsize = call_trans2findfirst(conn, inbuf, outbuf,
2554 bufsize, ¶ms, &data);
2555 END_PROFILE_NESTED(Trans2_findfirst);
2558 case TRANSACT2_FINDNEXT:
2559 START_PROFILE_NESTED(Trans2_findnext);
2560 outsize = call_trans2findnext(conn, inbuf, outbuf,
2563 END_PROFILE_NESTED(Trans2_findnext);
2566 case TRANSACT2_QFSINFO:
2567 START_PROFILE_NESTED(Trans2_qfsinfo);
2568 outsize = call_trans2qfsinfo(conn, inbuf, outbuf,
2569 length, bufsize, ¶ms,
2571 END_PROFILE_NESTED(Trans2_qfsinfo);
2574 case TRANSACT2_SETFSINFO:
2575 START_PROFILE_NESTED(Trans2_setfsinfo);
2576 outsize = call_trans2setfsinfo(conn, inbuf, outbuf,
2579 END_PROFILE_NESTED(Trans2_setfsinfo);
2582 case TRANSACT2_QPATHINFO:
2583 case TRANSACT2_QFILEINFO:
2584 START_PROFILE_NESTED(Trans2_qpathinfo);
2585 outsize = call_trans2qfilepathinfo(conn, inbuf, outbuf,
2587 ¶ms, &data, total_data);
2588 END_PROFILE_NESTED(Trans2_qpathinfo);
2590 case TRANSACT2_SETPATHINFO:
2591 case TRANSACT2_SETFILEINFO:
2592 START_PROFILE_NESTED(Trans2_setpathinfo);
2593 outsize = call_trans2setfilepathinfo(conn, inbuf, outbuf,
2597 END_PROFILE_NESTED(Trans2_setpathinfo);
2600 case TRANSACT2_FINDNOTIFYFIRST:
2601 START_PROFILE_NESTED(Trans2_findnotifyfirst);
2602 outsize = call_trans2findnotifyfirst(conn, inbuf, outbuf,
2605 END_PROFILE_NESTED(Trans2_findnotifyfirst);
2608 case TRANSACT2_FINDNOTIFYNEXT:
2609 START_PROFILE_NESTED(Trans2_findnotifynext);
2610 outsize = call_trans2findnotifynext(conn, inbuf, outbuf,
2613 END_PROFILE_NESTED(Trans2_findnotifynext);
2615 case TRANSACT2_MKDIR:
2616 START_PROFILE_NESTED(Trans2_mkdir);
2617 outsize = call_trans2mkdir(conn, inbuf, outbuf, length,
2618 bufsize, ¶ms, &data);
2619 END_PROFILE_NESTED(Trans2_mkdir);
2622 case TRANSACT2_GET_DFS_REFERRAL:
2623 START_PROFILE_NESTED(Trans2_get_dfs_referral);
2624 outsize = call_trans2getdfsreferral(conn,inbuf,outbuf,length,
2625 bufsize, ¶ms, &data);
2626 END_PROFILE_NESTED(Trans2_get_dfs_referral);
2628 case TRANSACT2_IOCTL:
2629 START_PROFILE_NESTED(Trans2_ioctl);
2630 outsize = call_trans2ioctl(conn,inbuf,outbuf,length,
2631 bufsize,¶ms,&data);
2632 END_PROFILE_NESTED(Trans2_ioctl);
2635 /* Error in request */
2636 DEBUG(2,("Unknown request %d in trans2 call\n", tran_call));
2641 END_PROFILE(SMBtrans2);
2642 return (ERROR(ERRSRV,ERRerror));
2645 /* As we do not know how many data packets will need to be
2646 returned here the various call_trans2xxxx calls
2647 must send their own. Thus a call_trans2xxx routine only
2648 returns a value other than -1 when it wants to send
2656 END_PROFILE(SMBtrans2);
2657 return outsize; /* If a correct response was needed the
2658 call_trans2xxx calls have already sent
2659 it. If outsize != -1 then it is returning */