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 p += align_string(outbuf, p, 0);
475 len = srvstr_push(outbuf, p, fname, -1, STR_TERMINATE);
476 SCVAL(nameptr, -1, len);
482 if(requires_resume_key) {
486 put_dos_date2(p,l2_fdateCreation,cdate);
487 put_dos_date2(p,l2_fdateLastAccess,adate);
488 put_dos_date2(p,l2_fdateLastWrite,mdate);
489 SIVAL(p,l2_cbFile,(uint32)size);
490 SIVAL(p,l2_cbFileAlloc,SMB_ROUNDUP(size,1024));
491 SSVAL(p,l2_attrFile,mode);
492 SIVAL(p,l2_cbList,0); /* No extended attributes */
495 len = srvstr_push(outbuf, p, fname, -1,
501 case SMB_FIND_FILE_BOTH_DIRECTORY_INFO:
502 was_8_3 = is_8_3(fname, True);
504 SIVAL(p,0,reskey); p += 4;
505 put_long_date(p,cdate); p += 8;
506 put_long_date(p,adate); p += 8;
507 put_long_date(p,mdate); p += 8;
508 put_long_date(p,mdate); p += 8;
512 SIVAL(p,0,nt_extmode); p += 4;
514 SIVAL(p,0,0); p += 4;
516 pstring mangled_name;
517 pstrcpy(mangled_name, fname);
518 name_map_mangle(mangled_name,True,True,SNUM(conn));
519 mangled_name[12] = 0;
520 len = srvstr_push(outbuf, p+2, mangled_name, 24, STR_UPPER);
527 len = srvstr_push(outbuf, p, fname, -1, STR_TERMINATE);
530 len = PTR_DIFF(p, pdata);
531 len = (len + 3) & ~3;
536 case SMB_FIND_FILE_DIRECTORY_INFO:
538 SIVAL(p,0,reskey); p += 4;
539 put_long_date(p,cdate); p += 8;
540 put_long_date(p,adate); p += 8;
541 put_long_date(p,mdate); p += 8;
542 put_long_date(p,mdate); p += 8;
546 SIVAL(p,0,nt_extmode); p += 4;
548 len = srvstr_push(outbuf, p, fname, -1, STR_TERMINATE);
551 len = PTR_DIFF(p, pdata);
552 len = (len + 3) & ~3;
558 case SMB_FIND_FILE_FULL_DIRECTORY_INFO:
560 SIVAL(p,0,reskey); p += 4;
561 put_long_date(p,cdate); p += 8;
562 put_long_date(p,adate); p += 8;
563 put_long_date(p,mdate); p += 8;
564 put_long_date(p,mdate); p += 8;
568 SIVAL(p,0,nt_extmode); p += 4;
570 SIVAL(p,0,0); p += 4;
572 len = srvstr_push(outbuf, p, fname, -1, STR_TERMINATE);
576 len = PTR_DIFF(p, pdata);
577 len = (len + 3) & ~3;
582 case SMB_FIND_FILE_NAMES_INFO:
584 SIVAL(p,0,reskey); p += 4;
586 len = srvstr_push(outbuf, p, fname, -1, STR_TERMINATE);
589 len = PTR_DIFF(p, pdata);
590 len = (len + 3) & ~3;
600 if (PTR_DIFF(p,pdata) > space_remaining) {
601 /* Move the dirptr back to prev_dirpos */
602 SeekDir(conn->dirptr, prev_dirpos);
603 *out_of_space = True;
604 DEBUG(9,("get_lanman2_dir_entry: out of space\n"));
605 return False; /* Not finished - just out of space */
608 /* Setup the last_filename pointer, as an offset from base_data */
609 *last_name_off = PTR_DIFF(nameptr,base_data);
610 /* Advance the data pointer to the next slot */
617 /****************************************************************************
618 Reply to a TRANS2_FINDFIRST.
619 ****************************************************************************/
621 static int call_trans2findfirst(connection_struct *conn,
622 char *inbuf, char *outbuf, int bufsize,
623 char **pparams, char **ppdata)
625 /* We must be careful here that we don't return more than the
626 allowed number of data bytes. If this means returning fewer than
627 maxentries then so be it. We assume that the redirector has
628 enough room for the fixed number of parameter bytes it has
630 uint32 max_data_bytes = SVAL(inbuf, smb_mdrcnt);
631 char *params = *pparams;
632 char *pdata = *ppdata;
633 int dirtype = SVAL(params,0);
634 int maxentries = SVAL(params,2);
635 BOOL close_after_first = BITSETW(params+4,0);
636 BOOL close_if_end = BITSETW(params+4,1);
637 BOOL requires_resume_key = BITSETW(params+4,2);
638 int info_level = SVAL(params,6);
646 BOOL finished = False;
647 BOOL dont_descend = False;
648 BOOL out_of_space = False;
650 BOOL bad_path = False;
651 SMB_STRUCT_STAT sbuf;
653 *directory = *mask = 0;
655 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",
656 dirtype, maxentries, close_after_first, close_if_end, requires_resume_key,
657 info_level, max_data_bytes));
665 case SMB_FIND_FILE_DIRECTORY_INFO:
666 case SMB_FIND_FILE_FULL_DIRECTORY_INFO:
667 case SMB_FIND_FILE_NAMES_INFO:
668 case SMB_FIND_FILE_BOTH_DIRECTORY_INFO:
671 return(ERROR(ERRDOS,ERRunknownlevel));
674 srvstr_pull(inbuf, directory, params+12, sizeof(directory), -1, STR_TERMINATE);
676 RESOLVE_FINDFIRST_DFSPATH(directory, conn, inbuf, outbuf);
678 unix_convert(directory,conn,0,&bad_path,&sbuf);
679 if(!check_name(directory,conn)) {
680 if((errno == ENOENT) && bad_path)
682 unix_ERR_class = ERRDOS;
683 unix_ERR_code = ERRbadpath;
687 /* Ugly - NT specific hack - maybe not needed ? (JRA) */
688 if((errno == ENOTDIR) && (Protocol >= PROTOCOL_NT1) &&
689 (get_remote_arch() == RA_WINNT))
691 unix_ERR_class = ERRDOS;
692 unix_ERR_code = ERRbaddirectory;
696 return(UNIXERROR(ERRDOS,ERRbadpath));
699 p = strrchr_m(directory,'/');
701 pstrcpy(mask,directory);
702 pstrcpy(directory,"./");
708 DEBUG(5,("dir=%s, mask = %s\n",directory, mask));
710 pdata = Realloc(*ppdata, max_data_bytes + 1024);
711 if( pdata == NULL ) {
712 return(ERROR(ERRDOS,ERRnomem));
715 memset((char *)pdata,'\0',max_data_bytes + 1024);
717 /* Realloc the params space */
718 params = Realloc(*pparams, 10);
719 if( params == NULL ) {
720 return(ERROR(ERRDOS,ERRnomem));
724 dptr_num = dptr_create(conn,directory, False, True ,SVAL(inbuf,smb_pid));
726 return(UNIXERROR(ERRDOS,ERRbadfile));
728 /* Save the wildcard match and attribs we are using on this directory -
729 needed as lanman2 assumes these are being saved between calls */
731 if(!(wcard = strdup(mask))) {
732 dptr_close(&dptr_num);
733 return(ERROR(ERRDOS,ERRnomem));
736 dptr_set_wcard(dptr_num, wcard);
737 dptr_set_attr(dptr_num, dirtype);
739 DEBUG(4,("dptr_num is %d, wcard = %s, attr = %d\n",dptr_num, wcard, dirtype));
741 /* We don't need to check for VOL here as this is returned by
742 a different TRANS2 call. */
744 DEBUG(8,("dirpath=<%s> dontdescend=<%s>\n",
745 conn->dirpath,lp_dontdescend(SNUM(conn))));
746 if (in_list(conn->dirpath,lp_dontdescend(SNUM(conn)),case_sensitive))
750 space_remaining = max_data_bytes;
751 out_of_space = False;
753 for (i=0;(i<maxentries) && !finished && !out_of_space;i++)
755 BOOL got_exact_match = False;
757 /* this is a heuristic to avoid seeking the dirptr except when
758 absolutely necessary. It allows for a filename of about 40 chars */
759 if (space_remaining < DIRLEN_GUESS && numentries > 0)
766 finished = !get_lanman2_dir_entry(conn,
768 mask,dirtype,info_level,
769 requires_resume_key,dont_descend,
770 &p,pdata,space_remaining, &out_of_space, &got_exact_match,
774 if (finished && out_of_space)
777 if (!finished && !out_of_space)
781 * As an optimisation if we know we aren't looking
782 * for a wildcard name (ie. the name matches the wildcard exactly)
783 * then we can finish on any (first) match.
784 * This speeds up large directory searches. JRA.
790 space_remaining = max_data_bytes - PTR_DIFF(p,pdata);
793 /* Check if we can close the dirptr */
794 if(close_after_first || (finished && close_if_end))
796 DEBUG(5,("call_trans2findfirst - (2) closing dptr_num %d\n", dptr_num));
797 dptr_close(&dptr_num);
801 * If there are no matching entries we must return ERRDOS/ERRbadfile -
802 * from observation of NT.
807 dptr_close(&dptr_num);
808 return(ERROR(ERRDOS,ERRbadfile));
811 /* At this point pdata points to numentries directory entries. */
813 /* Set up the return parameter block */
814 SSVAL(params,0,dptr_num);
815 SSVAL(params,2,numentries);
816 SSVAL(params,4,finished);
817 SSVAL(params,6,0); /* Never an EA error */
818 SSVAL(params,8,last_name_off);
820 send_trans2_replies( outbuf, bufsize, params, 10, pdata, PTR_DIFF(p,pdata));
822 if ((! *directory) && dptr_path(dptr_num))
823 slprintf(directory,sizeof(directory)-1, "(%s)",dptr_path(dptr_num));
825 DEBUG( 4, ( "%s mask=%s directory=%s dirtype=%d numentries=%d\n",
826 smb_fn_name(CVAL(inbuf,smb_com)),
827 mask, directory, dirtype, numentries ) );
830 * Force a name mangle here to ensure that the
831 * mask as an 8.3 name is top of the mangled cache.
832 * The reasons for this are subtle. Don't remove
833 * this code unless you know what you are doing
834 * (see PR#13758). JRA.
837 if(!is_8_3( mask, False))
838 name_map_mangle(mask, True, True, SNUM(conn));
844 /****************************************************************************
845 reply to a TRANS2_FINDNEXT
846 ****************************************************************************/
847 static int call_trans2findnext(connection_struct *conn,
848 char *inbuf, char *outbuf,
849 int length, int bufsize,
850 char **pparams, char **ppdata)
852 /* We must be careful here that we don't return more than the
853 allowed number of data bytes. If this means returning fewer than
854 maxentries then so be it. We assume that the redirector has
855 enough room for the fixed number of parameter bytes it has
857 int max_data_bytes = SVAL(inbuf, smb_mdrcnt);
858 char *params = *pparams;
859 char *pdata = *ppdata;
860 int dptr_num = SVAL(params,0);
861 int maxentries = SVAL(params,2);
862 uint16 info_level = SVAL(params,4);
863 uint32 resume_key = IVAL(params,6);
864 BOOL close_after_request = BITSETW(params+10,0);
865 BOOL close_if_end = BITSETW(params+10,1);
866 BOOL requires_resume_key = BITSETW(params+10,2);
867 BOOL continue_bit = BITSETW(params+10,3);
874 int i, last_name_off=0;
875 BOOL finished = False;
876 BOOL dont_descend = False;
877 BOOL out_of_space = False;
880 *mask = *directory = *resume_name = 0;
882 srvstr_pull(inbuf, resume_name, params+12, sizeof(resume_name), -1, STR_TERMINATE);
884 DEBUG(3,("call_trans2findnext: dirhandle = %d, max_data_bytes = %d, maxentries = %d, \
885 close_after_request=%d, close_if_end = %d requires_resume_key = %d \
886 resume_key = %d resume name = %s continue=%d level = %d\n",
887 dptr_num, max_data_bytes, maxentries, close_after_request, close_if_end,
888 requires_resume_key, resume_key, resume_name, continue_bit, info_level));
896 case SMB_FIND_FILE_DIRECTORY_INFO:
897 case SMB_FIND_FILE_FULL_DIRECTORY_INFO:
898 case SMB_FIND_FILE_NAMES_INFO:
899 case SMB_FIND_FILE_BOTH_DIRECTORY_INFO:
902 return(ERROR(ERRDOS,ERRunknownlevel));
905 pdata = Realloc( *ppdata, max_data_bytes + 1024);
907 return(ERROR(ERRDOS,ERRnomem));
910 memset((char *)pdata,'\0',max_data_bytes + 1024);
912 /* Realloc the params space */
913 params = Realloc(*pparams, 6*SIZEOFWORD);
914 if( params == NULL ) {
915 return(ERROR(ERRDOS,ERRnomem));
919 /* Check that the dptr is valid */
920 if(!(conn->dirptr = dptr_fetch_lanman2(dptr_num)))
921 return(ERROR(ERRDOS,ERRnofiles));
923 string_set(&conn->dirpath,dptr_path(dptr_num));
925 /* Get the wildcard mask from the dptr */
926 if((p = dptr_wcard(dptr_num))== NULL) {
927 DEBUG(2,("dptr_num %d has no wildcard\n", dptr_num));
928 return (ERROR(ERRDOS,ERRnofiles));
931 pstrcpy(directory,conn->dirpath);
933 /* Get the attr mask from the dptr */
934 dirtype = dptr_attr(dptr_num);
936 DEBUG(3,("dptr_num is %d, mask = %s, attr = %x, dirptr=(0x%lX,%d)\n",
937 dptr_num, mask, dirtype,
939 TellDir(conn->dirptr)));
941 /* We don't need to check for VOL here as this is returned by
942 a different TRANS2 call. */
944 DEBUG(8,("dirpath=<%s> dontdescend=<%s>\n",conn->dirpath,lp_dontdescend(SNUM(conn))));
945 if (in_list(conn->dirpath,lp_dontdescend(SNUM(conn)),case_sensitive))
949 space_remaining = max_data_bytes;
950 out_of_space = False;
953 * Seek to the correct position. We no longer use the resume key but
954 * depend on the last file name instead.
956 if(requires_resume_key && *resume_name && !continue_bit)
959 * Fix for NT redirector problem triggered by resume key indexes
960 * changing between directory scans. We now return a resume key of 0
961 * and instead look for the filename to continue from (also given
962 * to us by NT/95/smbfs/smbclient). If no other scans have been done between the
963 * findfirst/findnext (as is usual) then the directory pointer
964 * should already be at the correct place. Check this by scanning
965 * backwards looking for an exact (ie. case sensitive) filename match.
966 * If we get to the beginning of the directory and haven't found it then scan
967 * forwards again looking for a match. JRA.
970 int current_pos, start_pos;
972 void *dirptr = conn->dirptr;
973 start_pos = TellDir(dirptr);
974 for(current_pos = start_pos; current_pos >= 0; current_pos--)
976 DEBUG(7,("call_trans2findnext: seeking to pos %d\n", current_pos));
978 SeekDir(dirptr, current_pos);
979 dname = ReadDirName(dirptr);
982 * Remember, name_map_mangle is called by
983 * get_lanman2_dir_entry(), so the resume name
984 * could be mangled. Ensure we do the same
989 name_map_mangle( dname, False, True, SNUM(conn));
991 if(dname && strcsequal( resume_name, dname))
993 SeekDir(dirptr, current_pos+1);
994 DEBUG(7,("call_trans2findnext: got match at pos %d\n", current_pos+1 ));
1000 * Scan forward from start if not found going backwards.
1005 DEBUG(7,("call_trans2findnext: notfound: seeking to pos %d\n", start_pos));
1006 SeekDir(dirptr, start_pos);
1007 for(current_pos = start_pos; (dname = ReadDirName(dirptr)) != NULL; SeekDir(dirptr,++current_pos))
1010 * Remember, name_map_mangle is called by
1011 * get_lanman2_dir_entry(), so the resume name
1012 * could be mangled. Ensure we do the same
1017 name_map_mangle( dname, False, True, SNUM(conn));
1019 if(dname && strcsequal( resume_name, dname))
1021 SeekDir(dirptr, current_pos+1);
1022 DEBUG(7,("call_trans2findnext: got match at pos %d\n", current_pos+1 ));
1026 } /* end if current_pos */
1027 } /* end if requires_resume_key && !continue_bit */
1029 for (i=0;(i<(int)maxentries) && !finished && !out_of_space ;i++)
1031 BOOL got_exact_match = False;
1033 /* this is a heuristic to avoid seeking the dirptr except when
1034 absolutely necessary. It allows for a filename of about 40 chars */
1035 if (space_remaining < DIRLEN_GUESS && numentries > 0)
1037 out_of_space = True;
1042 finished = !get_lanman2_dir_entry(conn,
1044 mask,dirtype,info_level,
1045 requires_resume_key,dont_descend,
1046 &p,pdata,space_remaining, &out_of_space, &got_exact_match,
1050 if (finished && out_of_space)
1053 if (!finished && !out_of_space)
1057 * As an optimisation if we know we aren't looking
1058 * for a wildcard name (ie. the name matches the wildcard exactly)
1059 * then we can finish on any (first) match.
1060 * This speeds up large directory searches. JRA.
1066 space_remaining = max_data_bytes - PTR_DIFF(p,pdata);
1069 /* Check if we can close the dirptr */
1070 if(close_after_request || (finished && close_if_end))
1072 DEBUG(5,("call_trans2findnext: closing dptr_num = %d\n", dptr_num));
1073 dptr_close(&dptr_num); /* This frees up the saved mask */
1077 /* Set up the return parameter block */
1078 SSVAL(params,0,numentries);
1079 SSVAL(params,2,finished);
1080 SSVAL(params,4,0); /* Never an EA error */
1081 SSVAL(params,6,last_name_off);
1083 send_trans2_replies( outbuf, bufsize, params, 8, pdata, PTR_DIFF(p,pdata));
1085 if ((! *directory) && dptr_path(dptr_num))
1086 slprintf(directory,sizeof(directory)-1, "(%s)",dptr_path(dptr_num));
1088 DEBUG( 3, ( "%s mask=%s directory=%s dirtype=%d numentries=%d\n",
1089 smb_fn_name(CVAL(inbuf,smb_com)),
1090 mask, directory, dirtype, numentries ) );
1095 /****************************************************************************
1096 reply to a TRANS2_QFSINFO (query filesystem info)
1097 ****************************************************************************/
1099 static int call_trans2qfsinfo(connection_struct *conn,
1100 char *inbuf, char *outbuf,
1101 int length, int bufsize,
1102 char **pparams, char **ppdata)
1104 int max_data_bytes = SVAL(inbuf, smb_mdrcnt);
1105 char *pdata = *ppdata;
1106 char *params = *pparams;
1107 uint16 info_level = SVAL(params,0);
1110 char *vname = volume_label(SNUM(conn));
1111 int snum = SNUM(conn);
1112 char *fstype = lp_fstype(SNUM(conn));
1114 DEBUG(3,("call_trans2qfsinfo: level = %d\n", info_level));
1116 if(vfs_stat(conn,".",&st)!=0) {
1117 DEBUG(2,("call_trans2qfsinfo: stat of . failed (%s)\n", strerror(errno)));
1118 return (ERROR(ERRSRV,ERRinvdevice));
1121 pdata = Realloc(*ppdata, max_data_bytes + 1024);
1122 if ( pdata == NULL ) {
1123 return(ERROR(ERRDOS,ERRnomem));
1126 memset((char *)pdata,'\0',max_data_bytes + 1024);
1132 SMB_BIG_UINT dfree,dsize,bsize;
1134 conn->vfs_ops.disk_free(conn,".",False,&bsize,&dfree,&dsize);
1135 SIVAL(pdata,l1_idFileSystem,st.st_dev);
1136 SIVAL(pdata,l1_cSectorUnit,bsize/512);
1137 SIVAL(pdata,l1_cUnit,dsize);
1138 SIVAL(pdata,l1_cUnitAvail,dfree);
1139 SSVAL(pdata,l1_cbSector,512);
1140 DEBUG(5,("call_trans2qfsinfo : bsize=%u, id=%x, cSectorUnit=%u, cUnit=%u, cUnitAvail=%u, cbSector=%d\n",
1141 (unsigned int)bsize, (unsigned int)st.st_dev, ((unsigned int)bsize)/512, (unsigned int)dsize,
1142 (unsigned int)dfree, 512));
1146 /* Return volume name */
1148 * Add volume serial number - hash of a combination of
1149 * the called hostname and the service name.
1151 SIVAL(pdata,0,str_checksum(lp_servicename(snum)) ^ (str_checksum(local_machine)<<16) );
1152 len = srvstr_push(outbuf, pdata+l2_vol_szVolLabel, vname, -1,
1154 SCVAL(pdata,l2_vol_cch,len);
1155 data_len = l2_vol_szVolLabel + len;
1156 DEBUG(5,("call_trans2qfsinfo : time = %x, namelen = %d, name = %s\n",
1157 (unsigned)st.st_ctime, len, vname));
1160 case SMB_QUERY_FS_ATTRIBUTE_INFO:
1161 SIVAL(pdata,0,FILE_CASE_PRESERVED_NAMES|FILE_CASE_SENSITIVE_SEARCH|
1162 FILE_DEVICE_IS_MOUNTED|
1163 (lp_nt_acl_support() ? FILE_PERSISTENT_ACLS : 0)); /* FS ATTRIBUTES */
1164 SIVAL(pdata,4,255); /* Max filename component length */
1165 len = srvstr_push(outbuf, pdata+12, fstype, -1, STR_TERMINATE);
1167 data_len = 12 + len;
1170 case SMB_QUERY_FS_LABEL_INFO:
1171 len = srvstr_push(outbuf, pdata+4, vname, -1, STR_TERMINATE);
1175 case SMB_QUERY_FS_VOLUME_INFO:
1177 * Add volume serial number - hash of a combination of
1178 * the called hostname and the service name.
1180 SIVAL(pdata,8,str_checksum(lp_servicename(snum)) ^
1181 (str_checksum(local_machine)<<16));
1183 len = srvstr_push(outbuf, pdata+18, vname, -1, STR_TERMINATE);
1184 SIVAL(pdata,12,len);
1186 DEBUG(5,("call_trans2qfsinfo : SMB_QUERY_FS_VOLUME_INFO namelen = %d, vol=%s serv=%s\n",
1187 (int)strlen(vname),vname, lp_servicename(snum)));
1189 case SMB_QUERY_FS_SIZE_INFO:
1191 SMB_BIG_UINT dfree,dsize,bsize;
1193 conn->vfs_ops.disk_free(conn,".",False,&bsize,&dfree,&dsize);
1194 SBIG_UINT(pdata,0,dsize);
1195 SBIG_UINT(pdata,8,dfree);
1196 SIVAL(pdata,16,bsize/512);
1197 SIVAL(pdata,20,512);
1200 case SMB_QUERY_FS_DEVICE_INFO:
1202 SIVAL(pdata,0,0); /* dev type */
1203 SIVAL(pdata,4,0); /* characteristics */
1205 case SMB_MAC_QUERY_FS_INFO:
1207 * Thursby MAC extension... ONLY on NTFS filesystems
1208 * once we do streams then we don't need this
1210 if (strequal(lp_fstype(SNUM(conn)),"NTFS")) {
1212 SIVAL(pdata,84,0x100); /* Don't support mac... */
1217 return(ERROR(ERRDOS,ERRunknownlevel));
1221 send_trans2_replies( outbuf, bufsize, params, 0, pdata, data_len);
1223 DEBUG( 4, ( "%s info_level = %d\n",
1224 smb_fn_name(CVAL(inbuf,smb_com)), info_level) );
1229 /****************************************************************************
1230 reply to a TRANS2_SETFSINFO (set filesystem info)
1231 ****************************************************************************/
1232 static int call_trans2setfsinfo(connection_struct *conn,
1233 char *inbuf, char *outbuf, int length,
1235 char **pparams, char **ppdata)
1237 /* Just say yes we did it - there is nothing that
1238 can be set here so it doesn't matter. */
1240 DEBUG(3,("call_trans2setfsinfo\n"));
1242 if (!CAN_WRITE(conn))
1243 return(ERROR(ERRSRV,ERRaccess));
1245 outsize = set_message(outbuf,10,0,True);
1250 /****************************************************************************
1251 Reply to a TRANS2_QFILEPATHINFO or TRANSACT2_QFILEINFO (query file info by
1252 file name or file id).
1253 ****************************************************************************/
1255 static int call_trans2qfilepathinfo(connection_struct *conn,
1256 char *inbuf, char *outbuf, int length,
1258 char **pparams,char **ppdata,
1261 int max_data_bytes = SVAL(inbuf, smb_mdrcnt);
1262 char *params = *pparams;
1263 char *pdata = *ppdata;
1264 uint16 tran_call = SVAL(inbuf, smb_setup0);
1268 unsigned int data_size;
1269 SMB_STRUCT_STAT sbuf;
1274 BOOL bad_path = False;
1275 BOOL delete_pending = False;
1279 if (tran_call == TRANSACT2_QFILEINFO) {
1280 files_struct *fsp = file_fsp(params,0);
1281 info_level = SVAL(params,2);
1283 DEBUG(3,("call_trans2qfilepathinfo: TRANSACT2_QFILEINFO: level = %d\n",
1286 if(fsp && (fsp->is_directory || fsp->stat_open)) {
1288 * This is actually a QFILEINFO on a directory
1289 * handle (returned from an NT SMB). NT5.0 seems
1290 * to do this call. JRA.
1292 pstrcpy(fname, fsp->fsp_name);
1293 unix_convert(fname,conn,0,&bad_path,&sbuf);
1294 if (!check_name(fname,conn) ||
1295 (!VALID_STAT(sbuf) && vfs_stat(conn,fname,&sbuf))) {
1296 DEBUG(3,("fileinfo of %s failed (%s)\n",fname,strerror(errno)));
1297 if((errno == ENOENT) && bad_path) {
1298 unix_ERR_class = ERRDOS;
1299 unix_ERR_code = ERRbadpath;
1301 return(UNIXERROR(ERRDOS,ERRbadpath));
1304 delete_pending = fsp->directory_delete_on_close;
1307 * Original code - this is an open file.
1309 CHECK_FSP(fsp,conn);
1312 pstrcpy(fname, fsp->fsp_name);
1313 if (vfs_fstat(fsp,fsp->fd,&sbuf) != 0) {
1314 DEBUG(3,("fstat of fnum %d failed (%s)\n",
1315 fsp->fnum, strerror(errno)));
1316 return(UNIXERROR(ERRDOS,ERRbadfid));
1318 if((pos = fsp->conn->vfs_ops.lseek(fsp,fsp->fd,0,SEEK_CUR)) == -1)
1319 return(UNIXERROR(ERRDOS,ERRnoaccess));
1321 delete_pending = fsp->delete_on_close;
1325 info_level = SVAL(params,0);
1327 DEBUG(3,("call_trans2qfilepathinfo: TRANSACT2_QPATHINFO: level = %d\n",
1330 srvstr_pull(inbuf, fname, ¶ms[6], sizeof(fname), -1, STR_TERMINATE);
1332 RESOLVE_DFSPATH(fname, conn, inbuf, outbuf);
1334 unix_convert(fname,conn,0,&bad_path,&sbuf);
1335 if (!check_name(fname,conn) ||
1336 (!VALID_STAT(sbuf) && vfs_stat(conn,fname,&sbuf))) {
1337 DEBUG(3,("fileinfo of %s failed (%s)\n",fname,strerror(errno)));
1338 if((errno == ENOENT) && bad_path) {
1339 unix_ERR_class = ERRDOS;
1340 unix_ERR_code = ERRbadpath;
1342 return(UNIXERROR(ERRDOS,ERRbadpath));
1347 DEBUG(3,("call_trans2qfilepathinfo %s level=%d call=%d total_data=%d\n",
1348 fname,info_level,tran_call,total_data));
1350 p = strrchr_m(fname,'/');
1357 mode = dos_mode(conn,fname,&sbuf);
1358 size = sbuf.st_size;
1359 if (mode & aDIR) size = 0;
1361 params = Realloc(*pparams,2);
1362 if (params == NULL) {
1363 return(ERROR(ERRDOS,ERRnomem));
1366 memset((char *)params,'\0',2);
1367 data_size = max_data_bytes + 1024;
1368 pdata = Realloc(*ppdata, data_size);
1369 if ( pdata == NULL ) {
1370 return(ERROR(ERRDOS,ERRnomem));
1374 if (total_data > 0 && IVAL(pdata,0) == total_data) {
1375 /* uggh, EAs for OS2 */
1376 DEBUG(4,("Rejecting EA request with total_data=%d\n",total_data));
1377 return(ERROR(ERRDOS,ERROR_EAS_NOT_SUPPORTED));
1380 memset((char *)pdata,'\0',data_size);
1382 c_time = get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(conn)));
1384 if (lp_dos_filetime_resolution(SNUM(conn))) {
1386 sbuf.st_atime &= ~1;
1387 sbuf.st_mtime &= ~1;
1388 sbuf.st_mtime &= ~1;
1393 case SMB_INFO_STANDARD:
1394 case SMB_INFO_QUERY_EA_SIZE:
1395 data_size = (info_level==1?22:26);
1396 put_dos_date2(pdata,l1_fdateCreation,c_time);
1397 put_dos_date2(pdata,l1_fdateLastAccess,sbuf.st_atime);
1398 put_dos_date2(pdata,l1_fdateLastWrite,sbuf.st_mtime); /* write time */
1399 SIVAL(pdata,l1_cbFile,(uint32)size);
1400 SIVAL(pdata,l1_cbFileAlloc,SMB_ROUNDUP(size,1024));
1401 SSVAL(pdata,l1_attrFile,mode);
1402 SIVAL(pdata,l1_attrFile+2,4); /* this is what OS2 does */
1405 case SMB_INFO_QUERY_EAS_FROM_LIST:
1407 put_dos_date2(pdata,0,c_time);
1408 put_dos_date2(pdata,4,sbuf.st_atime);
1409 put_dos_date2(pdata,8,sbuf.st_mtime);
1410 SIVAL(pdata,12,(uint32)size);
1411 SIVAL(pdata,16,SMB_ROUNDUP(size,1024));
1412 SIVAL(pdata,20,mode);
1415 case SMB_INFO_QUERY_ALL_EAS:
1417 SIVAL(pdata,0,data_size);
1421 return(ERROR(ERRDOS,ERRbadfunc)); /* os/2 needs this */
1423 case SMB_QUERY_FILE_BASIC_INFO:
1426 if (info_level == SMB_QUERY_FILE_BASIC_INFO)
1427 data_size = 36; /* w95 returns 40 bytes not 36 - why ?. */
1432 put_long_date(pdata,c_time);
1433 put_long_date(pdata+8,sbuf.st_atime);
1434 put_long_date(pdata+16,sbuf.st_mtime); /* write time */
1435 put_long_date(pdata+24,sbuf.st_mtime); /* change time */
1436 SIVAL(pdata,32,mode);
1438 DEBUG(5,("SMB_QFBI - "));
1440 time_t create_time = c_time;
1441 DEBUG(5,("create: %s ", ctime(&create_time)));
1443 DEBUG(5,("access: %s ", ctime(&sbuf.st_atime)));
1444 DEBUG(5,("write: %s ", ctime(&sbuf.st_mtime)));
1445 DEBUG(5,("change: %s ", ctime(&sbuf.st_mtime)));
1446 DEBUG(5,("mode: %x\n", mode));
1450 case SMB_QUERY_FILE_STANDARD_INFO:
1452 SOFF_T(pdata,0,size);
1453 SOFF_T(pdata,8,size);
1454 SIVAL(pdata,16,sbuf.st_nlink);
1456 CVAL(pdata,21) = (mode&aDIR)?1:0;
1459 case SMB_QUERY_FILE_EA_INFO:
1463 /* Get the 8.3 name - used if NT SMB was negotiated. */
1464 case SMB_QUERY_FILE_ALT_NAME_INFO:
1468 pstrcpy(short_name,base_name);
1469 /* Mangle if not already 8.3 */
1470 if(!is_8_3(short_name, True))
1472 if(!name_map_mangle(short_name,True,True,SNUM(conn)))
1475 len = srvstr_push(outbuf, pdata+4, short_name, -1,
1476 STR_TERMINATE|STR_UPPER);
1477 data_size = 4 + len;
1482 case SMB_QUERY_FILE_NAME_INFO:
1484 * The first part of this code is essential
1485 * to get security descriptors to work on mapped
1486 * drives. Don't ask how I discovered this unless
1487 * you like hearing about me suffering.... :-). JRA.
1489 if(strequal(".", fname)) {
1490 len = srvstr_push(outbuf, pdata+4, "\\", -1, STR_TERMINATE);
1492 len = srvstr_push(outbuf, pdata+4, fname, -1, STR_TERMINATE);
1494 data_size = 4 + len;
1498 case SMB_QUERY_FILE_ALLOCATION_INFO:
1499 case SMB_QUERY_FILE_END_OF_FILEINFO:
1501 SOFF_T(pdata,0,size);
1504 case SMB_QUERY_FILE_ALL_INFO:
1505 put_long_date(pdata,c_time);
1506 put_long_date(pdata+8,sbuf.st_atime);
1507 put_long_date(pdata+16,sbuf.st_mtime); /* write time */
1508 put_long_date(pdata+24,sbuf.st_mtime); /* change time */
1509 SIVAL(pdata,32,mode);
1511 SOFF_T(pdata,0,size);
1512 SOFF_T(pdata,8,size);
1513 SIVAL(pdata,16,sbuf.st_nlink);
1514 CVAL(pdata,20) = delete_pending;
1515 CVAL(pdata,21) = (mode&aDIR)?1:0;
1517 SINO_T(pdata,0,(SMB_INO_T)sbuf.st_ino);
1518 pdata += 8; /* index number */
1519 pdata += 4; /* EA info */
1521 SIVAL(pdata,0,0xA9);
1523 SIVAL(pdata,0,0xd01BF);
1525 SOFF_T(pdata,0,pos); /* current offset */
1527 SIVAL(pdata,0,mode); /* is this the right sort of mode info? */
1529 pdata += 4; /* alignment */
1530 len = srvstr_push(outbuf, pdata+4, fname, -1, STR_TERMINATE);
1533 data_size = PTR_DIFF(pdata,(*ppdata));
1537 * Windows 2000 completely undocumented new SMB info levels.
1538 * Thanks Microsoft.... sure you're working on making this
1539 * protocol a standard.... sure you are... :-).
1540 * Lying rat-bastards. JRA.
1544 SIVAL(pdata,0,mode);
1545 SIVAL(pdata,4,0); /* ??? */
1546 SOFF_T(pdata,8,size);
1547 SIVAL(pdata,16,1); /* ??? */
1548 SIVAL(pdata,20,0); /* ??? */
1553 SIVAL(pdata,0,0x907); /* ??? */
1554 SIVAL(pdata,4,0x690000); /* ??? */
1559 SIVAL(pdata,0,0); /* ??? */
1564 SIVAL(pdata,0,0x12019F); /* ??? */
1569 /* Pathname with leading '\'. */
1574 pstrcpy(new_fname, "\\");
1575 pstrcat(new_fname, fname);
1576 byte_len = dos_PutUniCode(pdata+4,new_fname,max_data_bytes,False);
1577 SIVAL(pdata,0,byte_len);
1578 data_size = 4 + byte_len;
1583 SIVAL(pdata,0,0); /* ??? */
1584 SIVAL(pdata,4,0); /* ??? */
1589 SIVAL(pdata,0,0); /* ??? */
1594 SIVAL(pdata,0,0); /* ??? */
1599 /* Not yet finished... JRA */
1605 put_long_date(pdata,c_time);
1606 put_long_date(pdata+8,sbuf.st_atime);
1607 put_long_date(pdata+16,sbuf.st_mtime); /* write time */
1608 put_long_date(pdata+24,sbuf.st_mtime); /* change time */
1609 SIVAL(pdata,32,mode);
1610 SIVAL(pdata,36,0); /* ??? */
1611 SIVAL(pdata,40,0x20); /* ??? */
1612 SIVAL(pdata,44,0); /* ??? */
1613 SOFF_T(pdata,48,size);
1614 SIVAL(pdata,56,0x1); /* ??? */
1615 SIVAL(pdata,60,0); /* ??? */
1616 SIVAL(pdata,64,0); /* ??? */
1617 SIVAL(pdata,68,length); /* Following string length in bytes. */
1618 dos_PutUniCode(pdata+72,,False);
1624 /* Last component of pathname. */
1626 size_t byte_len = dos_PutUniCode(pdata+4,fname,max_data_bytes,False);
1627 SIVAL(pdata,0,byte_len);
1628 data_size = 4 + byte_len;
1634 size_t byte_len = dos_PutUniCode(pdata+24,"::$DATA", 0xE, False);
1635 SIVAL(pdata,0,0); /* ??? */
1636 SIVAL(pdata,4,byte_len); /* Byte length of unicode string ::$DATA */
1637 SOFF_T(pdata,8,size);
1638 SIVAL(pdata,16,0x20); /* ??? */
1639 SIVAL(pdata,20,0); /* ??? */
1640 data_size = 24 + byte_len;
1645 SOFF_T(pdata,0,size);
1646 SIVAL(pdata,8,0); /* ??? */
1647 SIVAL(pdata,12,0); /* ??? */
1652 put_long_date(pdata,c_time);
1653 put_long_date(pdata+8,sbuf.st_atime);
1654 put_long_date(pdata+16,sbuf.st_mtime); /* write time */
1655 put_long_date(pdata+24,sbuf.st_mtime); /* change time */
1656 SIVAL(pdata,32,0x20); /* ??? */
1657 SIVAL(pdata,36,0); /* ??? */
1658 SOFF_T(pdata,40,size);
1659 SIVAL(pdata,48,mode);
1660 SIVAL(pdata,52,0); /* ??? */
1665 SIVAL(pdata,0,mode);
1671 * End new completely undocumented info levels... JRA.
1675 /* NT4 server just returns "invalid query" to this - if we try to answer
1676 it then NTws gets a BSOD! (tridge) */
1677 case SMB_QUERY_FILE_STREAM_INFO:
1679 SIVAL(pdata,4,size);
1680 SIVAL(pdata,12,size);
1681 len = srvstr_push(outbuf, pdata+24, fname, -1, STR_TERMINATE);
1682 SIVAL(pdata,20,len);
1683 data_size = 24 + len;
1688 return(ERROR(ERRDOS,ERRunknownlevel));
1691 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, data_size);
1696 /****************************************************************************
1697 reply to a TRANS2_SETFILEINFO (set file info by fileid)
1698 ****************************************************************************/
1699 static int call_trans2setfilepathinfo(connection_struct *conn,
1700 char *inbuf, char *outbuf, int length,
1701 int bufsize, char **pparams,
1702 char **ppdata, int total_data)
1704 char *params = *pparams;
1705 char *pdata = *ppdata;
1706 uint16 tran_call = SVAL(inbuf, smb_setup0);
1711 SMB_STRUCT_STAT sbuf;
1714 BOOL bad_path = False;
1715 files_struct *fsp = NULL;
1717 if (tran_call == TRANSACT2_SETFILEINFO) {
1718 fsp = file_fsp(params,0);
1719 info_level = SVAL(params,2);
1721 if(fsp && (fsp->is_directory || fsp->stat_open)) {
1723 * This is actually a SETFILEINFO on a directory
1724 * handle (returned from an NT SMB). NT5.0 seems
1725 * to do this call. JRA.
1727 pstrcpy(fname, fsp->fsp_name);
1728 unix_convert(fname,conn,0,&bad_path,&sbuf);
1729 if (!check_name(fname,conn) || (!VALID_STAT(sbuf))) {
1730 DEBUG(3,("fileinfo of %s failed (%s)\n",fname,strerror(errno)));
1731 if((errno == ENOENT) && bad_path)
1733 unix_ERR_class = ERRDOS;
1734 unix_ERR_code = ERRbadpath;
1736 return(UNIXERROR(ERRDOS,ERRbadpath));
1738 } else if (fsp && fsp->print_file) {
1740 * Doing a DELETE_ON_CLOSE should cancel a print job.
1742 if ((info_level == SMB_SET_FILE_DISPOSITION_INFO) && CVAL(pdata,0)) {
1743 fsp->share_mode = FILE_DELETE_ON_CLOSE;
1745 DEBUG(3,("call_trans2setfilepathinfo: Cancelling print job (%s)\n",
1749 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
1754 * Original code - this is an open file.
1756 CHECK_FSP(fsp,conn);
1759 pstrcpy(fname, fsp->fsp_name);
1762 if (vfs_fstat(fsp,fd,&sbuf) != 0) {
1763 DEBUG(3,("fstat of fnum %d failed (%s)\n",fsp->fnum, strerror(errno)));
1764 return(UNIXERROR(ERRDOS,ERRbadfid));
1769 info_level = SVAL(params,0);
1770 srvstr_pull(inbuf, fname, ¶ms[6], sizeof(fname), -1, STR_TERMINATE);
1771 unix_convert(fname,conn,0,&bad_path,&sbuf);
1772 if(!check_name(fname, conn))
1774 if((errno == ENOENT) && bad_path)
1776 unix_ERR_class = ERRDOS;
1777 unix_ERR_code = ERRbadpath;
1779 return(UNIXERROR(ERRDOS,ERRbadpath));
1782 if(!VALID_STAT(sbuf)) {
1783 DEBUG(3,("stat of %s failed (%s)\n", fname, strerror(errno)));
1784 if((errno == ENOENT) && bad_path)
1786 unix_ERR_class = ERRDOS;
1787 unix_ERR_code = ERRbadpath;
1789 return(UNIXERROR(ERRDOS,ERRbadpath));
1793 if (!CAN_WRITE(conn))
1794 return(ERROR(ERRSRV,ERRaccess));
1796 DEBUG(3,("call_trans2setfilepathinfo(%d) %s info_level=%d totdata=%d\n",
1797 tran_call,fname,info_level,total_data));
1799 /* Realloc the parameter and data sizes */
1800 params = Realloc(*pparams,2);
1801 if(params == NULL) {
1802 return(ERROR(ERRDOS,ERRnomem));
1808 size = sbuf.st_size;
1809 tvs.modtime = sbuf.st_mtime;
1810 tvs.actime = sbuf.st_atime;
1811 mode = dos_mode(conn,fname,&sbuf);
1813 if (total_data > 4 && IVAL(pdata,0) == total_data) {
1814 /* uggh, EAs for OS2 */
1815 DEBUG(4,("Rejecting EA request with total_data=%d\n",total_data));
1816 return(ERROR(ERRDOS,ERROR_EAS_NOT_SUPPORTED));
1821 case SMB_INFO_STANDARD:
1822 case SMB_INFO_QUERY_EA_SIZE:
1825 tvs.actime = make_unix_date2(pdata+l1_fdateLastAccess);
1828 tvs.modtime = make_unix_date2(pdata+l1_fdateLastWrite);
1830 mode = SVAL(pdata,l1_attrFile);
1831 size = IVAL(pdata,l1_cbFile);
1835 /* XXXX um, i don't think this is right.
1836 it's also not in the cifs6.txt spec.
1838 case SMB_INFO_QUERY_EAS_FROM_LIST:
1839 tvs.actime = make_unix_date2(pdata+8);
1840 tvs.modtime = make_unix_date2(pdata+12);
1841 size = IVAL(pdata,16);
1842 mode = IVAL(pdata,24);
1845 /* XXXX nor this. not in cifs6.txt, either. */
1846 case SMB_INFO_QUERY_ALL_EAS:
1847 tvs.actime = make_unix_date2(pdata+8);
1848 tvs.modtime = make_unix_date2(pdata+12);
1849 size = IVAL(pdata,16);
1850 mode = IVAL(pdata,24);
1853 case SMB_SET_FILE_BASIC_INFO:
1856 /* Patch to do this correctly from Paul Eggert <eggert@twinsun.com>. */
1858 time_t changed_time;
1860 /* Ignore create time at offset pdata. */
1863 tvs.actime = interpret_long_date(pdata+8);
1865 write_time = interpret_long_date(pdata+16);
1866 changed_time = interpret_long_date(pdata+24);
1868 tvs.modtime = MIN(write_time, changed_time);
1870 /* Prefer a defined time to an undefined one. */
1871 if (tvs.modtime == (time_t)0 || tvs.modtime == (time_t)-1)
1872 tvs.modtime = (write_time == (time_t)0 || write_time == (time_t)-1
1877 mode = IVAL(pdata,32);
1882 * NT seems to use this call with a size of zero
1883 * to mean truncate the file. JRA.
1888 case SMB_SET_FILE_ALLOCATION_INFO:
1890 SMB_OFF_T newsize = IVAL(pdata,0);
1891 #ifdef LARGE_SMB_OFF_T
1892 newsize |= (((SMB_OFF_T)IVAL(pdata,4)) << 32);
1893 #else /* LARGE_SMB_OFF_T */
1894 if (IVAL(pdata,4) != 0) /* more than 32 bits? */
1895 return(ERROR(ERRDOS,ERRunknownlevel));
1896 #endif /* LARGE_SMB_OFF_T */
1897 DEBUG(10,("call_trans2setfilepathinfo: Set file allocation info for file %s to %.0f\n", fname, (double)newsize ));
1903 case SMB_SET_FILE_END_OF_FILE_INFO:
1905 size = IVAL(pdata,0);
1906 #ifdef LARGE_SMB_OFF_T
1907 size |= (((SMB_OFF_T)IVAL(pdata,4)) << 32);
1908 #else /* LARGE_SMB_OFF_T */
1909 if (IVAL(pdata,4) != 0) /* more than 32 bits? */
1910 return(ERROR(ERRDOS,ERRunknownlevel));
1911 #endif /* LARGE_SMB_OFF_T */
1912 DEBUG(10,("call_trans2setfilepathinfo: Set end of file info for file %s to %.0f\n", fname, (double)size ));
1916 case SMB_SET_FILE_DISPOSITION_INFO: /* Set delete on close for open file. */
1918 BOOL delete_on_close = (CVAL(pdata,0) ? True : False);
1920 if (tran_call != TRANSACT2_SETFILEINFO)
1921 return(ERROR(ERRDOS,ERRunknownlevel));
1924 return(UNIXERROR(ERRDOS,ERRbadfid));
1927 * Only allow delete on close for files/directories opened with delete intent.
1930 if (delete_on_close && !GET_DELETE_ACCESS_REQUESTED(fsp->share_mode)) {
1931 DEBUG(10,("call_trans2setfilepathinfo: file %s delete on close flag set but delete access denied.\n",
1933 return(ERROR(ERRDOS,ERRnoaccess));
1936 if(fsp->is_directory) {
1937 fsp->directory_delete_on_close = delete_on_close;
1938 DEBUG(10, ("call_trans2setfilepathinfo: %s delete on close flag for fnum = %d, directory %s\n",
1939 delete_on_close ? "Added" : "Removed", fsp->fnum, fsp->fsp_name ));
1940 } else if(fsp->stat_open) {
1942 DEBUG(10, ("call_trans2setfilepathinfo: %s delete on close flag for fnum = %d, stat open %s\n",
1943 delete_on_close ? "Added" : "Removed", fsp->fnum, fsp->fsp_name ));
1947 files_struct *iterate_fsp;
1950 * Modify the share mode entry for all files open
1951 * on this device and inode to tell other smbds we have
1952 * changed the delete on close flag. This will be noticed
1953 * in the close code, the last closer will delete the file
1957 DEBUG(10,("call_trans2setfilepathinfo: %s delete on close flag for fnum = %d, file %s\n",
1958 delete_on_close ? "Adding" : "Removing", fsp->fnum, fsp->fsp_name ));
1960 if (lock_share_entry_fsp(fsp) == False)
1961 return(ERROR(ERRDOS,ERRnoaccess));
1963 if (!modify_delete_flag(fsp->dev, fsp->inode, delete_on_close)) {
1964 DEBUG(0,("call_trans2setfilepathinfo: failed to change delete on close flag for file %s\n",
1966 unlock_share_entry_fsp(fsp);
1967 return(ERROR(ERRDOS,ERRnoaccess));
1974 unlock_share_entry_fsp(fsp);
1977 * Go through all files we have open on the same device and
1978 * inode (hanging off the same hash bucket) and set the DELETE_ON_CLOSE_FLAG.
1979 * Other smbd's that have this file open will look in the share_mode on close.
1980 * take care of this (rare) case in close_file(). See the comment there.
1981 * NB. JRA. We don't really need to do this anymore - all should be taken
1982 * care of in the share_mode changes in the tdb.
1985 for(iterate_fsp = file_find_di_first(fsp->dev, fsp->inode);
1986 iterate_fsp; iterate_fsp = file_find_di_next(iterate_fsp))
1987 fsp->delete_on_close = delete_on_close;
1990 * Set the delete on close flag in the fsp.
1992 fsp->delete_on_close = delete_on_close;
1994 DEBUG(10, ("call_trans2setfilepathinfo: %s delete on close flag for fnum = %d, file %s\n",
1995 delete_on_close ? "Added" : "Removed", fsp->fnum, fsp->fsp_name ));
2005 * This (new) W2K call seems to set one byte. Not sure
2006 * yet what it's trying to do. JRA.
2009 unsigned char setval = CVAL(pdata,0);
2012 return(ERROR(ERRDOS,ERRnoaccess));
2016 return(ERROR(ERRDOS,ERRunknownlevel));
2020 /* get some defaults (no modifications) if any info is zero or -1. */
2021 if (tvs.actime == (time_t)0 || tvs.actime == (time_t)-1)
2022 tvs.actime = sbuf.st_atime;
2024 if (tvs.modtime == (time_t)0 || tvs.modtime == (time_t)-1)
2025 tvs.modtime = sbuf.st_mtime;
2027 DEBUG(6,("actime: %s " , ctime(&tvs.actime)));
2028 DEBUG(6,("modtime: %s ", ctime(&tvs.modtime)));
2029 DEBUG(6,("size: %.0f ", (double)size));
2030 DEBUG(6,("mode: %x\n" , mode));
2032 if(!((info_level == SMB_SET_FILE_END_OF_FILE_INFO) ||
2033 (info_level == SMB_SET_FILE_ALLOCATION_INFO) ||
2034 (info_level == 1019) ||
2035 (info_level == 1020))) {
2037 * Only do this test if we are not explicitly
2038 * changing the size of a file.
2041 size = sbuf.st_size;
2044 /* Try and set the times, size and mode of this file -
2045 if they are different from the current values
2047 if (sbuf.st_mtime != tvs.modtime || sbuf.st_atime != tvs.actime) {
2050 * This was a setfileinfo on an open file.
2051 * NT does this a lot. It's actually pointless
2052 * setting the time here, as it will be overwritten
2053 * on the next write, so we save the request
2054 * away and will set it on file code. JRA.
2057 if (tvs.modtime != (time_t)0 && tvs.modtime != (time_t)-1) {
2058 DEBUG(10,("call_trans2setfilepathinfo: setting pending modtime to %s\n",
2059 ctime(&tvs.modtime) ));
2060 fsp->pending_modtime = tvs.modtime;
2065 DEBUG(10,("call_trans2setfilepathinfo: setting utimes to modified values.\n"));
2067 if(file_utime(conn, fname, &tvs)!=0)
2068 return(UNIXERROR(ERRDOS,ERRnoaccess));
2072 /* check the mode isn't different, before changing it */
2073 if ((mode != 0) && (mode != dos_mode(conn, fname, &sbuf))) {
2075 DEBUG(10,("call_trans2setfilepathinfo: file %s : setting dos mode %x\n",
2078 if(file_chmod(conn, fname, mode, NULL)) {
2079 DEBUG(2,("chmod of %s failed (%s)\n", fname, strerror(errno)));
2080 return(UNIXERROR(ERRDOS,ERRnoaccess));
2084 if(size != sbuf.st_size) {
2086 DEBUG(10,("call_trans2setfilepathinfo: file %s : setting new size to %.0f\n",
2087 fname, (double)size ));
2090 files_struct *new_fsp = NULL;
2091 int access_mode = 0;
2094 if(global_oplock_break) {
2095 /* Queue this file modify as we are the process of an oplock break. */
2097 DEBUG(2,("call_trans2setfilepathinfo: queueing message due to being "));
2098 DEBUGADD(2,( "in oplock break state.\n"));
2100 push_oplock_pending_smb_message(inbuf, length);
2104 new_fsp = open_file_shared(conn, fname, &sbuf,
2105 SET_OPEN_MODE(DOS_OPEN_RDWR),
2106 (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN),
2107 0, 0, &access_mode, &action);
2109 if (new_fsp == NULL)
2110 return(UNIXERROR(ERRDOS,ERRbadpath));
2111 vfs_set_filelen(new_fsp, size);
2112 close_file(new_fsp,True);
2114 vfs_set_filelen(fsp, size);
2120 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
2125 /****************************************************************************
2126 reply to a TRANS2_MKDIR (make directory with extended attributes).
2127 ****************************************************************************/
2128 static int call_trans2mkdir(connection_struct *conn,
2129 char *inbuf, char *outbuf, int length, int bufsize,
2130 char **pparams, char **ppdata)
2132 char *params = *pparams;
2135 SMB_STRUCT_STAT sbuf;
2136 BOOL bad_path = False;
2138 if (!CAN_WRITE(conn))
2139 return(ERROR(ERRSRV,ERRaccess));
2141 srvstr_pull(inbuf, directory, ¶ms[4], sizeof(directory), -1, STR_TERMINATE);
2143 DEBUG(3,("call_trans2mkdir : name = %s\n", directory));
2145 unix_convert(directory,conn,0,&bad_path,&sbuf);
2146 if (check_name(directory,conn))
2147 ret = vfs_mkdir(conn,directory,unix_mode(conn,aDIR,directory));
2151 DEBUG(5,("call_trans2mkdir error (%s)\n", strerror(errno)));
2152 if((errno == ENOENT) && bad_path)
2154 unix_ERR_class = ERRDOS;
2155 unix_ERR_code = ERRbadpath;
2157 return(UNIXERROR(ERRDOS,ERRnoaccess));
2160 /* Realloc the parameter and data sizes */
2161 params = Realloc(*pparams,2);
2162 if(params == NULL) {
2163 return(ERROR(ERRDOS,ERRnomem));
2169 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
2174 /****************************************************************************
2175 reply to a TRANS2_FINDNOTIFYFIRST (start monitoring a directory for changes)
2176 We don't actually do this - we just send a null response.
2177 ****************************************************************************/
2178 static int call_trans2findnotifyfirst(connection_struct *conn,
2179 char *inbuf, char *outbuf,
2180 int length, int bufsize,
2181 char **pparams, char **ppdata)
2183 static uint16 fnf_handle = 257;
2184 char *params = *pparams;
2185 uint16 info_level = SVAL(params,4);
2187 DEBUG(3,("call_trans2findnotifyfirst - info_level %d\n", info_level));
2195 return(ERROR(ERRDOS,ERRunknownlevel));
2198 /* Realloc the parameter and data sizes */
2199 params = Realloc(*pparams,6);
2200 if(params == NULL) {
2201 return(ERROR(ERRDOS,ERRnomem));
2205 SSVAL(params,0,fnf_handle);
2206 SSVAL(params,2,0); /* No changes */
2207 SSVAL(params,4,0); /* No EA errors */
2214 send_trans2_replies(outbuf, bufsize, params, 6, *ppdata, 0);
2219 /****************************************************************************
2220 reply to a TRANS2_FINDNOTIFYNEXT (continue monitoring a directory for
2221 changes). Currently this does nothing.
2222 ****************************************************************************/
2223 static int call_trans2findnotifynext(connection_struct *conn,
2224 char *inbuf, char *outbuf,
2225 int length, int bufsize,
2226 char **pparams, char **ppdata)
2228 char *params = *pparams;
2230 DEBUG(3,("call_trans2findnotifynext\n"));
2232 /* Realloc the parameter and data sizes */
2233 params = Realloc(*pparams,4);
2234 if(params == NULL) {
2235 return(ERROR(ERRDOS,ERRnomem));
2239 SSVAL(params,0,0); /* No changes */
2240 SSVAL(params,2,0); /* No EA errors */
2242 send_trans2_replies(outbuf, bufsize, params, 4, *ppdata, 0);
2247 /****************************************************************************
2248 reply to a TRANS2_GET_DFS_REFERRAL - Shirish Kalele <kalele@veritas.com>
2249 ****************************************************************************/
2250 static int call_trans2getdfsreferral(connection_struct *conn, char* inbuf,
2251 char* outbuf, int length, int bufsize,
2252 char** pparams, char** ppdata)
2254 char *params = *pparams;
2257 int max_referral_level = SVAL(params,0);
2260 DEBUG(10,("call_trans2getdfsreferral\n"));
2262 if(!lp_host_msdfs())
2263 return(ERROR(ERRDOS,ERRbadfunc));
2265 srvstr_pull(inbuf, pathname, ¶ms[2], sizeof(pathname), -1, STR_TERMINATE);
2267 if((reply_size = setup_dfs_referral(pathname,max_referral_level,ppdata)) < 0)
2268 return(ERROR(ERRDOS,ERRbadfile));
2270 SSVAL(outbuf,smb_flg2,SVAL(outbuf,smb_flg2) | FLAGS2_DFS_PATHNAMES);
2271 send_trans2_replies(outbuf,bufsize,0,0,*ppdata,reply_size);
2276 #define LMCAT_SPL 0x53
2277 #define LMFUNC_GETJOBID 0x60
2279 /****************************************************************************
2280 reply to a TRANS2_IOCTL - used for OS/2 printing.
2281 ****************************************************************************/
2283 static int call_trans2ioctl(connection_struct *conn, char* inbuf,
2284 char* outbuf, int length, int bufsize,
2285 char** pparams, char** ppdata)
2287 char *pdata = *ppdata;
2288 files_struct *fsp = file_fsp(inbuf,smb_vwv15);
2290 if ((SVAL(inbuf,(smb_setup+4)) == LMCAT_SPL) &&
2291 (SVAL(inbuf,(smb_setup+6)) == LMFUNC_GETJOBID)) {
2292 pdata = Realloc(*ppdata, 32);
2294 return(ERROR(ERRDOS,ERRnomem));
2298 /* NOTE - THIS IS ASCII ONLY AT THE MOMENT - NOT SURE IF OS/2
2299 CAN ACCEPT THIS IN UNICODE. JRA. */
2301 SSVAL(pdata,0,fsp->print_jobid); /* Job number */
2302 srvstr_push( outbuf, pdata + 2, global_myname, 15, STR_ASCII|STR_TERMINATE); /* Our NetBIOS name */
2303 srvstr_push( outbuf, pdata+18, lp_servicename(SNUM(conn)), 13, STR_ASCII|STR_TERMINATE); /* Service name */
2304 send_trans2_replies(outbuf,bufsize,*pparams,0,*ppdata,32);
2307 DEBUG(2,("Unknown TRANS2_IOCTL\n"));
2308 return(ERROR(ERRSRV,ERRerror));
2312 /****************************************************************************
2313 reply to a SMBfindclose (stop trans2 directory search)
2314 ****************************************************************************/
2315 int reply_findclose(connection_struct *conn,
2316 char *inbuf,char *outbuf,int length,int bufsize)
2319 int dptr_num=SVALS(inbuf,smb_vwv0);
2320 START_PROFILE(SMBfindclose);
2322 DEBUG(3,("reply_findclose, dptr_num = %d\n", dptr_num));
2324 dptr_close(&dptr_num);
2326 outsize = set_message(outbuf,0,0,True);
2328 DEBUG(3,("SMBfindclose dptr_num = %d\n", dptr_num));
2330 END_PROFILE(SMBfindclose);
2334 /****************************************************************************
2335 reply to a SMBfindnclose (stop FINDNOTIFYFIRST directory search)
2336 ****************************************************************************/
2337 int reply_findnclose(connection_struct *conn,
2338 char *inbuf,char *outbuf,int length,int bufsize)
2342 START_PROFILE(SMBfindnclose);
2344 dptr_num = SVAL(inbuf,smb_vwv0);
2346 DEBUG(3,("reply_findnclose, dptr_num = %d\n", dptr_num));
2348 /* We never give out valid handles for a
2349 findnotifyfirst - so any dptr_num is ok here.
2352 outsize = set_message(outbuf,0,0,True);
2354 DEBUG(3,("SMB_findnclose dptr_num = %d\n", dptr_num));
2356 END_PROFILE(SMBfindnclose);
2361 /****************************************************************************
2362 reply to a SMBtranss2 - just ignore it!
2363 ****************************************************************************/
2364 int reply_transs2(connection_struct *conn,
2365 char *inbuf,char *outbuf,int length,int bufsize)
2367 START_PROFILE(SMBtranss2);
2368 DEBUG(4,("Ignoring transs2 of length %d\n",length));
2369 END_PROFILE(SMBtranss2);
2373 /****************************************************************************
2374 reply to a SMBtrans2
2375 ****************************************************************************/
2376 int reply_trans2(connection_struct *conn,
2377 char *inbuf,char *outbuf,int length,int bufsize)
2380 unsigned int total_params = SVAL(inbuf, smb_tpscnt);
2381 unsigned int total_data =SVAL(inbuf, smb_tdscnt);
2383 unsigned int max_param_reply = SVAL(inbuf, smb_mprcnt);
2384 unsigned int max_data_reply = SVAL(inbuf, smb_mdrcnt);
2385 unsigned int max_setup_fields = SVAL(inbuf, smb_msrcnt);
2386 BOOL close_tid = BITSETW(inbuf+smb_flags,0);
2387 BOOL no_final_response = BITSETW(inbuf+smb_flags,1);
2388 int32 timeout = IVALS(inbuf,smb_timeout);
2390 unsigned int suwcnt = SVAL(inbuf, smb_suwcnt);
2391 unsigned int tran_call = SVAL(inbuf, smb_setup0);
2392 char *params = NULL, *data = NULL;
2393 int num_params, num_params_sofar, num_data, num_data_sofar;
2394 START_PROFILE(SMBtrans2);
2396 if(global_oplock_break && (tran_call == TRANSACT2_OPEN)) {
2397 /* Queue this open message as we are the process of an
2400 DEBUG(2,("reply_trans2: queueing message trans2open due to being "));
2401 DEBUGADD(2,( "in oplock break state.\n"));
2403 push_oplock_pending_smb_message(inbuf, length);
2404 END_PROFILE(SMBtrans2);
2408 if (IS_IPC(conn) && (tran_call != TRANSACT2_OPEN)
2409 && (tran_call != TRANSACT2_GET_DFS_REFERRAL)) {
2410 END_PROFILE(SMBtrans2);
2411 return(ERROR(ERRSRV,ERRaccess));
2414 outsize = set_message(outbuf,0,0,True);
2416 /* All trans2 messages we handle have smb_sucnt == 1 - ensure this
2417 is so as a sanity check */
2420 * Need to have rc=0 for ioctl to get job id for OS/2.
2421 * Network printing will fail if function is not successful.
2422 * Similar function in reply.c will be used if protocol
2423 * is LANMAN1.0 instead of LM1.2X002.
2424 * Until DosPrintSetJobInfo with PRJINFO3 is supported,
2425 * outbuf doesn't have to be set(only job id is used).
2427 if ( (suwcnt == 4) && (tran_call == TRANSACT2_IOCTL) &&
2428 (SVAL(inbuf,(smb_setup+4)) == LMCAT_SPL) &&
2429 (SVAL(inbuf,(smb_setup+6)) == LMFUNC_GETJOBID)) {
2430 DEBUG(2,("Got Trans2 DevIOctl jobid\n"));
2432 DEBUG(2,("Invalid smb_sucnt in trans2 call(%d)\n",suwcnt));
2433 DEBUG(2,("Transaction is %d\n",tran_call));
2434 END_PROFILE(SMBtrans2);
2435 return(ERROR(ERRSRV,ERRerror));
2439 /* Allocate the space for the maximum needed parameters and data */
2440 if (total_params > 0)
2441 params = (char *)malloc(total_params);
2443 data = (char *)malloc(total_data);
2445 if ((total_params && !params) || (total_data && !data)) {
2446 DEBUG(2,("Out of memory in reply_trans2\n"));
2451 END_PROFILE(SMBtrans2);
2452 return(ERROR(ERRDOS,ERRnomem));
2455 /* Copy the param and data bytes sent with this request into
2456 the params buffer */
2457 num_params = num_params_sofar = SVAL(inbuf,smb_pscnt);
2458 num_data = num_data_sofar = SVAL(inbuf, smb_dscnt);
2460 if (num_params > total_params || num_data > total_data)
2461 exit_server("invalid params in reply_trans2");
2464 memcpy( params, smb_base(inbuf) + SVAL(inbuf, smb_psoff), num_params);
2466 memcpy( data, smb_base(inbuf) + SVAL(inbuf, smb_dsoff), num_data);
2468 if(num_data_sofar < total_data || num_params_sofar < total_params) {
2469 /* We need to send an interim response then receive the rest
2470 of the parameter/data bytes */
2471 outsize = set_message(outbuf,0,0,True);
2472 if (!send_smb(smbd_server_fd(),outbuf))
2473 exit_server("reply_trans2: send_smb failed.\n");
2475 while (num_data_sofar < total_data ||
2476 num_params_sofar < total_params) {
2479 ret = receive_next_smb(inbuf,bufsize,SMB_SECONDARY_WAIT);
2482 (CVAL(inbuf, smb_com) != SMBtranss2)) || !ret) {
2483 outsize = set_message(outbuf,0,0,True);
2485 DEBUG(0,("reply_trans2: Invalid secondary trans2 packet\n"));
2487 DEBUG(0,("reply_trans2: %s in getting secondary trans2 response.\n",
2488 (smb_read_error == READ_ERROR) ? "error" : "timeout" ));
2493 END_PROFILE(SMBtrans2);
2494 return(ERROR(ERRSRV,ERRerror));
2497 /* Revise total_params and total_data in case
2498 they have changed downwards */
2499 total_params = SVAL(inbuf, smb_tpscnt);
2500 total_data = SVAL(inbuf, smb_tdscnt);
2501 num_params_sofar += (num_params = SVAL(inbuf,smb_spscnt));
2502 num_data_sofar += ( num_data = SVAL(inbuf, smb_sdscnt));
2503 if (num_params_sofar > total_params || num_data_sofar > total_data)
2504 exit_server("data overflow in trans2");
2506 memcpy( ¶ms[ SVAL(inbuf, smb_spsdisp)],
2507 smb_base(inbuf) + SVAL(inbuf, smb_spsoff), num_params);
2508 memcpy( &data[SVAL(inbuf, smb_sdsdisp)],
2509 smb_base(inbuf)+ SVAL(inbuf, smb_sdsoff), num_data);
2513 if (Protocol >= PROTOCOL_NT1) {
2514 SSVAL(outbuf,smb_flg2,SVAL(outbuf,smb_flg2) | 0x40); /* IS_LONG_NAME */
2517 /* Now we must call the relevant TRANS2 function */
2519 case TRANSACT2_OPEN:
2520 START_PROFILE_NESTED(Trans2_open);
2521 outsize = call_trans2open(conn,
2522 inbuf, outbuf, bufsize,
2524 END_PROFILE_NESTED(Trans2_open);
2527 case TRANSACT2_FINDFIRST:
2528 START_PROFILE_NESTED(Trans2_findfirst);
2529 outsize = call_trans2findfirst(conn, inbuf, outbuf,
2530 bufsize, ¶ms, &data);
2531 END_PROFILE_NESTED(Trans2_findfirst);
2534 case TRANSACT2_FINDNEXT:
2535 START_PROFILE_NESTED(Trans2_findnext);
2536 outsize = call_trans2findnext(conn, inbuf, outbuf,
2539 END_PROFILE_NESTED(Trans2_findnext);
2542 case TRANSACT2_QFSINFO:
2543 START_PROFILE_NESTED(Trans2_qfsinfo);
2544 outsize = call_trans2qfsinfo(conn, inbuf, outbuf,
2545 length, bufsize, ¶ms,
2547 END_PROFILE_NESTED(Trans2_qfsinfo);
2550 case TRANSACT2_SETFSINFO:
2551 START_PROFILE_NESTED(Trans2_setfsinfo);
2552 outsize = call_trans2setfsinfo(conn, inbuf, outbuf,
2555 END_PROFILE_NESTED(Trans2_setfsinfo);
2558 case TRANSACT2_QPATHINFO:
2559 case TRANSACT2_QFILEINFO:
2560 START_PROFILE_NESTED(Trans2_qpathinfo);
2561 outsize = call_trans2qfilepathinfo(conn, inbuf, outbuf,
2563 ¶ms, &data, total_data);
2564 END_PROFILE_NESTED(Trans2_qpathinfo);
2566 case TRANSACT2_SETPATHINFO:
2567 case TRANSACT2_SETFILEINFO:
2568 START_PROFILE_NESTED(Trans2_setpathinfo);
2569 outsize = call_trans2setfilepathinfo(conn, inbuf, outbuf,
2573 END_PROFILE_NESTED(Trans2_setpathinfo);
2576 case TRANSACT2_FINDNOTIFYFIRST:
2577 START_PROFILE_NESTED(Trans2_findnotifyfirst);
2578 outsize = call_trans2findnotifyfirst(conn, inbuf, outbuf,
2581 END_PROFILE_NESTED(Trans2_findnotifyfirst);
2584 case TRANSACT2_FINDNOTIFYNEXT:
2585 START_PROFILE_NESTED(Trans2_findnotifynext);
2586 outsize = call_trans2findnotifynext(conn, inbuf, outbuf,
2589 END_PROFILE_NESTED(Trans2_findnotifynext);
2591 case TRANSACT2_MKDIR:
2592 START_PROFILE_NESTED(Trans2_mkdir);
2593 outsize = call_trans2mkdir(conn, inbuf, outbuf, length,
2594 bufsize, ¶ms, &data);
2595 END_PROFILE_NESTED(Trans2_mkdir);
2598 case TRANSACT2_GET_DFS_REFERRAL:
2599 START_PROFILE_NESTED(Trans2_get_dfs_referral);
2600 outsize = call_trans2getdfsreferral(conn,inbuf,outbuf,length,
2601 bufsize, ¶ms, &data);
2602 END_PROFILE_NESTED(Trans2_get_dfs_referral);
2604 case TRANSACT2_IOCTL:
2605 START_PROFILE_NESTED(Trans2_ioctl);
2606 outsize = call_trans2ioctl(conn,inbuf,outbuf,length,
2607 bufsize,¶ms,&data);
2608 END_PROFILE_NESTED(Trans2_ioctl);
2611 /* Error in request */
2612 DEBUG(2,("Unknown request %d in trans2 call\n", tran_call));
2617 END_PROFILE(SMBtrans2);
2618 return (ERROR(ERRSRV,ERRerror));
2621 /* As we do not know how many data packets will need to be
2622 returned here the various call_trans2xxxx calls
2623 must send their own. Thus a call_trans2xxx routine only
2624 returns a value other than -1 when it wants to send
2632 END_PROFILE(SMBtrans2);
2633 return outsize; /* If a correct response was needed the
2634 call_trans2xxx calls have already sent
2635 it. If outsize != -1 then it is returning */