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 = 1; /* JRA. This used to be 3. Set to 1 to make netmon parse ok. */
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,ERReasnotsupported));
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;
1632 case SMB_FILE_STREAM_INFORMATION:
1636 size_t byte_len = dos_PutUniCode(pdata+24,"::$DATA", 0xE, False);
1637 SIVAL(pdata,0,0); /* ??? */
1638 SIVAL(pdata,4,byte_len); /* Byte length of unicode string ::$DATA */
1639 SOFF_T(pdata,8,size);
1640 SIVAL(pdata,16,0x20); /* ??? */
1641 SIVAL(pdata,20,0); /* ??? */
1642 data_size = 24 + byte_len;
1647 SOFF_T(pdata,0,size);
1648 SIVAL(pdata,8,0); /* ??? */
1649 SIVAL(pdata,12,0); /* ??? */
1654 put_long_date(pdata,c_time);
1655 put_long_date(pdata+8,sbuf.st_atime);
1656 put_long_date(pdata+16,sbuf.st_mtime); /* write time */
1657 put_long_date(pdata+24,sbuf.st_mtime); /* change time */
1658 SIVAL(pdata,32,0x20); /* ??? */
1659 SIVAL(pdata,36,0); /* ??? */
1660 SOFF_T(pdata,40,size);
1661 SIVAL(pdata,48,mode);
1662 SIVAL(pdata,52,0); /* ??? */
1667 SIVAL(pdata,0,mode);
1673 * End new completely undocumented info levels... JRA.
1677 /* NT4 server just returns "invalid query" to this - if we try to answer
1678 it then NTws gets a BSOD! (tridge) */
1679 case SMB_QUERY_FILE_STREAM_INFO:
1681 SIVAL(pdata,4,size);
1682 SIVAL(pdata,12,size);
1683 len = srvstr_push(outbuf, pdata+24, fname, -1, STR_TERMINATE);
1684 SIVAL(pdata,20,len);
1685 data_size = 24 + len;
1690 return(ERROR(ERRDOS,ERRunknownlevel));
1693 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, data_size);
1698 /****************************************************************************
1699 reply to a TRANS2_SETFILEINFO (set file info by fileid)
1700 ****************************************************************************/
1701 static int call_trans2setfilepathinfo(connection_struct *conn,
1702 char *inbuf, char *outbuf, int length,
1703 int bufsize, char **pparams,
1704 char **ppdata, int total_data)
1706 char *params = *pparams;
1707 char *pdata = *ppdata;
1708 uint16 tran_call = SVAL(inbuf, smb_setup0);
1713 SMB_STRUCT_STAT sbuf;
1716 BOOL bad_path = False;
1717 files_struct *fsp = NULL;
1719 if (tran_call == TRANSACT2_SETFILEINFO) {
1720 fsp = file_fsp(params,0);
1721 info_level = SVAL(params,2);
1723 if(fsp && (fsp->is_directory || fsp->stat_open)) {
1725 * This is actually a SETFILEINFO on a directory
1726 * handle (returned from an NT SMB). NT5.0 seems
1727 * to do this call. JRA.
1729 pstrcpy(fname, fsp->fsp_name);
1730 unix_convert(fname,conn,0,&bad_path,&sbuf);
1731 if (!check_name(fname,conn) || (!VALID_STAT(sbuf))) {
1732 DEBUG(3,("fileinfo of %s failed (%s)\n",fname,strerror(errno)));
1733 if((errno == ENOENT) && bad_path)
1735 unix_ERR_class = ERRDOS;
1736 unix_ERR_code = ERRbadpath;
1738 return(UNIXERROR(ERRDOS,ERRbadpath));
1740 } else if (fsp && fsp->print_file) {
1742 * Doing a DELETE_ON_CLOSE should cancel a print job.
1744 if ((info_level == SMB_SET_FILE_DISPOSITION_INFO) && CVAL(pdata,0)) {
1745 fsp->share_mode = FILE_DELETE_ON_CLOSE;
1747 DEBUG(3,("call_trans2setfilepathinfo: Cancelling print job (%s)\n",
1751 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
1756 * Original code - this is an open file.
1758 CHECK_FSP(fsp,conn);
1761 pstrcpy(fname, fsp->fsp_name);
1764 if (vfs_fstat(fsp,fd,&sbuf) != 0) {
1765 DEBUG(3,("fstat of fnum %d failed (%s)\n",fsp->fnum, strerror(errno)));
1766 return(UNIXERROR(ERRDOS,ERRbadfid));
1771 info_level = SVAL(params,0);
1772 srvstr_pull(inbuf, fname, ¶ms[6], sizeof(fname), -1, STR_TERMINATE);
1773 unix_convert(fname,conn,0,&bad_path,&sbuf);
1774 if(!check_name(fname, conn))
1776 if((errno == ENOENT) && bad_path)
1778 unix_ERR_class = ERRDOS;
1779 unix_ERR_code = ERRbadpath;
1781 return(UNIXERROR(ERRDOS,ERRbadpath));
1784 if(!VALID_STAT(sbuf)) {
1785 DEBUG(3,("stat of %s failed (%s)\n", fname, strerror(errno)));
1786 if((errno == ENOENT) && bad_path)
1788 unix_ERR_class = ERRDOS;
1789 unix_ERR_code = ERRbadpath;
1791 return(UNIXERROR(ERRDOS,ERRbadpath));
1795 if (!CAN_WRITE(conn))
1796 return(ERROR(ERRSRV,ERRaccess));
1798 DEBUG(3,("call_trans2setfilepathinfo(%d) %s info_level=%d totdata=%d\n",
1799 tran_call,fname,info_level,total_data));
1801 /* Realloc the parameter and data sizes */
1802 params = Realloc(*pparams,2);
1803 if(params == NULL) {
1804 return(ERROR(ERRDOS,ERRnomem));
1810 size = sbuf.st_size;
1811 tvs.modtime = sbuf.st_mtime;
1812 tvs.actime = sbuf.st_atime;
1813 mode = dos_mode(conn,fname,&sbuf);
1815 if (total_data > 4 && IVAL(pdata,0) == total_data) {
1816 /* uggh, EAs for OS2 */
1817 DEBUG(4,("Rejecting EA request with total_data=%d\n",total_data));
1818 return(ERROR(ERRDOS,ERReasnotsupported));
1823 case SMB_INFO_STANDARD:
1824 case SMB_INFO_QUERY_EA_SIZE:
1827 tvs.actime = make_unix_date2(pdata+l1_fdateLastAccess);
1830 tvs.modtime = make_unix_date2(pdata+l1_fdateLastWrite);
1832 mode = SVAL(pdata,l1_attrFile);
1833 size = IVAL(pdata,l1_cbFile);
1837 /* XXXX um, i don't think this is right.
1838 it's also not in the cifs6.txt spec.
1840 case SMB_INFO_QUERY_EAS_FROM_LIST:
1841 tvs.actime = make_unix_date2(pdata+8);
1842 tvs.modtime = make_unix_date2(pdata+12);
1843 size = IVAL(pdata,16);
1844 mode = IVAL(pdata,24);
1847 /* XXXX nor this. not in cifs6.txt, either. */
1848 case SMB_INFO_QUERY_ALL_EAS:
1849 tvs.actime = make_unix_date2(pdata+8);
1850 tvs.modtime = make_unix_date2(pdata+12);
1851 size = IVAL(pdata,16);
1852 mode = IVAL(pdata,24);
1855 case SMB_SET_FILE_BASIC_INFO:
1858 /* Patch to do this correctly from Paul Eggert <eggert@twinsun.com>. */
1860 time_t changed_time;
1862 /* Ignore create time at offset pdata. */
1865 tvs.actime = interpret_long_date(pdata+8);
1867 write_time = interpret_long_date(pdata+16);
1868 changed_time = interpret_long_date(pdata+24);
1870 tvs.modtime = MIN(write_time, changed_time);
1872 /* Prefer a defined time to an undefined one. */
1873 if (tvs.modtime == (time_t)0 || tvs.modtime == (time_t)-1)
1874 tvs.modtime = (write_time == (time_t)0 || write_time == (time_t)-1
1879 mode = IVAL(pdata,32);
1885 case SMB_SET_FILE_ALLOCATION_INFO:
1888 size = IVAL(pdata,0);
1889 #ifdef LARGE_SMB_OFF_T
1890 size |= (((SMB_OFF_T)IVAL(pdata,4)) << 32);
1891 #else /* LARGE_SMB_OFF_T */
1892 if (IVAL(pdata,4) != 0) /* more than 32 bits? */
1893 return(ERROR(ERRDOS,ERRunknownlevel));
1894 #endif /* LARGE_SMB_OFF_T */
1895 DEBUG(10,("call_trans2setfilepathinfo: Set file allocation info for file %s to %.0f\n",
1896 fname, (double)size ));
1898 if(size != sbuf.st_size) {
1900 DEBUG(10,("call_trans2setfilepathinfo: file %s : setting new size to %.0f\n",
1901 fname, (double)size ));
1904 files_struct *new_fsp = NULL;
1905 int access_mode = 0;
1908 if(global_oplock_break) {
1909 /* Queue this file modify as we are the process of an oplock break. */
1911 DEBUG(2,("call_trans2setfilepathinfo: queueing message due to being "));
1912 DEBUGADD(2,( "in oplock break state.\n"));
1914 push_oplock_pending_smb_message(inbuf, length);
1918 new_fsp = open_file_shared(conn, fname, &sbuf,
1919 SET_OPEN_MODE(DOS_OPEN_RDWR),
1920 (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN),
1921 0, 0, &access_mode, &action);
1923 if (new_fsp == NULL)
1924 return(UNIXERROR(ERRDOS,ERRbadpath));
1925 ret = vfs_allocate_file_space(new_fsp, size);
1926 close_file(new_fsp,True);
1928 ret = vfs_allocate_file_space(fsp, size);
1931 return allocate_space_error(inbuf, outbuf, errno);
1933 sbuf.st_size = size;
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_FILE_DISPOSITION_INFORMATION:
1953 case SMB_SET_FILE_DISPOSITION_INFO: /* Set delete on close for open file. */
1955 BOOL delete_on_close = (CVAL(pdata,0) ? True : False);
1957 if (tran_call != TRANSACT2_SETFILEINFO)
1958 return(ERROR(ERRDOS,ERRunknownlevel));
1961 return(UNIXERROR(ERRDOS,ERRbadfid));
1964 * Only allow delete on close for files/directories opened with delete intent.
1967 if (delete_on_close && !GET_DELETE_ACCESS_REQUESTED(fsp->share_mode)) {
1968 DEBUG(10,("call_trans2setfilepathinfo: file %s delete on close flag set but delete access denied.\n",
1970 return(ERROR(ERRDOS,ERRnoaccess));
1973 if(fsp->is_directory) {
1974 fsp->directory_delete_on_close = delete_on_close;
1975 DEBUG(10, ("call_trans2setfilepathinfo: %s delete on close flag for fnum = %d, directory %s\n",
1976 delete_on_close ? "Added" : "Removed", fsp->fnum, fsp->fsp_name ));
1977 } else if(fsp->stat_open) {
1979 DEBUG(10, ("call_trans2setfilepathinfo: %s delete on close flag for fnum = %d, stat open %s\n",
1980 delete_on_close ? "Added" : "Removed", fsp->fnum, fsp->fsp_name ));
1984 files_struct *iterate_fsp;
1987 * Modify the share mode entry for all files open
1988 * on this device and inode to tell other smbds we have
1989 * changed the delete on close flag. This will be noticed
1990 * in the close code, the last closer will delete the file
1994 DEBUG(10,("call_trans2setfilepathinfo: %s delete on close flag for fnum = %d, file %s\n",
1995 delete_on_close ? "Adding" : "Removing", fsp->fnum, fsp->fsp_name ));
1997 if (lock_share_entry_fsp(fsp) == False)
1998 return(ERROR(ERRDOS,ERRnoaccess));
2000 if (!modify_delete_flag(fsp->dev, fsp->inode, delete_on_close)) {
2001 DEBUG(0,("call_trans2setfilepathinfo: failed to change delete on close flag for file %s\n",
2003 unlock_share_entry_fsp(fsp);
2004 return(ERROR(ERRDOS,ERRnoaccess));
2011 unlock_share_entry_fsp(fsp);
2014 * Go through all files we have open on the same device and
2015 * inode (hanging off the same hash bucket) and set the DELETE_ON_CLOSE_FLAG.
2016 * Other smbd's that have this file open will look in the share_mode on close.
2017 * take care of this (rare) case in close_file(). See the comment there.
2018 * NB. JRA. We don't really need to do this anymore - all should be taken
2019 * care of in the share_mode changes in the tdb.
2022 for(iterate_fsp = file_find_di_first(fsp->dev, fsp->inode);
2023 iterate_fsp; iterate_fsp = file_find_di_next(iterate_fsp))
2024 fsp->delete_on_close = delete_on_close;
2027 * Set the delete on close flag in the fsp.
2029 fsp->delete_on_close = delete_on_close;
2031 DEBUG(10, ("call_trans2setfilepathinfo: %s delete on close flag for fnum = %d, file %s\n",
2032 delete_on_close ? "Added" : "Removed", fsp->fnum, fsp->fsp_name ));
2041 return(ERROR(ERRDOS,ERRunknownlevel));
2045 /* get some defaults (no modifications) if any info is zero or -1. */
2046 if (tvs.actime == (time_t)0 || tvs.actime == (time_t)-1)
2047 tvs.actime = sbuf.st_atime;
2049 if (tvs.modtime == (time_t)0 || tvs.modtime == (time_t)-1)
2050 tvs.modtime = sbuf.st_mtime;
2052 DEBUG(6,("actime: %s " , ctime(&tvs.actime)));
2053 DEBUG(6,("modtime: %s ", ctime(&tvs.modtime)));
2054 DEBUG(6,("size: %.0f ", (double)size));
2055 DEBUG(6,("mode: %x\n" , mode));
2057 if(!((info_level == SMB_SET_FILE_END_OF_FILE_INFO) ||
2058 (info_level == SMB_SET_FILE_ALLOCATION_INFO) ||
2059 (info_level == 1019) ||
2060 (info_level == 1020))) {
2062 * Only do this test if we are not explicitly
2063 * changing the size of a file.
2066 size = sbuf.st_size;
2069 /* Try and set the times, size and mode of this file -
2070 if they are different from the current values
2072 if (sbuf.st_mtime != tvs.modtime || sbuf.st_atime != tvs.actime) {
2075 * This was a setfileinfo on an open file.
2076 * NT does this a lot. It's actually pointless
2077 * setting the time here, as it will be overwritten
2078 * on the next write, so we save the request
2079 * away and will set it on file code. JRA.
2082 if (tvs.modtime != (time_t)0 && tvs.modtime != (time_t)-1) {
2083 DEBUG(10,("call_trans2setfilepathinfo: setting pending modtime to %s\n",
2084 ctime(&tvs.modtime) ));
2085 fsp->pending_modtime = tvs.modtime;
2090 DEBUG(10,("call_trans2setfilepathinfo: setting utimes to modified values.\n"));
2092 if(file_utime(conn, fname, &tvs)!=0)
2093 return(UNIXERROR(ERRDOS,ERRnoaccess));
2097 /* check the mode isn't different, before changing it */
2098 if ((mode != 0) && (mode != dos_mode(conn, fname, &sbuf))) {
2100 DEBUG(10,("call_trans2setfilepathinfo: file %s : setting dos mode %x\n",
2103 if(file_chmod(conn, fname, mode, NULL)) {
2104 DEBUG(2,("chmod of %s failed (%s)\n", fname, strerror(errno)));
2105 return(UNIXERROR(ERRDOS,ERRnoaccess));
2109 if(size != sbuf.st_size) {
2111 DEBUG(10,("call_trans2setfilepathinfo: file %s : setting new size to %.0f\n",
2112 fname, (double)size ));
2115 files_struct *new_fsp = NULL;
2116 int access_mode = 0;
2119 if(global_oplock_break) {
2120 /* Queue this file modify as we are the process of an oplock break. */
2122 DEBUG(2,("call_trans2setfilepathinfo: queueing message due to being "));
2123 DEBUGADD(2,( "in oplock break state.\n"));
2125 push_oplock_pending_smb_message(inbuf, length);
2129 new_fsp = open_file_shared(conn, fname, &sbuf,
2130 SET_OPEN_MODE(DOS_OPEN_RDWR),
2131 (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN),
2132 0, 0, &access_mode, &action);
2134 if (new_fsp == NULL)
2135 return(UNIXERROR(ERRDOS,ERRbadpath));
2136 vfs_set_filelen(new_fsp, size);
2137 close_file(new_fsp,True);
2139 vfs_set_filelen(fsp, size);
2145 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
2150 /****************************************************************************
2151 reply to a TRANS2_MKDIR (make directory with extended attributes).
2152 ****************************************************************************/
2153 static int call_trans2mkdir(connection_struct *conn,
2154 char *inbuf, char *outbuf, int length, int bufsize,
2155 char **pparams, char **ppdata)
2157 char *params = *pparams;
2160 SMB_STRUCT_STAT sbuf;
2161 BOOL bad_path = False;
2163 if (!CAN_WRITE(conn))
2164 return(ERROR(ERRSRV,ERRaccess));
2166 srvstr_pull(inbuf, directory, ¶ms[4], sizeof(directory), -1, STR_TERMINATE);
2168 DEBUG(3,("call_trans2mkdir : name = %s\n", directory));
2170 unix_convert(directory,conn,0,&bad_path,&sbuf);
2171 if (check_name(directory,conn))
2172 ret = vfs_mkdir(conn,directory,unix_mode(conn,aDIR,directory));
2176 DEBUG(5,("call_trans2mkdir error (%s)\n", strerror(errno)));
2177 if((errno == ENOENT) && bad_path)
2179 unix_ERR_class = ERRDOS;
2180 unix_ERR_code = ERRbadpath;
2182 return(UNIXERROR(ERRDOS,ERRnoaccess));
2185 /* Realloc the parameter and data sizes */
2186 params = Realloc(*pparams,2);
2187 if(params == NULL) {
2188 return(ERROR(ERRDOS,ERRnomem));
2194 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
2199 /****************************************************************************
2200 reply to a TRANS2_FINDNOTIFYFIRST (start monitoring a directory for changes)
2201 We don't actually do this - we just send a null response.
2202 ****************************************************************************/
2203 static int call_trans2findnotifyfirst(connection_struct *conn,
2204 char *inbuf, char *outbuf,
2205 int length, int bufsize,
2206 char **pparams, char **ppdata)
2208 static uint16 fnf_handle = 257;
2209 char *params = *pparams;
2210 uint16 info_level = SVAL(params,4);
2212 DEBUG(3,("call_trans2findnotifyfirst - info_level %d\n", info_level));
2220 return(ERROR(ERRDOS,ERRunknownlevel));
2223 /* Realloc the parameter and data sizes */
2224 params = Realloc(*pparams,6);
2225 if(params == NULL) {
2226 return(ERROR(ERRDOS,ERRnomem));
2230 SSVAL(params,0,fnf_handle);
2231 SSVAL(params,2,0); /* No changes */
2232 SSVAL(params,4,0); /* No EA errors */
2239 send_trans2_replies(outbuf, bufsize, params, 6, *ppdata, 0);
2244 /****************************************************************************
2245 reply to a TRANS2_FINDNOTIFYNEXT (continue monitoring a directory for
2246 changes). Currently this does nothing.
2247 ****************************************************************************/
2248 static int call_trans2findnotifynext(connection_struct *conn,
2249 char *inbuf, char *outbuf,
2250 int length, int bufsize,
2251 char **pparams, char **ppdata)
2253 char *params = *pparams;
2255 DEBUG(3,("call_trans2findnotifynext\n"));
2257 /* Realloc the parameter and data sizes */
2258 params = Realloc(*pparams,4);
2259 if(params == NULL) {
2260 return(ERROR(ERRDOS,ERRnomem));
2264 SSVAL(params,0,0); /* No changes */
2265 SSVAL(params,2,0); /* No EA errors */
2267 send_trans2_replies(outbuf, bufsize, params, 4, *ppdata, 0);
2272 /****************************************************************************
2273 reply to a TRANS2_GET_DFS_REFERRAL - Shirish Kalele <kalele@veritas.com>
2274 ****************************************************************************/
2275 static int call_trans2getdfsreferral(connection_struct *conn, char* inbuf,
2276 char* outbuf, int length, int bufsize,
2277 char** pparams, char** ppdata)
2279 char *params = *pparams;
2282 int max_referral_level = SVAL(params,0);
2285 DEBUG(10,("call_trans2getdfsreferral\n"));
2287 if(!lp_host_msdfs())
2288 return(ERROR(ERRDOS,ERRbadfunc));
2290 srvstr_pull(inbuf, pathname, ¶ms[2], sizeof(pathname), -1, STR_TERMINATE);
2292 if((reply_size = setup_dfs_referral(pathname,max_referral_level,ppdata)) < 0)
2293 return(ERROR(ERRDOS,ERRbadfile));
2295 SSVAL(outbuf,smb_flg2,SVAL(outbuf,smb_flg2) | FLAGS2_DFS_PATHNAMES);
2296 send_trans2_replies(outbuf,bufsize,0,0,*ppdata,reply_size);
2301 #define LMCAT_SPL 0x53
2302 #define LMFUNC_GETJOBID 0x60
2304 /****************************************************************************
2305 reply to a TRANS2_IOCTL - used for OS/2 printing.
2306 ****************************************************************************/
2308 static int call_trans2ioctl(connection_struct *conn, char* inbuf,
2309 char* outbuf, int length, int bufsize,
2310 char** pparams, char** ppdata)
2312 char *pdata = *ppdata;
2313 files_struct *fsp = file_fsp(inbuf,smb_vwv15);
2315 if ((SVAL(inbuf,(smb_setup+4)) == LMCAT_SPL) &&
2316 (SVAL(inbuf,(smb_setup+6)) == LMFUNC_GETJOBID)) {
2317 pdata = Realloc(*ppdata, 32);
2319 return(ERROR(ERRDOS,ERRnomem));
2323 /* NOTE - THIS IS ASCII ONLY AT THE MOMENT - NOT SURE IF OS/2
2324 CAN ACCEPT THIS IN UNICODE. JRA. */
2326 SSVAL(pdata,0,fsp->print_jobid); /* Job number */
2327 srvstr_push( outbuf, pdata + 2, global_myname, 15, STR_ASCII|STR_TERMINATE); /* Our NetBIOS name */
2328 srvstr_push( outbuf, pdata+18, lp_servicename(SNUM(conn)), 13, STR_ASCII|STR_TERMINATE); /* Service name */
2329 send_trans2_replies(outbuf,bufsize,*pparams,0,*ppdata,32);
2332 DEBUG(2,("Unknown TRANS2_IOCTL\n"));
2333 return(ERROR(ERRSRV,ERRerror));
2337 /****************************************************************************
2338 reply to a SMBfindclose (stop trans2 directory search)
2339 ****************************************************************************/
2340 int reply_findclose(connection_struct *conn,
2341 char *inbuf,char *outbuf,int length,int bufsize)
2344 int dptr_num=SVALS(inbuf,smb_vwv0);
2345 START_PROFILE(SMBfindclose);
2347 DEBUG(3,("reply_findclose, dptr_num = %d\n", dptr_num));
2349 dptr_close(&dptr_num);
2351 outsize = set_message(outbuf,0,0,True);
2353 DEBUG(3,("SMBfindclose dptr_num = %d\n", dptr_num));
2355 END_PROFILE(SMBfindclose);
2359 /****************************************************************************
2360 reply to a SMBfindnclose (stop FINDNOTIFYFIRST directory search)
2361 ****************************************************************************/
2362 int reply_findnclose(connection_struct *conn,
2363 char *inbuf,char *outbuf,int length,int bufsize)
2367 START_PROFILE(SMBfindnclose);
2369 dptr_num = SVAL(inbuf,smb_vwv0);
2371 DEBUG(3,("reply_findnclose, dptr_num = %d\n", dptr_num));
2373 /* We never give out valid handles for a
2374 findnotifyfirst - so any dptr_num is ok here.
2377 outsize = set_message(outbuf,0,0,True);
2379 DEBUG(3,("SMB_findnclose dptr_num = %d\n", dptr_num));
2381 END_PROFILE(SMBfindnclose);
2386 /****************************************************************************
2387 reply to a SMBtranss2 - just ignore it!
2388 ****************************************************************************/
2389 int reply_transs2(connection_struct *conn,
2390 char *inbuf,char *outbuf,int length,int bufsize)
2392 START_PROFILE(SMBtranss2);
2393 DEBUG(4,("Ignoring transs2 of length %d\n",length));
2394 END_PROFILE(SMBtranss2);
2398 /****************************************************************************
2399 reply to a SMBtrans2
2400 ****************************************************************************/
2401 int reply_trans2(connection_struct *conn,
2402 char *inbuf,char *outbuf,int length,int bufsize)
2405 unsigned int total_params = SVAL(inbuf, smb_tpscnt);
2406 unsigned int total_data =SVAL(inbuf, smb_tdscnt);
2408 unsigned int max_param_reply = SVAL(inbuf, smb_mprcnt);
2409 unsigned int max_data_reply = SVAL(inbuf, smb_mdrcnt);
2410 unsigned int max_setup_fields = SVAL(inbuf, smb_msrcnt);
2411 BOOL close_tid = BITSETW(inbuf+smb_flags,0);
2412 BOOL no_final_response = BITSETW(inbuf+smb_flags,1);
2413 int32 timeout = IVALS(inbuf,smb_timeout);
2415 unsigned int suwcnt = SVAL(inbuf, smb_suwcnt);
2416 unsigned int tran_call = SVAL(inbuf, smb_setup0);
2417 char *params = NULL, *data = NULL;
2418 int num_params, num_params_sofar, num_data, num_data_sofar;
2419 START_PROFILE(SMBtrans2);
2421 if(global_oplock_break && (tran_call == TRANSACT2_OPEN)) {
2422 /* Queue this open message as we are the process of an
2425 DEBUG(2,("reply_trans2: queueing message trans2open due to being "));
2426 DEBUGADD(2,( "in oplock break state.\n"));
2428 push_oplock_pending_smb_message(inbuf, length);
2429 END_PROFILE(SMBtrans2);
2433 if (IS_IPC(conn) && (tran_call != TRANSACT2_OPEN)
2434 && (tran_call != TRANSACT2_GET_DFS_REFERRAL)) {
2435 END_PROFILE(SMBtrans2);
2436 return(ERROR(ERRSRV,ERRaccess));
2439 outsize = set_message(outbuf,0,0,True);
2441 /* All trans2 messages we handle have smb_sucnt == 1 - ensure this
2442 is so as a sanity check */
2445 * Need to have rc=0 for ioctl to get job id for OS/2.
2446 * Network printing will fail if function is not successful.
2447 * Similar function in reply.c will be used if protocol
2448 * is LANMAN1.0 instead of LM1.2X002.
2449 * Until DosPrintSetJobInfo with PRJINFO3 is supported,
2450 * outbuf doesn't have to be set(only job id is used).
2452 if ( (suwcnt == 4) && (tran_call == TRANSACT2_IOCTL) &&
2453 (SVAL(inbuf,(smb_setup+4)) == LMCAT_SPL) &&
2454 (SVAL(inbuf,(smb_setup+6)) == LMFUNC_GETJOBID)) {
2455 DEBUG(2,("Got Trans2 DevIOctl jobid\n"));
2457 DEBUG(2,("Invalid smb_sucnt in trans2 call(%d)\n",suwcnt));
2458 DEBUG(2,("Transaction is %d\n",tran_call));
2459 END_PROFILE(SMBtrans2);
2460 return(ERROR(ERRSRV,ERRerror));
2464 /* Allocate the space for the maximum needed parameters and data */
2465 if (total_params > 0)
2466 params = (char *)malloc(total_params);
2468 data = (char *)malloc(total_data);
2470 if ((total_params && !params) || (total_data && !data)) {
2471 DEBUG(2,("Out of memory in reply_trans2\n"));
2476 END_PROFILE(SMBtrans2);
2477 return(ERROR(ERRDOS,ERRnomem));
2480 /* Copy the param and data bytes sent with this request into
2481 the params buffer */
2482 num_params = num_params_sofar = SVAL(inbuf,smb_pscnt);
2483 num_data = num_data_sofar = SVAL(inbuf, smb_dscnt);
2485 if (num_params > total_params || num_data > total_data)
2486 exit_server("invalid params in reply_trans2");
2489 memcpy( params, smb_base(inbuf) + SVAL(inbuf, smb_psoff), num_params);
2491 memcpy( data, smb_base(inbuf) + SVAL(inbuf, smb_dsoff), num_data);
2493 if(num_data_sofar < total_data || num_params_sofar < total_params) {
2494 /* We need to send an interim response then receive the rest
2495 of the parameter/data bytes */
2496 outsize = set_message(outbuf,0,0,True);
2497 if (!send_smb(smbd_server_fd(),outbuf))
2498 exit_server("reply_trans2: send_smb failed.\n");
2500 while (num_data_sofar < total_data ||
2501 num_params_sofar < total_params) {
2504 ret = receive_next_smb(inbuf,bufsize,SMB_SECONDARY_WAIT);
2507 (CVAL(inbuf, smb_com) != SMBtranss2)) || !ret) {
2508 outsize = set_message(outbuf,0,0,True);
2510 DEBUG(0,("reply_trans2: Invalid secondary trans2 packet\n"));
2512 DEBUG(0,("reply_trans2: %s in getting secondary trans2 response.\n",
2513 (smb_read_error == READ_ERROR) ? "error" : "timeout" ));
2518 END_PROFILE(SMBtrans2);
2519 return(ERROR(ERRSRV,ERRerror));
2522 /* Revise total_params and total_data in case
2523 they have changed downwards */
2524 total_params = SVAL(inbuf, smb_tpscnt);
2525 total_data = SVAL(inbuf, smb_tdscnt);
2526 num_params_sofar += (num_params = SVAL(inbuf,smb_spscnt));
2527 num_data_sofar += ( num_data = SVAL(inbuf, smb_sdscnt));
2528 if (num_params_sofar > total_params || num_data_sofar > total_data)
2529 exit_server("data overflow in trans2");
2531 memcpy( ¶ms[ SVAL(inbuf, smb_spsdisp)],
2532 smb_base(inbuf) + SVAL(inbuf, smb_spsoff), num_params);
2533 memcpy( &data[SVAL(inbuf, smb_sdsdisp)],
2534 smb_base(inbuf)+ SVAL(inbuf, smb_sdsoff), num_data);
2538 if (Protocol >= PROTOCOL_NT1) {
2539 SSVAL(outbuf,smb_flg2,SVAL(outbuf,smb_flg2) | 0x40); /* IS_LONG_NAME */
2542 /* Now we must call the relevant TRANS2 function */
2544 case TRANSACT2_OPEN:
2545 START_PROFILE_NESTED(Trans2_open);
2546 outsize = call_trans2open(conn,
2547 inbuf, outbuf, bufsize,
2549 END_PROFILE_NESTED(Trans2_open);
2552 case TRANSACT2_FINDFIRST:
2553 START_PROFILE_NESTED(Trans2_findfirst);
2554 outsize = call_trans2findfirst(conn, inbuf, outbuf,
2555 bufsize, ¶ms, &data);
2556 END_PROFILE_NESTED(Trans2_findfirst);
2559 case TRANSACT2_FINDNEXT:
2560 START_PROFILE_NESTED(Trans2_findnext);
2561 outsize = call_trans2findnext(conn, inbuf, outbuf,
2564 END_PROFILE_NESTED(Trans2_findnext);
2567 case TRANSACT2_QFSINFO:
2568 START_PROFILE_NESTED(Trans2_qfsinfo);
2569 outsize = call_trans2qfsinfo(conn, inbuf, outbuf,
2570 length, bufsize, ¶ms,
2572 END_PROFILE_NESTED(Trans2_qfsinfo);
2575 case TRANSACT2_SETFSINFO:
2576 START_PROFILE_NESTED(Trans2_setfsinfo);
2577 outsize = call_trans2setfsinfo(conn, inbuf, outbuf,
2580 END_PROFILE_NESTED(Trans2_setfsinfo);
2583 case TRANSACT2_QPATHINFO:
2584 case TRANSACT2_QFILEINFO:
2585 START_PROFILE_NESTED(Trans2_qpathinfo);
2586 outsize = call_trans2qfilepathinfo(conn, inbuf, outbuf,
2588 ¶ms, &data, total_data);
2589 END_PROFILE_NESTED(Trans2_qpathinfo);
2591 case TRANSACT2_SETPATHINFO:
2592 case TRANSACT2_SETFILEINFO:
2593 START_PROFILE_NESTED(Trans2_setpathinfo);
2594 outsize = call_trans2setfilepathinfo(conn, inbuf, outbuf,
2598 END_PROFILE_NESTED(Trans2_setpathinfo);
2601 case TRANSACT2_FINDNOTIFYFIRST:
2602 START_PROFILE_NESTED(Trans2_findnotifyfirst);
2603 outsize = call_trans2findnotifyfirst(conn, inbuf, outbuf,
2606 END_PROFILE_NESTED(Trans2_findnotifyfirst);
2609 case TRANSACT2_FINDNOTIFYNEXT:
2610 START_PROFILE_NESTED(Trans2_findnotifynext);
2611 outsize = call_trans2findnotifynext(conn, inbuf, outbuf,
2614 END_PROFILE_NESTED(Trans2_findnotifynext);
2616 case TRANSACT2_MKDIR:
2617 START_PROFILE_NESTED(Trans2_mkdir);
2618 outsize = call_trans2mkdir(conn, inbuf, outbuf, length,
2619 bufsize, ¶ms, &data);
2620 END_PROFILE_NESTED(Trans2_mkdir);
2623 case TRANSACT2_GET_DFS_REFERRAL:
2624 START_PROFILE_NESTED(Trans2_get_dfs_referral);
2625 outsize = call_trans2getdfsreferral(conn,inbuf,outbuf,length,
2626 bufsize, ¶ms, &data);
2627 END_PROFILE_NESTED(Trans2_get_dfs_referral);
2629 case TRANSACT2_IOCTL:
2630 START_PROFILE_NESTED(Trans2_ioctl);
2631 outsize = call_trans2ioctl(conn,inbuf,outbuf,length,
2632 bufsize,¶ms,&data);
2633 END_PROFILE_NESTED(Trans2_ioctl);
2636 /* Error in request */
2637 DEBUG(2,("Unknown request %d in trans2 call\n", tran_call));
2642 END_PROFILE(SMBtrans2);
2643 return (ERROR(ERRSRV,ERRerror));
2646 /* As we do not know how many data packets will need to be
2647 returned here the various call_trans2xxxx calls
2648 must send their own. Thus a call_trans2xxx routine only
2649 returns a value other than -1 when it wants to send
2657 END_PROFILE(SMBtrans2);
2658 return outsize; /* If a correct response was needed the
2659 call_trans2xxx calls have already sent
2660 it. If outsize != -1 then it is returning */