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;
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,ERReasnotsupported));
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);
1883 case SMB_SET_FILE_ALLOCATION_INFO:
1886 size = IVAL(pdata,0);
1887 #ifdef LARGE_SMB_OFF_T
1888 size |= (((SMB_OFF_T)IVAL(pdata,4)) << 32);
1889 #else /* LARGE_SMB_OFF_T */
1890 if (IVAL(pdata,4) != 0) /* more than 32 bits? */
1891 return(ERROR(ERRDOS,ERRunknownlevel));
1892 #endif /* LARGE_SMB_OFF_T */
1893 DEBUG(10,("call_trans2setfilepathinfo: Set file allocation info for file %s to %.0f\n",
1894 fname, (double)size ));
1896 if(size != sbuf.st_size) {
1898 DEBUG(10,("call_trans2setfilepathinfo: file %s : setting new size to %.0f\n",
1899 fname, (double)size ));
1902 files_struct *new_fsp = NULL;
1903 int access_mode = 0;
1906 if(global_oplock_break) {
1907 /* Queue this file modify as we are the process of an oplock break. */
1909 DEBUG(2,("call_trans2setfilepathinfo: queueing message due to being "));
1910 DEBUGADD(2,( "in oplock break state.\n"));
1912 push_oplock_pending_smb_message(inbuf, length);
1916 new_fsp = open_file_shared(conn, fname, &sbuf,
1917 SET_OPEN_MODE(DOS_OPEN_RDWR),
1918 (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN),
1919 0, 0, &access_mode, &action);
1921 if (new_fsp == NULL)
1922 return(UNIXERROR(ERRDOS,ERRbadpath));
1923 ret = vfs_allocate_file_space(new_fsp, size);
1924 close_file(new_fsp,True);
1926 ret = vfs_allocate_file_space(fsp, size);
1929 return allocate_space_error(inbuf, outbuf, errno);
1931 sbuf.st_size = size;
1937 case SMB_SET_FILE_END_OF_FILE_INFO:
1939 size = IVAL(pdata,0);
1940 #ifdef LARGE_SMB_OFF_T
1941 size |= (((SMB_OFF_T)IVAL(pdata,4)) << 32);
1942 #else /* LARGE_SMB_OFF_T */
1943 if (IVAL(pdata,4) != 0) /* more than 32 bits? */
1944 return(ERROR(ERRDOS,ERRunknownlevel));
1945 #endif /* LARGE_SMB_OFF_T */
1946 DEBUG(10,("call_trans2setfilepathinfo: Set end of file info for file %s to %.0f\n", fname, (double)size ));
1950 case SMB_SET_FILE_DISPOSITION_INFO: /* Set delete on close for open file. */
1952 BOOL delete_on_close = (CVAL(pdata,0) ? True : False);
1954 if (tran_call != TRANSACT2_SETFILEINFO)
1955 return(ERROR(ERRDOS,ERRunknownlevel));
1958 return(UNIXERROR(ERRDOS,ERRbadfid));
1961 * Only allow delete on close for files/directories opened with delete intent.
1964 if (delete_on_close && !GET_DELETE_ACCESS_REQUESTED(fsp->share_mode)) {
1965 DEBUG(10,("call_trans2setfilepathinfo: file %s delete on close flag set but delete access denied.\n",
1967 return(ERROR(ERRDOS,ERRnoaccess));
1970 if(fsp->is_directory) {
1971 fsp->directory_delete_on_close = delete_on_close;
1972 DEBUG(10, ("call_trans2setfilepathinfo: %s delete on close flag for fnum = %d, directory %s\n",
1973 delete_on_close ? "Added" : "Removed", fsp->fnum, fsp->fsp_name ));
1974 } else if(fsp->stat_open) {
1976 DEBUG(10, ("call_trans2setfilepathinfo: %s delete on close flag for fnum = %d, stat open %s\n",
1977 delete_on_close ? "Added" : "Removed", fsp->fnum, fsp->fsp_name ));
1981 files_struct *iterate_fsp;
1984 * Modify the share mode entry for all files open
1985 * on this device and inode to tell other smbds we have
1986 * changed the delete on close flag. This will be noticed
1987 * in the close code, the last closer will delete the file
1991 DEBUG(10,("call_trans2setfilepathinfo: %s delete on close flag for fnum = %d, file %s\n",
1992 delete_on_close ? "Adding" : "Removing", fsp->fnum, fsp->fsp_name ));
1994 if (lock_share_entry_fsp(fsp) == False)
1995 return(ERROR(ERRDOS,ERRnoaccess));
1997 if (!modify_delete_flag(fsp->dev, fsp->inode, delete_on_close)) {
1998 DEBUG(0,("call_trans2setfilepathinfo: failed to change delete on close flag for file %s\n",
2000 unlock_share_entry_fsp(fsp);
2001 return(ERROR(ERRDOS,ERRnoaccess));
2008 unlock_share_entry_fsp(fsp);
2011 * Go through all files we have open on the same device and
2012 * inode (hanging off the same hash bucket) and set the DELETE_ON_CLOSE_FLAG.
2013 * Other smbd's that have this file open will look in the share_mode on close.
2014 * take care of this (rare) case in close_file(). See the comment there.
2015 * NB. JRA. We don't really need to do this anymore - all should be taken
2016 * care of in the share_mode changes in the tdb.
2019 for(iterate_fsp = file_find_di_first(fsp->dev, fsp->inode);
2020 iterate_fsp; iterate_fsp = file_find_di_next(iterate_fsp))
2021 fsp->delete_on_close = delete_on_close;
2024 * Set the delete on close flag in the fsp.
2026 fsp->delete_on_close = delete_on_close;
2028 DEBUG(10, ("call_trans2setfilepathinfo: %s delete on close flag for fnum = %d, file %s\n",
2029 delete_on_close ? "Added" : "Removed", fsp->fnum, fsp->fsp_name ));
2039 * This (new) W2K call seems to set one byte. Not sure
2040 * yet what it's trying to do. JRA.
2043 unsigned char setval = CVAL(pdata,0);
2046 return(ERROR(ERRDOS,ERRnoaccess));
2050 return(ERROR(ERRDOS,ERRunknownlevel));
2054 /* get some defaults (no modifications) if any info is zero or -1. */
2055 if (tvs.actime == (time_t)0 || tvs.actime == (time_t)-1)
2056 tvs.actime = sbuf.st_atime;
2058 if (tvs.modtime == (time_t)0 || tvs.modtime == (time_t)-1)
2059 tvs.modtime = sbuf.st_mtime;
2061 DEBUG(6,("actime: %s " , ctime(&tvs.actime)));
2062 DEBUG(6,("modtime: %s ", ctime(&tvs.modtime)));
2063 DEBUG(6,("size: %.0f ", (double)size));
2064 DEBUG(6,("mode: %x\n" , mode));
2066 if(!((info_level == SMB_SET_FILE_END_OF_FILE_INFO) ||
2067 (info_level == SMB_SET_FILE_ALLOCATION_INFO) ||
2068 (info_level == 1019) ||
2069 (info_level == 1020))) {
2071 * Only do this test if we are not explicitly
2072 * changing the size of a file.
2075 size = sbuf.st_size;
2078 /* Try and set the times, size and mode of this file -
2079 if they are different from the current values
2081 if (sbuf.st_mtime != tvs.modtime || sbuf.st_atime != tvs.actime) {
2084 * This was a setfileinfo on an open file.
2085 * NT does this a lot. It's actually pointless
2086 * setting the time here, as it will be overwritten
2087 * on the next write, so we save the request
2088 * away and will set it on file code. JRA.
2091 if (tvs.modtime != (time_t)0 && tvs.modtime != (time_t)-1) {
2092 DEBUG(10,("call_trans2setfilepathinfo: setting pending modtime to %s\n",
2093 ctime(&tvs.modtime) ));
2094 fsp->pending_modtime = tvs.modtime;
2099 DEBUG(10,("call_trans2setfilepathinfo: setting utimes to modified values.\n"));
2101 if(file_utime(conn, fname, &tvs)!=0)
2102 return(UNIXERROR(ERRDOS,ERRnoaccess));
2106 /* check the mode isn't different, before changing it */
2107 if ((mode != 0) && (mode != dos_mode(conn, fname, &sbuf))) {
2109 DEBUG(10,("call_trans2setfilepathinfo: file %s : setting dos mode %x\n",
2112 if(file_chmod(conn, fname, mode, NULL)) {
2113 DEBUG(2,("chmod of %s failed (%s)\n", fname, strerror(errno)));
2114 return(UNIXERROR(ERRDOS,ERRnoaccess));
2118 if(size != sbuf.st_size) {
2120 DEBUG(10,("call_trans2setfilepathinfo: file %s : setting new size to %.0f\n",
2121 fname, (double)size ));
2124 files_struct *new_fsp = NULL;
2125 int access_mode = 0;
2128 if(global_oplock_break) {
2129 /* Queue this file modify as we are the process of an oplock break. */
2131 DEBUG(2,("call_trans2setfilepathinfo: queueing message due to being "));
2132 DEBUGADD(2,( "in oplock break state.\n"));
2134 push_oplock_pending_smb_message(inbuf, length);
2138 new_fsp = open_file_shared(conn, fname, &sbuf,
2139 SET_OPEN_MODE(DOS_OPEN_RDWR),
2140 (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN),
2141 0, 0, &access_mode, &action);
2143 if (new_fsp == NULL)
2144 return(UNIXERROR(ERRDOS,ERRbadpath));
2145 vfs_set_filelen(new_fsp, size);
2146 close_file(new_fsp,True);
2148 vfs_set_filelen(fsp, size);
2154 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
2159 /****************************************************************************
2160 reply to a TRANS2_MKDIR (make directory with extended attributes).
2161 ****************************************************************************/
2162 static int call_trans2mkdir(connection_struct *conn,
2163 char *inbuf, char *outbuf, int length, int bufsize,
2164 char **pparams, char **ppdata)
2166 char *params = *pparams;
2169 SMB_STRUCT_STAT sbuf;
2170 BOOL bad_path = False;
2172 if (!CAN_WRITE(conn))
2173 return(ERROR(ERRSRV,ERRaccess));
2175 srvstr_pull(inbuf, directory, ¶ms[4], sizeof(directory), -1, STR_TERMINATE);
2177 DEBUG(3,("call_trans2mkdir : name = %s\n", directory));
2179 unix_convert(directory,conn,0,&bad_path,&sbuf);
2180 if (check_name(directory,conn))
2181 ret = vfs_mkdir(conn,directory,unix_mode(conn,aDIR,directory));
2185 DEBUG(5,("call_trans2mkdir error (%s)\n", strerror(errno)));
2186 if((errno == ENOENT) && bad_path)
2188 unix_ERR_class = ERRDOS;
2189 unix_ERR_code = ERRbadpath;
2191 return(UNIXERROR(ERRDOS,ERRnoaccess));
2194 /* Realloc the parameter and data sizes */
2195 params = Realloc(*pparams,2);
2196 if(params == NULL) {
2197 return(ERROR(ERRDOS,ERRnomem));
2203 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
2208 /****************************************************************************
2209 reply to a TRANS2_FINDNOTIFYFIRST (start monitoring a directory for changes)
2210 We don't actually do this - we just send a null response.
2211 ****************************************************************************/
2212 static int call_trans2findnotifyfirst(connection_struct *conn,
2213 char *inbuf, char *outbuf,
2214 int length, int bufsize,
2215 char **pparams, char **ppdata)
2217 static uint16 fnf_handle = 257;
2218 char *params = *pparams;
2219 uint16 info_level = SVAL(params,4);
2221 DEBUG(3,("call_trans2findnotifyfirst - info_level %d\n", info_level));
2229 return(ERROR(ERRDOS,ERRunknownlevel));
2232 /* Realloc the parameter and data sizes */
2233 params = Realloc(*pparams,6);
2234 if(params == NULL) {
2235 return(ERROR(ERRDOS,ERRnomem));
2239 SSVAL(params,0,fnf_handle);
2240 SSVAL(params,2,0); /* No changes */
2241 SSVAL(params,4,0); /* No EA errors */
2248 send_trans2_replies(outbuf, bufsize, params, 6, *ppdata, 0);
2253 /****************************************************************************
2254 reply to a TRANS2_FINDNOTIFYNEXT (continue monitoring a directory for
2255 changes). Currently this does nothing.
2256 ****************************************************************************/
2257 static int call_trans2findnotifynext(connection_struct *conn,
2258 char *inbuf, char *outbuf,
2259 int length, int bufsize,
2260 char **pparams, char **ppdata)
2262 char *params = *pparams;
2264 DEBUG(3,("call_trans2findnotifynext\n"));
2266 /* Realloc the parameter and data sizes */
2267 params = Realloc(*pparams,4);
2268 if(params == NULL) {
2269 return(ERROR(ERRDOS,ERRnomem));
2273 SSVAL(params,0,0); /* No changes */
2274 SSVAL(params,2,0); /* No EA errors */
2276 send_trans2_replies(outbuf, bufsize, params, 4, *ppdata, 0);
2281 /****************************************************************************
2282 reply to a TRANS2_GET_DFS_REFERRAL - Shirish Kalele <kalele@veritas.com>
2283 ****************************************************************************/
2284 static int call_trans2getdfsreferral(connection_struct *conn, char* inbuf,
2285 char* outbuf, int length, int bufsize,
2286 char** pparams, char** ppdata)
2288 char *params = *pparams;
2291 int max_referral_level = SVAL(params,0);
2294 DEBUG(10,("call_trans2getdfsreferral\n"));
2296 if(!lp_host_msdfs())
2297 return(ERROR(ERRDOS,ERRbadfunc));
2299 srvstr_pull(inbuf, pathname, ¶ms[2], sizeof(pathname), -1, STR_TERMINATE);
2301 if((reply_size = setup_dfs_referral(pathname,max_referral_level,ppdata)) < 0)
2302 return(ERROR(ERRDOS,ERRbadfile));
2304 SSVAL(outbuf,smb_flg2,SVAL(outbuf,smb_flg2) | FLAGS2_DFS_PATHNAMES);
2305 send_trans2_replies(outbuf,bufsize,0,0,*ppdata,reply_size);
2310 #define LMCAT_SPL 0x53
2311 #define LMFUNC_GETJOBID 0x60
2313 /****************************************************************************
2314 reply to a TRANS2_IOCTL - used for OS/2 printing.
2315 ****************************************************************************/
2317 static int call_trans2ioctl(connection_struct *conn, char* inbuf,
2318 char* outbuf, int length, int bufsize,
2319 char** pparams, char** ppdata)
2321 char *pdata = *ppdata;
2322 files_struct *fsp = file_fsp(inbuf,smb_vwv15);
2324 if ((SVAL(inbuf,(smb_setup+4)) == LMCAT_SPL) &&
2325 (SVAL(inbuf,(smb_setup+6)) == LMFUNC_GETJOBID)) {
2326 pdata = Realloc(*ppdata, 32);
2328 return(ERROR(ERRDOS,ERRnomem));
2332 /* NOTE - THIS IS ASCII ONLY AT THE MOMENT - NOT SURE IF OS/2
2333 CAN ACCEPT THIS IN UNICODE. JRA. */
2335 SSVAL(pdata,0,fsp->print_jobid); /* Job number */
2336 srvstr_push( outbuf, pdata + 2, global_myname, 15, STR_ASCII|STR_TERMINATE); /* Our NetBIOS name */
2337 srvstr_push( outbuf, pdata+18, lp_servicename(SNUM(conn)), 13, STR_ASCII|STR_TERMINATE); /* Service name */
2338 send_trans2_replies(outbuf,bufsize,*pparams,0,*ppdata,32);
2341 DEBUG(2,("Unknown TRANS2_IOCTL\n"));
2342 return(ERROR(ERRSRV,ERRerror));
2346 /****************************************************************************
2347 reply to a SMBfindclose (stop trans2 directory search)
2348 ****************************************************************************/
2349 int reply_findclose(connection_struct *conn,
2350 char *inbuf,char *outbuf,int length,int bufsize)
2353 int dptr_num=SVALS(inbuf,smb_vwv0);
2354 START_PROFILE(SMBfindclose);
2356 DEBUG(3,("reply_findclose, dptr_num = %d\n", dptr_num));
2358 dptr_close(&dptr_num);
2360 outsize = set_message(outbuf,0,0,True);
2362 DEBUG(3,("SMBfindclose dptr_num = %d\n", dptr_num));
2364 END_PROFILE(SMBfindclose);
2368 /****************************************************************************
2369 reply to a SMBfindnclose (stop FINDNOTIFYFIRST directory search)
2370 ****************************************************************************/
2371 int reply_findnclose(connection_struct *conn,
2372 char *inbuf,char *outbuf,int length,int bufsize)
2376 START_PROFILE(SMBfindnclose);
2378 dptr_num = SVAL(inbuf,smb_vwv0);
2380 DEBUG(3,("reply_findnclose, dptr_num = %d\n", dptr_num));
2382 /* We never give out valid handles for a
2383 findnotifyfirst - so any dptr_num is ok here.
2386 outsize = set_message(outbuf,0,0,True);
2388 DEBUG(3,("SMB_findnclose dptr_num = %d\n", dptr_num));
2390 END_PROFILE(SMBfindnclose);
2395 /****************************************************************************
2396 reply to a SMBtranss2 - just ignore it!
2397 ****************************************************************************/
2398 int reply_transs2(connection_struct *conn,
2399 char *inbuf,char *outbuf,int length,int bufsize)
2401 START_PROFILE(SMBtranss2);
2402 DEBUG(4,("Ignoring transs2 of length %d\n",length));
2403 END_PROFILE(SMBtranss2);
2407 /****************************************************************************
2408 reply to a SMBtrans2
2409 ****************************************************************************/
2410 int reply_trans2(connection_struct *conn,
2411 char *inbuf,char *outbuf,int length,int bufsize)
2414 unsigned int total_params = SVAL(inbuf, smb_tpscnt);
2415 unsigned int total_data =SVAL(inbuf, smb_tdscnt);
2417 unsigned int max_param_reply = SVAL(inbuf, smb_mprcnt);
2418 unsigned int max_data_reply = SVAL(inbuf, smb_mdrcnt);
2419 unsigned int max_setup_fields = SVAL(inbuf, smb_msrcnt);
2420 BOOL close_tid = BITSETW(inbuf+smb_flags,0);
2421 BOOL no_final_response = BITSETW(inbuf+smb_flags,1);
2422 int32 timeout = IVALS(inbuf,smb_timeout);
2424 unsigned int suwcnt = SVAL(inbuf, smb_suwcnt);
2425 unsigned int tran_call = SVAL(inbuf, smb_setup0);
2426 char *params = NULL, *data = NULL;
2427 int num_params, num_params_sofar, num_data, num_data_sofar;
2428 START_PROFILE(SMBtrans2);
2430 if(global_oplock_break && (tran_call == TRANSACT2_OPEN)) {
2431 /* Queue this open message as we are the process of an
2434 DEBUG(2,("reply_trans2: queueing message trans2open due to being "));
2435 DEBUGADD(2,( "in oplock break state.\n"));
2437 push_oplock_pending_smb_message(inbuf, length);
2438 END_PROFILE(SMBtrans2);
2442 if (IS_IPC(conn) && (tran_call != TRANSACT2_OPEN)
2443 && (tran_call != TRANSACT2_GET_DFS_REFERRAL)) {
2444 END_PROFILE(SMBtrans2);
2445 return(ERROR(ERRSRV,ERRaccess));
2448 outsize = set_message(outbuf,0,0,True);
2450 /* All trans2 messages we handle have smb_sucnt == 1 - ensure this
2451 is so as a sanity check */
2454 * Need to have rc=0 for ioctl to get job id for OS/2.
2455 * Network printing will fail if function is not successful.
2456 * Similar function in reply.c will be used if protocol
2457 * is LANMAN1.0 instead of LM1.2X002.
2458 * Until DosPrintSetJobInfo with PRJINFO3 is supported,
2459 * outbuf doesn't have to be set(only job id is used).
2461 if ( (suwcnt == 4) && (tran_call == TRANSACT2_IOCTL) &&
2462 (SVAL(inbuf,(smb_setup+4)) == LMCAT_SPL) &&
2463 (SVAL(inbuf,(smb_setup+6)) == LMFUNC_GETJOBID)) {
2464 DEBUG(2,("Got Trans2 DevIOctl jobid\n"));
2466 DEBUG(2,("Invalid smb_sucnt in trans2 call(%d)\n",suwcnt));
2467 DEBUG(2,("Transaction is %d\n",tran_call));
2468 END_PROFILE(SMBtrans2);
2469 return(ERROR(ERRSRV,ERRerror));
2473 /* Allocate the space for the maximum needed parameters and data */
2474 if (total_params > 0)
2475 params = (char *)malloc(total_params);
2477 data = (char *)malloc(total_data);
2479 if ((total_params && !params) || (total_data && !data)) {
2480 DEBUG(2,("Out of memory in reply_trans2\n"));
2485 END_PROFILE(SMBtrans2);
2486 return(ERROR(ERRDOS,ERRnomem));
2489 /* Copy the param and data bytes sent with this request into
2490 the params buffer */
2491 num_params = num_params_sofar = SVAL(inbuf,smb_pscnt);
2492 num_data = num_data_sofar = SVAL(inbuf, smb_dscnt);
2494 if (num_params > total_params || num_data > total_data)
2495 exit_server("invalid params in reply_trans2");
2498 memcpy( params, smb_base(inbuf) + SVAL(inbuf, smb_psoff), num_params);
2500 memcpy( data, smb_base(inbuf) + SVAL(inbuf, smb_dsoff), num_data);
2502 if(num_data_sofar < total_data || num_params_sofar < total_params) {
2503 /* We need to send an interim response then receive the rest
2504 of the parameter/data bytes */
2505 outsize = set_message(outbuf,0,0,True);
2506 if (!send_smb(smbd_server_fd(),outbuf))
2507 exit_server("reply_trans2: send_smb failed.\n");
2509 while (num_data_sofar < total_data ||
2510 num_params_sofar < total_params) {
2513 ret = receive_next_smb(inbuf,bufsize,SMB_SECONDARY_WAIT);
2516 (CVAL(inbuf, smb_com) != SMBtranss2)) || !ret) {
2517 outsize = set_message(outbuf,0,0,True);
2519 DEBUG(0,("reply_trans2: Invalid secondary trans2 packet\n"));
2521 DEBUG(0,("reply_trans2: %s in getting secondary trans2 response.\n",
2522 (smb_read_error == READ_ERROR) ? "error" : "timeout" ));
2527 END_PROFILE(SMBtrans2);
2528 return(ERROR(ERRSRV,ERRerror));
2531 /* Revise total_params and total_data in case
2532 they have changed downwards */
2533 total_params = SVAL(inbuf, smb_tpscnt);
2534 total_data = SVAL(inbuf, smb_tdscnt);
2535 num_params_sofar += (num_params = SVAL(inbuf,smb_spscnt));
2536 num_data_sofar += ( num_data = SVAL(inbuf, smb_sdscnt));
2537 if (num_params_sofar > total_params || num_data_sofar > total_data)
2538 exit_server("data overflow in trans2");
2540 memcpy( ¶ms[ SVAL(inbuf, smb_spsdisp)],
2541 smb_base(inbuf) + SVAL(inbuf, smb_spsoff), num_params);
2542 memcpy( &data[SVAL(inbuf, smb_sdsdisp)],
2543 smb_base(inbuf)+ SVAL(inbuf, smb_sdsoff), num_data);
2547 if (Protocol >= PROTOCOL_NT1) {
2548 SSVAL(outbuf,smb_flg2,SVAL(outbuf,smb_flg2) | 0x40); /* IS_LONG_NAME */
2551 /* Now we must call the relevant TRANS2 function */
2553 case TRANSACT2_OPEN:
2554 START_PROFILE_NESTED(Trans2_open);
2555 outsize = call_trans2open(conn,
2556 inbuf, outbuf, bufsize,
2558 END_PROFILE_NESTED(Trans2_open);
2561 case TRANSACT2_FINDFIRST:
2562 START_PROFILE_NESTED(Trans2_findfirst);
2563 outsize = call_trans2findfirst(conn, inbuf, outbuf,
2564 bufsize, ¶ms, &data);
2565 END_PROFILE_NESTED(Trans2_findfirst);
2568 case TRANSACT2_FINDNEXT:
2569 START_PROFILE_NESTED(Trans2_findnext);
2570 outsize = call_trans2findnext(conn, inbuf, outbuf,
2573 END_PROFILE_NESTED(Trans2_findnext);
2576 case TRANSACT2_QFSINFO:
2577 START_PROFILE_NESTED(Trans2_qfsinfo);
2578 outsize = call_trans2qfsinfo(conn, inbuf, outbuf,
2579 length, bufsize, ¶ms,
2581 END_PROFILE_NESTED(Trans2_qfsinfo);
2584 case TRANSACT2_SETFSINFO:
2585 START_PROFILE_NESTED(Trans2_setfsinfo);
2586 outsize = call_trans2setfsinfo(conn, inbuf, outbuf,
2589 END_PROFILE_NESTED(Trans2_setfsinfo);
2592 case TRANSACT2_QPATHINFO:
2593 case TRANSACT2_QFILEINFO:
2594 START_PROFILE_NESTED(Trans2_qpathinfo);
2595 outsize = call_trans2qfilepathinfo(conn, inbuf, outbuf,
2597 ¶ms, &data, total_data);
2598 END_PROFILE_NESTED(Trans2_qpathinfo);
2600 case TRANSACT2_SETPATHINFO:
2601 case TRANSACT2_SETFILEINFO:
2602 START_PROFILE_NESTED(Trans2_setpathinfo);
2603 outsize = call_trans2setfilepathinfo(conn, inbuf, outbuf,
2607 END_PROFILE_NESTED(Trans2_setpathinfo);
2610 case TRANSACT2_FINDNOTIFYFIRST:
2611 START_PROFILE_NESTED(Trans2_findnotifyfirst);
2612 outsize = call_trans2findnotifyfirst(conn, inbuf, outbuf,
2615 END_PROFILE_NESTED(Trans2_findnotifyfirst);
2618 case TRANSACT2_FINDNOTIFYNEXT:
2619 START_PROFILE_NESTED(Trans2_findnotifynext);
2620 outsize = call_trans2findnotifynext(conn, inbuf, outbuf,
2623 END_PROFILE_NESTED(Trans2_findnotifynext);
2625 case TRANSACT2_MKDIR:
2626 START_PROFILE_NESTED(Trans2_mkdir);
2627 outsize = call_trans2mkdir(conn, inbuf, outbuf, length,
2628 bufsize, ¶ms, &data);
2629 END_PROFILE_NESTED(Trans2_mkdir);
2632 case TRANSACT2_GET_DFS_REFERRAL:
2633 START_PROFILE_NESTED(Trans2_get_dfs_referral);
2634 outsize = call_trans2getdfsreferral(conn,inbuf,outbuf,length,
2635 bufsize, ¶ms, &data);
2636 END_PROFILE_NESTED(Trans2_get_dfs_referral);
2638 case TRANSACT2_IOCTL:
2639 START_PROFILE_NESTED(Trans2_ioctl);
2640 outsize = call_trans2ioctl(conn,inbuf,outbuf,length,
2641 bufsize,¶ms,&data);
2642 END_PROFILE_NESTED(Trans2_ioctl);
2645 /* Error in request */
2646 DEBUG(2,("Unknown request %d in trans2 call\n", tran_call));
2651 END_PROFILE(SMBtrans2);
2652 return (ERROR(ERRSRV,ERRerror));
2655 /* As we do not know how many data packets will need to be
2656 returned here the various call_trans2xxxx calls
2657 must send their own. Thus a call_trans2xxx routine only
2658 returns a value other than -1 when it wants to send
2666 END_PROFILE(SMBtrans2);
2667 return outsize; /* If a correct response was needed the
2668 call_trans2xxx calls have already sent
2669 it. If outsize != -1 then it is returning */