2 Unix SMB/Netbios implementation.
4 SMB transaction2 handling
5 Copyright (C) Jeremy Allison 1994-1998
7 Extensively modified by Andrew Tridgell, 1995
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26 extern int DEBUGLEVEL;
28 extern BOOL case_sensitive;
29 extern int smb_read_error;
30 extern fstring local_machine;
31 extern int global_oplock_break;
32 extern uint32 global_client_caps;
33 extern pstring global_myname;
35 /****************************************************************************
36 Send the required number of replies back.
37 We assume all fields other than the data fields are
38 set correctly for the type of call.
39 HACK ! Always assumes smb_setup field is zero.
40 ****************************************************************************/
41 static int send_trans2_replies(char *outbuf, int bufsize, char *params,
42 int paramsize, char *pdata, int datasize)
44 /* As we are using a protocol > LANMAN1 then the max_send
45 variable must have been set in the sessetupX call.
46 This takes precedence over the max_xmit field in the
47 global struct. These different max_xmit variables should
48 be merged as this is now too confusing */
51 int data_to_send = datasize;
52 int params_to_send = paramsize;
56 int params_sent_thistime, data_sent_thistime, total_sent_thistime;
57 int alignment_offset = 3;
58 int data_alignment_offset = 0;
60 /* Initially set the wcnt area to be 10 - this is true for all
62 set_message(outbuf,10,0,True);
64 /* If there genuinely are no parameters or data to send just send
66 if(params_to_send == 0 && data_to_send == 0)
68 if (!send_smb(smbd_server_fd(),outbuf))
69 exit_server("send_trans2_replies: send_smb failed.\n");
73 /* When sending params and data ensure that both are nicely aligned */
74 /* Only do this alignment when there is also data to send - else
75 can cause NT redirector problems. */
76 if (((params_to_send % 4) != 0) && (data_to_send != 0))
77 data_alignment_offset = 4 - (params_to_send % 4);
79 /* Space is bufsize minus Netbios over TCP header minus SMB header */
80 /* The alignment_offset is to align the param bytes on an even byte
81 boundary. NT 4.0 Beta needs this to work correctly. */
82 useable_space = bufsize - ((smb_buf(outbuf)+
83 alignment_offset+data_alignment_offset) -
86 /* useable_space can never be more than max_send minus the
88 useable_space = MIN(useable_space,
89 max_send - (alignment_offset+data_alignment_offset));
92 while (params_to_send || data_to_send)
94 /* Calculate whether we will totally or partially fill this packet */
95 total_sent_thistime = params_to_send + data_to_send +
96 alignment_offset + data_alignment_offset;
97 /* We can never send more than useable_space */
99 * Note that 'useable_space' does not include the alignment offsets,
100 * but we must include the alignment offsets in the calculation of
101 * the length of the data we send over the wire, as the alignment offsets
102 * are sent here. Fix from Marc_Jacobsen@hp.com.
104 total_sent_thistime = MIN(total_sent_thistime, useable_space+
105 alignment_offset + data_alignment_offset);
107 set_message(outbuf, 10, total_sent_thistime, True);
109 /* Set total params and data to be sent */
110 SSVAL(outbuf,smb_tprcnt,paramsize);
111 SSVAL(outbuf,smb_tdrcnt,datasize);
113 /* Calculate how many parameters and data we can fit into
114 this packet. Parameters get precedence */
116 params_sent_thistime = MIN(params_to_send,useable_space);
117 data_sent_thistime = useable_space - params_sent_thistime;
118 data_sent_thistime = MIN(data_sent_thistime,data_to_send);
120 SSVAL(outbuf,smb_prcnt, params_sent_thistime);
122 /* smb_proff is the offset from the start of the SMB header to the
123 parameter bytes, however the first 4 bytes of outbuf are
124 the Netbios over TCP header. Thus use smb_base() to subtract
125 them from the calculation */
127 SSVAL(outbuf,smb_proff,((smb_buf(outbuf)+alignment_offset) - smb_base(outbuf)));
129 if(params_sent_thistime == 0)
130 SSVAL(outbuf,smb_prdisp,0);
132 /* Absolute displacement of param bytes sent in this packet */
133 SSVAL(outbuf,smb_prdisp,pp - params);
135 SSVAL(outbuf,smb_drcnt, data_sent_thistime);
136 if(data_sent_thistime == 0)
138 SSVAL(outbuf,smb_droff,0);
139 SSVAL(outbuf,smb_drdisp, 0);
143 /* The offset of the data bytes is the offset of the
144 parameter bytes plus the number of parameters being sent this time */
145 SSVAL(outbuf,smb_droff,((smb_buf(outbuf)+alignment_offset) -
146 smb_base(outbuf)) + params_sent_thistime + data_alignment_offset);
147 SSVAL(outbuf,smb_drdisp, pd - pdata);
150 /* Copy the param bytes into the packet */
151 if(params_sent_thistime)
152 memcpy((smb_buf(outbuf)+alignment_offset),pp,params_sent_thistime);
153 /* Copy in the data bytes */
154 if(data_sent_thistime)
155 memcpy(smb_buf(outbuf)+alignment_offset+params_sent_thistime+
156 data_alignment_offset,pd,data_sent_thistime);
158 DEBUG(9,("t2_rep: params_sent_thistime = %d, data_sent_thistime = %d, useable_space = %d\n",
159 params_sent_thistime, data_sent_thistime, useable_space));
160 DEBUG(9,("t2_rep: params_to_send = %d, data_to_send = %d, paramsize = %d, datasize = %d\n",
161 params_to_send, data_to_send, paramsize, datasize));
163 /* Send the packet */
164 if (!send_smb(smbd_server_fd(),outbuf))
165 exit_server("send_trans2_replies: send_smb failed.\n");
167 pp += params_sent_thistime;
168 pd += data_sent_thistime;
170 params_to_send -= params_sent_thistime;
171 data_to_send -= data_sent_thistime;
174 if(params_to_send < 0 || data_to_send < 0)
176 DEBUG(0,("send_trans2_replies failed sanity check pts = %d, dts = %d\n!!!",
177 params_to_send, data_to_send));
186 /****************************************************************************
187 reply to a TRANSACT2_OPEN
188 ****************************************************************************/
189 static int call_trans2open(connection_struct *conn, char *inbuf, char *outbuf,
191 char **pparams, char **ppdata)
193 char *params = *pparams;
194 int16 open_mode = SVAL(params, 2);
195 int16 open_attr = SVAL(params,6);
196 BOOL oplock_request = (((SVAL(params,0)|(1<<1))>>1) | ((SVAL(params,0)|(1<<2))>>1));
198 BOOL return_additional_info = BITSETW(params,0);
199 int16 open_sattr = SVAL(params, 4);
200 time_t open_time = make_unix_date3(params+8);
202 int16 open_ofun = SVAL(params,12);
203 int32 open_size = IVAL(params,14);
204 char *pname = ¶ms[28];
208 int fmode=0,mtime=0,rmode;
210 SMB_STRUCT_STAT sbuf;
212 BOOL bad_path = False;
215 srvstr_pull(inbuf, fname, pname, sizeof(fname), -1, STR_TERMINATE);
217 DEBUG(3,("trans2open %s mode=%d attr=%d ofun=%d size=%d\n",
218 fname,open_mode, open_attr, open_ofun, open_size));
221 return(ERROR(ERRSRV,ERRaccess));
224 /* XXXX we need to handle passed times, sattr and flags */
226 unix_convert(fname,conn,0,&bad_path,&sbuf);
228 if (!check_name(fname,conn))
230 if((errno == ENOENT) && bad_path)
232 unix_ERR_class = ERRDOS;
233 unix_ERR_code = ERRbadpath;
235 return(UNIXERROR(ERRDOS,ERRnoaccess));
238 unixmode = unix_mode(conn,open_attr | aARCH, fname);
240 fsp = open_file_shared(conn,fname,&sbuf,open_mode,open_ofun,unixmode,
241 oplock_request, &rmode,&smb_action);
245 if((errno == ENOENT) && bad_path)
247 unix_ERR_class = ERRDOS;
248 unix_ERR_code = ERRbadpath;
250 return(UNIXERROR(ERRDOS,ERRnoaccess));
254 fmode = dos_mode(conn,fname,&sbuf);
255 mtime = sbuf.st_mtime;
258 close_file(fsp,False);
259 return(ERROR(ERRDOS,ERRnoaccess));
262 /* Realloc the size of parameters and data we will return */
263 params = Realloc(*pparams, 28);
264 if( params == NULL ) {
265 return(ERROR(ERRDOS,ERRnomem));
269 memset((char *)params,'\0',28);
270 SSVAL(params,0,fsp->fnum);
271 SSVAL(params,2,fmode);
272 put_dos_date2(params,4, mtime);
273 SIVAL(params,8, (uint32)size);
274 SSVAL(params,12,rmode);
276 if (oplock_request && lp_fake_oplocks(SNUM(conn))) {
277 smb_action |= EXTENDED_OPLOCK_GRANTED;
280 SSVAL(params,18,smb_action);
282 * WARNING - this may need to be changed if SMB_INO_T <> 4 bytes.
284 SIVAL(params,20,inode);
286 /* Send the required number of replies */
287 send_trans2_replies(outbuf, bufsize, params, 28, *ppdata, 0);
292 /*********************************************************
293 * Routine to check if a given string matches exactly.
294 * as a special case a mask of "." does NOT match. That
295 * is required for correct wildcard semantics
296 * Case can be significant or not.
297 **********************************************************/
298 static BOOL exact_match(char *str,char *mask, BOOL case_sig)
300 if (mask[0] == '.' && mask[1] == 0) return False;
301 if (case_sig) return strcmp(str,mask)==0;
302 return strcasecmp(str,mask) == 0;
305 /****************************************************************************
306 get a level dependent lanman2 dir entry.
307 ****************************************************************************/
308 static BOOL get_lanman2_dir_entry(connection_struct *conn,
309 void *inbuf, void *outbuf,
310 char *path_mask,int dirtype,int info_level,
311 int requires_resume_key,
312 BOOL dont_descend,char **ppdata,
313 char *base_data, int space_remaining,
314 BOOL *out_of_space, BOOL *got_exact_match,
319 SMB_STRUCT_STAT sbuf;
323 char *p, *q, *pdata = *ppdata;
329 time_t mdate=0, adate=0, cdate=0;
332 int nt_extmode; /* Used for NT connections instead of mode */
333 BOOL needslash = ( conn->dirpath[strlen(conn->dirpath) -1] != '/');
336 *out_of_space = False;
337 *got_exact_match = False;
342 p = strrchr(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)));
439 DEBUG(5,("get_lanman2_dir_entry found %s fname=%s\n",pathreal,fname));
445 name_map_mangle(fname,False,True,SNUM(conn));
450 nt_extmode = mode ? mode : FILE_ATTRIBUTE_NORMAL;
455 if(requires_resume_key) {
459 put_dos_date2(p,l1_fdateCreation,cdate);
460 put_dos_date2(p,l1_fdateLastAccess,adate);
461 put_dos_date2(p,l1_fdateLastWrite,mdate);
462 SIVAL(p,l1_cbFile,(uint32)size);
463 SIVAL(p,l1_cbFileAlloc,SMB_ROUNDUP(size,1024));
464 SSVAL(p,l1_attrFile,mode);
467 len = srvstr_push(outbuf, p, fname, -1,
468 STR_TERMINATE|STR_CONVERT);
475 if(requires_resume_key) {
479 put_dos_date2(p,l2_fdateCreation,cdate);
480 put_dos_date2(p,l2_fdateLastAccess,adate);
481 put_dos_date2(p,l2_fdateLastWrite,mdate);
482 SIVAL(p,l2_cbFile,(uint32)size);
483 SIVAL(p,l2_cbFileAlloc,SMB_ROUNDUP(size,1024));
484 SSVAL(p,l2_attrFile,mode);
485 SIVAL(p,l2_cbList,0); /* No extended attributes */
488 len = srvstr_push(outbuf, p, fname, -1,
489 STR_TERMINATE|STR_CONVERT);
496 put_dos_date2(p,4,cdate);
497 put_dos_date2(p,8,adate);
498 put_dos_date2(p,12,mdate);
499 SIVAL(p,16,(uint32)size);
500 SIVAL(p,20,SMB_ROUNDUP(size,1024));
505 len = srvstr_push(outbuf, p, fname, -1,
506 STR_TERMINATE|STR_CONVERT);
512 if(requires_resume_key) {
517 put_dos_date2(p,4,cdate);
518 put_dos_date2(p,8,adate);
519 put_dos_date2(p,12,mdate);
520 SIVAL(p,16,(uint32)size);
521 SIVAL(p,20,SMB_ROUNDUP(size,1024));
525 len = srvstr_push(outbuf, p, fname, -1,
526 STR_TERMINATE|STR_CONVERT);
529 SIVAL(q,4,PTR_DIFF(p, q));
533 case SMB_FIND_FILE_BOTH_DIRECTORY_INFO:
534 was_8_3 = is_8_3(fname, True);
536 SIVAL(p,0,reskey); p += 4;
537 put_long_date(p,cdate); p += 8;
538 put_long_date(p,adate); p += 8;
539 put_long_date(p,mdate); p += 8;
540 put_long_date(p,mdate); p += 8;
544 SIVAL(p,0,nt_extmode); p += 4;
546 SIVAL(p,0,0); p += 4;
548 pstring mangled_name;
549 pstrcpy(mangled_name, fname);
550 name_map_mangle(mangled_name,True,True,SNUM(conn));
551 mangled_name[12] = 0;
552 len = srvstr_push(outbuf, p+2, mangled_name, 24,
553 STR_CONVERT|STR_UPPER);
560 len = srvstr_push(outbuf, p, fname, -1,
561 STR_TERMINATE|STR_CONVERT);
564 len = PTR_DIFF(p, pdata);
565 len = (len + 3) & ~3;
570 case SMB_FIND_FILE_DIRECTORY_INFO:
572 SIVAL(p,0,reskey); p += 4;
573 put_long_date(p,cdate); p += 8;
574 put_long_date(p,adate); p += 8;
575 put_long_date(p,mdate); p += 8;
576 put_long_date(p,mdate); p += 8;
580 SIVAL(p,0,nt_extmode); p += 4;
582 len = srvstr_push(outbuf, p, fname, -1,
583 STR_TERMINATE|STR_CONVERT);
586 len = PTR_DIFF(p, pdata);
587 len = (len + 3) & ~3;
593 case SMB_FIND_FILE_FULL_DIRECTORY_INFO:
595 SIVAL(p,0,reskey); p += 4;
596 put_long_date(p,cdate); p += 8;
597 put_long_date(p,adate); p += 8;
598 put_long_date(p,mdate); p += 8;
599 put_long_date(p,mdate); p += 8;
603 SIVAL(p,0,nt_extmode); p += 4;
605 SIVAL(p,0,0); p += 4;
607 len = srvstr_push(outbuf, p, fname, -1,
608 STR_TERMINATE|STR_CONVERT);
612 len = PTR_DIFF(p, pdata);
613 len = (len + 3) & ~3;
618 case SMB_FIND_FILE_NAMES_INFO:
620 SIVAL(p,0,reskey); p += 4;
622 len = srvstr_push(outbuf, p, fname, -1,
623 STR_TERMINATE|STR_CONVERT);
626 len = PTR_DIFF(p, pdata);
627 len = (len + 3) & ~3;
637 if (PTR_DIFF(p,pdata) > space_remaining) {
638 /* Move the dirptr back to prev_dirpos */
639 SeekDir(conn->dirptr, prev_dirpos);
640 *out_of_space = True;
641 DEBUG(9,("get_lanman2_dir_entry: out of space\n"));
642 return False; /* Not finished - just out of space */
645 /* Setup the last_filename pointer, as an offset from base_data */
646 *last_name_off = PTR_DIFF(nameptr,base_data);
647 /* Advance the data pointer to the next slot */
654 /****************************************************************************
655 Reply to a TRANS2_FINDFIRST.
656 ****************************************************************************/
658 static int call_trans2findfirst(connection_struct *conn,
659 char *inbuf, char *outbuf, int bufsize,
660 char **pparams, char **ppdata)
662 /* We must be careful here that we don't return more than the
663 allowed number of data bytes. If this means returning fewer than
664 maxentries then so be it. We assume that the redirector has
665 enough room for the fixed number of parameter bytes it has
667 uint32 max_data_bytes = SVAL(inbuf, smb_mdrcnt);
668 char *params = *pparams;
669 char *pdata = *ppdata;
670 int dirtype = SVAL(params,0);
671 int maxentries = SVAL(params,2);
672 BOOL close_after_first = BITSETW(params+4,0);
673 BOOL close_if_end = BITSETW(params+4,1);
674 BOOL requires_resume_key = BITSETW(params+4,2);
675 int info_level = SVAL(params,6);
683 BOOL finished = False;
684 BOOL dont_descend = False;
685 BOOL out_of_space = False;
687 BOOL bad_path = False;
688 SMB_STRUCT_STAT sbuf;
690 *directory = *mask = 0;
692 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",
693 dirtype, maxentries, close_after_first, close_if_end, requires_resume_key,
694 info_level, max_data_bytes));
702 case SMB_FIND_FILE_DIRECTORY_INFO:
703 case SMB_FIND_FILE_FULL_DIRECTORY_INFO:
704 case SMB_FIND_FILE_NAMES_INFO:
705 case SMB_FIND_FILE_BOTH_DIRECTORY_INFO:
708 return(ERROR(ERRDOS,ERRunknownlevel));
711 srvstr_pull(inbuf, directory, params+12, sizeof(directory), -1, STR_TERMINATE);
713 RESOLVE_FINDFIRST_DFSPATH(directory, conn, inbuf, outbuf);
715 unix_convert(directory,conn,0,&bad_path,&sbuf);
716 if(!check_name(directory,conn)) {
717 if((errno == ENOENT) && bad_path)
719 unix_ERR_class = ERRDOS;
720 unix_ERR_code = ERRbadpath;
724 /* Ugly - NT specific hack - maybe not needed ? (JRA) */
725 if((errno == ENOTDIR) && (Protocol >= PROTOCOL_NT1) &&
726 (get_remote_arch() == RA_WINNT))
728 unix_ERR_class = ERRDOS;
729 unix_ERR_code = ERRbaddirectory;
733 return(UNIXERROR(ERRDOS,ERRbadpath));
736 p = strrchr(directory,'/');
738 pstrcpy(mask,directory);
739 pstrcpy(directory,"./");
745 DEBUG(5,("dir=%s, mask = %s\n",directory, mask));
747 pdata = Realloc(*ppdata, max_data_bytes + 1024);
748 if( pdata == NULL ) {
749 return(ERROR(ERRDOS,ERRnomem));
752 memset((char *)pdata,'\0',max_data_bytes + 1024);
754 /* Realloc the params space */
755 params = Realloc(*pparams, 10);
756 if( params == NULL ) {
757 return(ERROR(ERRDOS,ERRnomem));
761 dptr_num = dptr_create(conn,directory, False, True ,SVAL(inbuf,smb_pid));
763 return(UNIXERROR(ERRDOS,ERRbadfile));
765 /* Save the wildcard match and attribs we are using on this directory -
766 needed as lanman2 assumes these are being saved between calls */
768 if(!(wcard = strdup(mask))) {
769 dptr_close(&dptr_num);
770 return(ERROR(ERRDOS,ERRnomem));
773 dptr_set_wcard(dptr_num, wcard);
774 dptr_set_attr(dptr_num, dirtype);
776 DEBUG(4,("dptr_num is %d, wcard = %s, attr = %d\n",dptr_num, wcard, dirtype));
778 /* We don't need to check for VOL here as this is returned by
779 a different TRANS2 call. */
781 DEBUG(8,("dirpath=<%s> dontdescend=<%s>\n",
782 conn->dirpath,lp_dontdescend(SNUM(conn))));
783 if (in_list(conn->dirpath,lp_dontdescend(SNUM(conn)),case_sensitive))
787 space_remaining = max_data_bytes;
788 out_of_space = False;
790 for (i=0;(i<maxentries) && !finished && !out_of_space;i++)
792 BOOL got_exact_match = False;
794 /* this is a heuristic to avoid seeking the dirptr except when
795 absolutely necessary. It allows for a filename of about 40 chars */
796 if (space_remaining < DIRLEN_GUESS && numentries > 0)
803 finished = !get_lanman2_dir_entry(conn,
805 mask,dirtype,info_level,
806 requires_resume_key,dont_descend,
807 &p,pdata,space_remaining, &out_of_space, &got_exact_match,
811 if (finished && out_of_space)
814 if (!finished && !out_of_space)
818 * As an optimisation if we know we aren't looking
819 * for a wildcard name (ie. the name matches the wildcard exactly)
820 * then we can finish on any (first) match.
821 * This speeds up large directory searches. JRA.
827 space_remaining = max_data_bytes - PTR_DIFF(p,pdata);
830 /* Check if we can close the dirptr */
831 if(close_after_first || (finished && close_if_end))
833 DEBUG(5,("call_trans2findfirst - (2) closing dptr_num %d\n", dptr_num));
834 dptr_close(&dptr_num);
838 * If there are no matching entries we must return ERRDOS/ERRbadfile -
839 * from observation of NT.
844 dptr_close(&dptr_num);
845 return(ERROR(ERRDOS,ERRbadfile));
848 /* At this point pdata points to numentries directory entries. */
850 /* Set up the return parameter block */
851 SSVAL(params,0,dptr_num);
852 SSVAL(params,2,numentries);
853 SSVAL(params,4,finished);
854 SSVAL(params,6,0); /* Never an EA error */
855 SSVAL(params,8,last_name_off);
857 send_trans2_replies( outbuf, bufsize, params, 10, pdata, PTR_DIFF(p,pdata));
859 if ((! *directory) && dptr_path(dptr_num))
860 slprintf(directory,sizeof(directory)-1, "(%s)",dptr_path(dptr_num));
862 DEBUG( 4, ( "%s mask=%s directory=%s dirtype=%d numentries=%d\n",
863 smb_fn_name(CVAL(inbuf,smb_com)),
864 mask, directory, dirtype, numentries ) );
867 * Force a name mangle here to ensure that the
868 * mask as an 8.3 name is top of the mangled cache.
869 * The reasons for this are subtle. Don't remove
870 * this code unless you know what you are doing
871 * (see PR#13758). JRA.
874 if(!is_8_3( mask, False))
875 name_map_mangle(mask, True, True, SNUM(conn));
881 /****************************************************************************
882 reply to a TRANS2_FINDNEXT
883 ****************************************************************************/
884 static int call_trans2findnext(connection_struct *conn,
885 char *inbuf, char *outbuf,
886 int length, int bufsize,
887 char **pparams, char **ppdata)
889 /* We must be careful here that we don't return more than the
890 allowed number of data bytes. If this means returning fewer than
891 maxentries then so be it. We assume that the redirector has
892 enough room for the fixed number of parameter bytes it has
894 int max_data_bytes = SVAL(inbuf, smb_mdrcnt);
895 char *params = *pparams;
896 char *pdata = *ppdata;
897 int dptr_num = SVAL(params,0);
898 int maxentries = SVAL(params,2);
899 uint16 info_level = SVAL(params,4);
900 uint32 resume_key = IVAL(params,6);
901 BOOL close_after_request = BITSETW(params+10,0);
902 BOOL close_if_end = BITSETW(params+10,1);
903 BOOL requires_resume_key = BITSETW(params+10,2);
904 BOOL continue_bit = BITSETW(params+10,3);
911 int i, last_name_off=0;
912 BOOL finished = False;
913 BOOL dont_descend = False;
914 BOOL out_of_space = False;
917 *mask = *directory = *resume_name = 0;
919 srvstr_pull(inbuf, resume_name, params+12, sizeof(resume_name), -1, STR_TERMINATE|STR_CONVERT);
921 DEBUG(3,("call_trans2findnext: dirhandle = %d, max_data_bytes = %d, maxentries = %d, \
922 close_after_request=%d, close_if_end = %d requires_resume_key = %d \
923 resume_key = %d resume name = %s continue=%d level = %d\n",
924 dptr_num, max_data_bytes, maxentries, close_after_request, close_if_end,
925 requires_resume_key, resume_key, resume_name, continue_bit, info_level));
933 case SMB_FIND_FILE_DIRECTORY_INFO:
934 case SMB_FIND_FILE_FULL_DIRECTORY_INFO:
935 case SMB_FIND_FILE_NAMES_INFO:
936 case SMB_FIND_FILE_BOTH_DIRECTORY_INFO:
939 return(ERROR(ERRDOS,ERRunknownlevel));
942 pdata = Realloc( *ppdata, max_data_bytes + 1024);
944 return(ERROR(ERRDOS,ERRnomem));
947 memset((char *)pdata,'\0',max_data_bytes + 1024);
949 /* Realloc the params space */
950 params = Realloc(*pparams, 6*SIZEOFWORD);
951 if( params == NULL ) {
952 return(ERROR(ERRDOS,ERRnomem));
956 /* Check that the dptr is valid */
957 if(!(conn->dirptr = dptr_fetch_lanman2(dptr_num)))
958 return(ERROR(ERRDOS,ERRnofiles));
960 string_set(&conn->dirpath,dptr_path(dptr_num));
962 /* Get the wildcard mask from the dptr */
963 if((p = dptr_wcard(dptr_num))== NULL) {
964 DEBUG(2,("dptr_num %d has no wildcard\n", dptr_num));
965 return (ERROR(ERRDOS,ERRnofiles));
968 pstrcpy(directory,conn->dirpath);
970 /* Get the attr mask from the dptr */
971 dirtype = dptr_attr(dptr_num);
973 DEBUG(3,("dptr_num is %d, mask = %s, attr = %x, dirptr=(0x%lX,%d)\n",
974 dptr_num, mask, dirtype,
976 TellDir(conn->dirptr)));
978 /* We don't need to check for VOL here as this is returned by
979 a different TRANS2 call. */
981 DEBUG(8,("dirpath=<%s> dontdescend=<%s>\n",conn->dirpath,lp_dontdescend(SNUM(conn))));
982 if (in_list(conn->dirpath,lp_dontdescend(SNUM(conn)),case_sensitive))
986 space_remaining = max_data_bytes;
987 out_of_space = False;
990 * Seek to the correct position. We no longer use the resume key but
991 * depend on the last file name instead.
993 if(requires_resume_key && *resume_name && !continue_bit)
996 * Fix for NT redirector problem triggered by resume key indexes
997 * changing between directory scans. We now return a resume key of 0
998 * and instead look for the filename to continue from (also given
999 * to us by NT/95/smbfs/smbclient). If no other scans have been done between the
1000 * findfirst/findnext (as is usual) then the directory pointer
1001 * should already be at the correct place. Check this by scanning
1002 * backwards looking for an exact (ie. case sensitive) filename match.
1003 * If we get to the beginning of the directory and haven't found it then scan
1004 * forwards again looking for a match. JRA.
1007 int current_pos, start_pos;
1009 void *dirptr = conn->dirptr;
1010 start_pos = TellDir(dirptr);
1011 for(current_pos = start_pos; current_pos >= 0; current_pos--)
1013 DEBUG(7,("call_trans2findnext: seeking to pos %d\n", current_pos));
1015 SeekDir(dirptr, current_pos);
1016 dname = ReadDirName(dirptr);
1019 * Remember, name_map_mangle is called by
1020 * get_lanman2_dir_entry(), so the resume name
1021 * could be mangled. Ensure we do the same
1026 name_map_mangle( dname, False, True, SNUM(conn));
1028 if(dname && strcsequal( resume_name, dname))
1030 SeekDir(dirptr, current_pos+1);
1031 DEBUG(7,("call_trans2findnext: got match at pos %d\n", current_pos+1 ));
1037 * Scan forward from start if not found going backwards.
1042 DEBUG(7,("call_trans2findnext: notfound: seeking to pos %d\n", start_pos));
1043 SeekDir(dirptr, start_pos);
1044 for(current_pos = start_pos; (dname = ReadDirName(dirptr)) != NULL; SeekDir(dirptr,++current_pos))
1047 * Remember, name_map_mangle is called by
1048 * get_lanman2_dir_entry(), so the resume name
1049 * could be mangled. Ensure we do the same
1054 name_map_mangle( dname, False, True, SNUM(conn));
1056 if(dname && strcsequal( resume_name, dname))
1058 SeekDir(dirptr, current_pos+1);
1059 DEBUG(7,("call_trans2findnext: got match at pos %d\n", current_pos+1 ));
1063 } /* end if current_pos */
1064 } /* end if requires_resume_key && !continue_bit */
1066 for (i=0;(i<(int)maxentries) && !finished && !out_of_space ;i++)
1068 BOOL got_exact_match = False;
1070 /* this is a heuristic to avoid seeking the dirptr except when
1071 absolutely necessary. It allows for a filename of about 40 chars */
1072 if (space_remaining < DIRLEN_GUESS && numentries > 0)
1074 out_of_space = True;
1079 finished = !get_lanman2_dir_entry(conn,
1081 mask,dirtype,info_level,
1082 requires_resume_key,dont_descend,
1083 &p,pdata,space_remaining, &out_of_space, &got_exact_match,
1087 if (finished && out_of_space)
1090 if (!finished && !out_of_space)
1094 * As an optimisation if we know we aren't looking
1095 * for a wildcard name (ie. the name matches the wildcard exactly)
1096 * then we can finish on any (first) match.
1097 * This speeds up large directory searches. JRA.
1103 space_remaining = max_data_bytes - PTR_DIFF(p,pdata);
1106 /* Check if we can close the dirptr */
1107 if(close_after_request || (finished && close_if_end))
1109 DEBUG(5,("call_trans2findnext: closing dptr_num = %d\n", dptr_num));
1110 dptr_close(&dptr_num); /* This frees up the saved mask */
1114 /* Set up the return parameter block */
1115 SSVAL(params,0,numentries);
1116 SSVAL(params,2,finished);
1117 SSVAL(params,4,0); /* Never an EA error */
1118 SSVAL(params,6,last_name_off);
1120 send_trans2_replies( outbuf, bufsize, params, 8, pdata, PTR_DIFF(p,pdata));
1122 if ((! *directory) && dptr_path(dptr_num))
1123 slprintf(directory,sizeof(directory)-1, "(%s)",dptr_path(dptr_num));
1125 DEBUG( 3, ( "%s mask=%s directory=%s dirtype=%d numentries=%d\n",
1126 smb_fn_name(CVAL(inbuf,smb_com)),
1127 mask, directory, dirtype, numentries ) );
1132 /****************************************************************************
1133 reply to a TRANS2_QFSINFO (query filesystem info)
1134 ****************************************************************************/
1136 static int call_trans2qfsinfo(connection_struct *conn,
1137 char *inbuf, char *outbuf,
1138 int length, int bufsize,
1139 char **pparams, char **ppdata)
1141 int max_data_bytes = SVAL(inbuf, smb_mdrcnt);
1142 char *pdata = *ppdata;
1143 char *params = *pparams;
1144 uint16 info_level = SVAL(params,0);
1147 char *vname = volume_label(SNUM(conn));
1148 int snum = SNUM(conn);
1149 char *fstype = lp_fstype(SNUM(conn));
1151 DEBUG(3,("call_trans2qfsinfo: level = %d\n", info_level));
1153 if(vfs_stat(conn,".",&st)!=0) {
1154 DEBUG(2,("call_trans2qfsinfo: stat of . failed (%s)\n", strerror(errno)));
1155 return (ERROR(ERRSRV,ERRinvdevice));
1158 pdata = Realloc(*ppdata, max_data_bytes + 1024);
1159 if ( pdata == NULL ) {
1160 return(ERROR(ERRDOS,ERRnomem));
1163 memset((char *)pdata,'\0',max_data_bytes + 1024);
1169 SMB_BIG_UINT dfree,dsize,bsize;
1171 conn->vfs_ops.disk_free(conn,".",False,&bsize,&dfree,&dsize);
1172 SIVAL(pdata,l1_idFileSystem,st.st_dev);
1173 SIVAL(pdata,l1_cSectorUnit,bsize/512);
1174 SIVAL(pdata,l1_cUnit,dsize);
1175 SIVAL(pdata,l1_cUnitAvail,dfree);
1176 SSVAL(pdata,l1_cbSector,512);
1177 DEBUG(5,("call_trans2qfsinfo : bsize=%u, id=%x, cSectorUnit=%u, cUnit=%u, cUnitAvail=%u, cbSector=%d\n",
1178 (unsigned int)bsize, (unsigned int)st.st_dev, ((unsigned int)bsize)/512, (unsigned int)dsize,
1179 (unsigned int)dfree, 512));
1183 /* Return volume name */
1185 * Add volume serial number - hash of a combination of
1186 * the called hostname and the service name.
1188 SIVAL(pdata,0,str_checksum(lp_servicename(snum)) ^ (str_checksum(local_machine)<<16) );
1189 len = srvstr_push(outbuf, pdata+l2_vol_szVolLabel, vname, -1,
1190 STR_TERMINATE|STR_CONVERT);
1191 SCVAL(pdata,l2_vol_cch,len);
1192 data_len = l2_vol_szVolLabel + len;
1193 DEBUG(5,("call_trans2qfsinfo : time = %x, namelen = %d, name = %s\n",
1194 (unsigned)st.st_ctime, len, vname));
1197 case SMB_QUERY_FS_ATTRIBUTE_INFO:
1198 SIVAL(pdata,0,FILE_CASE_PRESERVED_NAMES|FILE_CASE_SENSITIVE_SEARCH|
1199 FILE_DEVICE_IS_MOUNTED|
1200 (lp_nt_acl_support() ? FILE_PERSISTENT_ACLS : 0)); /* FS ATTRIBUTES */
1201 SIVAL(pdata,4,255); /* Max filename component length */
1202 len = srvstr_push(outbuf, pdata+12, fstype, -1, STR_TERMINATE|STR_CONVERT);
1204 data_len = 12 + len;
1207 case SMB_QUERY_FS_LABEL_INFO:
1208 len = srvstr_push(outbuf, pdata+4, vname, -1, STR_TERMINATE|STR_CONVERT);
1212 case SMB_QUERY_FS_VOLUME_INFO:
1214 * Add volume serial number - hash of a combination of
1215 * the called hostname and the service name.
1217 SIVAL(pdata,8,str_checksum(lp_servicename(snum)) ^
1218 (str_checksum(local_machine)<<16));
1220 len = srvstr_push(outbuf, pdata+18, vname, -1, STR_TERMINATE|STR_CONVERT);
1221 SIVAL(pdata,12,len);
1223 DEBUG(5,("call_trans2qfsinfo : SMB_QUERY_FS_VOLUME_INFO namelen = %d, vol=%s serv=%s\n",
1224 (int)strlen(vname),vname, lp_servicename(snum)));
1226 case SMB_QUERY_FS_SIZE_INFO:
1228 SMB_BIG_UINT dfree,dsize,bsize;
1230 conn->vfs_ops.disk_free(conn,".",False,&bsize,&dfree,&dsize);
1231 SBIG_UINT(pdata,0,dsize);
1232 SBIG_UINT(pdata,8,dfree);
1233 SIVAL(pdata,16,bsize/512);
1234 SIVAL(pdata,20,512);
1237 case SMB_QUERY_FS_DEVICE_INFO:
1239 SIVAL(pdata,0,0); /* dev type */
1240 SIVAL(pdata,4,0); /* characteristics */
1242 case SMB_MAC_QUERY_FS_INFO:
1244 * Thursby MAC extension... ONLY on NTFS filesystems
1245 * once we do streams then we don't need this
1247 if (strequal(lp_fstype(SNUM(conn)),"NTFS")) {
1249 SIVAL(pdata,84,0x100); /* Don't support mac... */
1254 return(ERROR(ERRDOS,ERRunknownlevel));
1258 send_trans2_replies( outbuf, bufsize, params, 0, pdata, data_len);
1260 DEBUG( 4, ( "%s info_level = %d\n",
1261 smb_fn_name(CVAL(inbuf,smb_com)), info_level) );
1266 /****************************************************************************
1267 reply to a TRANS2_SETFSINFO (set filesystem info)
1268 ****************************************************************************/
1269 static int call_trans2setfsinfo(connection_struct *conn,
1270 char *inbuf, char *outbuf, int length,
1272 char **pparams, char **ppdata)
1274 /* Just say yes we did it - there is nothing that
1275 can be set here so it doesn't matter. */
1277 DEBUG(3,("call_trans2setfsinfo\n"));
1279 if (!CAN_WRITE(conn))
1280 return(ERROR(ERRSRV,ERRaccess));
1282 outsize = set_message(outbuf,10,0,True);
1287 /****************************************************************************
1288 Reply to a TRANS2_QFILEPATHINFO or TRANSACT2_QFILEINFO (query file info by
1289 file name or file id).
1290 ****************************************************************************/
1292 static int call_trans2qfilepathinfo(connection_struct *conn,
1293 char *inbuf, char *outbuf, int length,
1295 char **pparams,char **ppdata,
1298 int max_data_bytes = SVAL(inbuf, smb_mdrcnt);
1299 char *params = *pparams;
1300 char *pdata = *ppdata;
1301 uint16 tran_call = SVAL(inbuf, smb_setup0);
1305 unsigned int data_size;
1306 SMB_STRUCT_STAT sbuf;
1311 BOOL bad_path = False;
1312 BOOL delete_pending = False;
1315 if (tran_call == TRANSACT2_QFILEINFO) {
1316 files_struct *fsp = file_fsp(params,0);
1317 info_level = SVAL(params,2);
1319 DEBUG(3,("call_trans2qfilepathinfo: TRANSACT2_QFILEINFO: level = %d\n",
1322 if(fsp && (fsp->is_directory || fsp->stat_open)) {
1324 * This is actually a QFILEINFO on a directory
1325 * handle (returned from an NT SMB). NT5.0 seems
1326 * to do this call. JRA.
1328 pstrcpy(fname, fsp->fsp_name);
1329 unix_convert(fname,conn,0,&bad_path,&sbuf);
1330 if (!check_name(fname,conn) ||
1331 (!VALID_STAT(sbuf) && vfs_stat(conn,fname,&sbuf))) {
1332 DEBUG(3,("fileinfo of %s failed (%s)\n",fname,strerror(errno)));
1333 if((errno == ENOENT) && bad_path) {
1334 unix_ERR_class = ERRDOS;
1335 unix_ERR_code = ERRbadpath;
1337 return(UNIXERROR(ERRDOS,ERRbadpath));
1340 delete_pending = fsp->directory_delete_on_close;
1343 * Original code - this is an open file.
1345 CHECK_FSP(fsp,conn);
1348 pstrcpy(fname, fsp->fsp_name);
1349 if (vfs_fstat(fsp,fsp->fd,&sbuf) != 0) {
1350 DEBUG(3,("fstat of fnum %d failed (%s)\n",
1351 fsp->fnum, strerror(errno)));
1352 return(UNIXERROR(ERRDOS,ERRbadfid));
1354 if((pos = fsp->conn->vfs_ops.lseek(fsp,fsp->fd,0,SEEK_CUR)) == -1)
1355 return(UNIXERROR(ERRDOS,ERRnoaccess));
1357 delete_pending = fsp->delete_on_close;
1361 info_level = SVAL(params,0);
1363 DEBUG(3,("call_trans2qfilepathinfo: TRANSACT2_QPATHINFO: level = %d\n",
1366 srvstr_pull(inbuf, fname, ¶ms[6], sizeof(fname), -1, STR_TERMINATE);
1368 RESOLVE_DFSPATH(fname, conn, inbuf, outbuf);
1370 unix_convert(fname,conn,0,&bad_path,&sbuf);
1371 if (!check_name(fname,conn) ||
1372 (!VALID_STAT(sbuf) && vfs_stat(conn,fname,&sbuf))) {
1373 DEBUG(3,("fileinfo of %s failed (%s)\n",fname,strerror(errno)));
1374 if((errno == ENOENT) && bad_path) {
1375 unix_ERR_class = ERRDOS;
1376 unix_ERR_code = ERRbadpath;
1378 return(UNIXERROR(ERRDOS,ERRbadpath));
1383 DEBUG(3,("call_trans2qfilepathinfo %s level=%d call=%d total_data=%d\n",
1384 fname,info_level,tran_call,total_data));
1386 p = strrchr(fname,'/');
1393 mode = dos_mode(conn,fname,&sbuf);
1394 size = sbuf.st_size;
1395 if (mode & aDIR) size = 0;
1397 params = Realloc(*pparams,2);
1398 if (params == NULL) {
1399 return(ERROR(ERRDOS,ERRnomem));
1402 memset((char *)params,'\0',2);
1403 data_size = max_data_bytes + 1024;
1404 pdata = Realloc(*ppdata, data_size);
1405 if ( pdata == NULL ) {
1406 return(ERROR(ERRDOS,ERRnomem));
1410 if (total_data > 0 && IVAL(pdata,0) == total_data) {
1411 /* uggh, EAs for OS2 */
1412 DEBUG(4,("Rejecting EA request with total_data=%d\n",total_data));
1413 return(ERROR(ERRDOS,ERROR_EAS_NOT_SUPPORTED));
1416 memset((char *)pdata,'\0',data_size);
1420 case SMB_INFO_STANDARD:
1421 case SMB_INFO_QUERY_EA_SIZE:
1422 data_size = (info_level==1?22:26);
1423 put_dos_date2(pdata,l1_fdateCreation,get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(conn))));
1424 put_dos_date2(pdata,l1_fdateLastAccess,sbuf.st_atime);
1425 put_dos_date2(pdata,l1_fdateLastWrite,sbuf.st_mtime); /* write time */
1426 SIVAL(pdata,l1_cbFile,(uint32)size);
1427 SIVAL(pdata,l1_cbFileAlloc,SMB_ROUNDUP(size,1024));
1428 SSVAL(pdata,l1_attrFile,mode);
1429 SIVAL(pdata,l1_attrFile+2,4); /* this is what OS2 does */
1432 case SMB_INFO_QUERY_EAS_FROM_LIST:
1434 put_dos_date2(pdata,0,get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(conn))));
1435 put_dos_date2(pdata,4,sbuf.st_atime);
1436 put_dos_date2(pdata,8,sbuf.st_mtime);
1437 SIVAL(pdata,12,(uint32)size);
1438 SIVAL(pdata,16,SMB_ROUNDUP(size,1024));
1439 SIVAL(pdata,20,mode);
1442 case SMB_INFO_QUERY_ALL_EAS:
1444 SIVAL(pdata,0,data_size);
1448 return(ERROR(ERRDOS,ERRbadfunc)); /* os/2 needs this */
1450 case SMB_QUERY_FILE_BASIC_INFO:
1453 if (info_level == SMB_QUERY_FILE_BASIC_INFO)
1454 data_size = 36; /* w95 returns 40 bytes not 36 - why ?. */
1459 put_long_date(pdata,get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(conn))));
1460 put_long_date(pdata+8,sbuf.st_atime);
1461 put_long_date(pdata+16,sbuf.st_mtime); /* write time */
1462 put_long_date(pdata+24,sbuf.st_mtime); /* change time */
1463 SIVAL(pdata,32,mode);
1465 DEBUG(5,("SMB_QFBI - "));
1467 time_t create_time = get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(conn)));
1468 DEBUG(5,("create: %s ", ctime(&create_time)));
1470 DEBUG(5,("access: %s ", ctime(&sbuf.st_atime)));
1471 DEBUG(5,("write: %s ", ctime(&sbuf.st_mtime)));
1472 DEBUG(5,("change: %s ", ctime(&sbuf.st_mtime)));
1473 DEBUG(5,("mode: %x\n", mode));
1477 case SMB_QUERY_FILE_STANDARD_INFO:
1479 SOFF_T(pdata,0,size);
1480 SOFF_T(pdata,8,size);
1481 SIVAL(pdata,16,sbuf.st_nlink);
1483 CVAL(pdata,21) = (mode&aDIR)?1:0;
1486 case SMB_QUERY_FILE_EA_INFO:
1490 /* Get the 8.3 name - used if NT SMB was negotiated. */
1491 case SMB_QUERY_FILE_ALT_NAME_INFO:
1495 pstrcpy(short_name,base_name);
1496 /* Mangle if not already 8.3 */
1497 if(!is_8_3(short_name, True))
1499 if(!name_map_mangle(short_name,True,True,SNUM(conn)))
1502 len = srvstr_push(outbuf, pdata+4, short_name, -1,
1503 STR_TERMINATE|STR_CONVERT|STR_UPPER);
1504 data_size = 4 + len;
1509 case SMB_QUERY_FILE_NAME_INFO:
1511 * The first part of this code is essential
1512 * to get security descriptors to work on mapped
1513 * drives. Don't ask how I discovered this unless
1514 * you like hearing about me suffering.... :-). JRA.
1516 if(strequal(".", fname)) {
1517 len = srvstr_push(outbuf, pdata+4, "\\", -1, STR_TERMINATE|STR_CONVERT);
1519 len = srvstr_push(outbuf, pdata+4, fname, -1, STR_TERMINATE|STR_CONVERT);
1521 data_size = 4 + len;
1525 case SMB_QUERY_FILE_ALLOCATION_INFO:
1526 case SMB_QUERY_FILE_END_OF_FILEINFO:
1528 SOFF_T(pdata,0,size);
1531 case SMB_QUERY_FILE_ALL_INFO:
1532 put_long_date(pdata,get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(conn))));
1533 put_long_date(pdata+8,sbuf.st_atime);
1534 put_long_date(pdata+16,sbuf.st_mtime); /* write time */
1535 put_long_date(pdata+24,sbuf.st_mtime); /* change time */
1536 SIVAL(pdata,32,mode);
1538 SOFF_T(pdata,0,size);
1539 SOFF_T(pdata,8,size);
1540 SIVAL(pdata,16,sbuf.st_nlink);
1541 CVAL(pdata,20) = delete_pending;
1542 CVAL(pdata,21) = (mode&aDIR)?1:0;
1544 SINO_T(pdata,0,(SMB_INO_T)sbuf.st_ino);
1545 pdata += 8; /* index number */
1546 pdata += 4; /* EA info */
1548 SIVAL(pdata,0,0xA9);
1550 SIVAL(pdata,0,0xd01BF);
1552 SOFF_T(pdata,0,pos); /* current offset */
1554 SIVAL(pdata,0,mode); /* is this the right sort of mode info? */
1556 pdata += 4; /* alignment */
1557 len = srvstr_push(outbuf, pdata+4, fname, -1, STR_TERMINATE|STR_CONVERT);
1560 data_size = PTR_DIFF(pdata,(*ppdata));
1564 * Windows 2000 completely undocumented new SMB info levels.
1565 * Thanks Microsoft.... sure you're working on making this
1566 * protocol a standard.... sure you are... :-).
1567 * Lying rat-bastards. JRA.
1571 SIVAL(pdata,0,mode);
1572 SIVAL(pdata,4,0); /* ??? */
1573 SOFF_T(pdata,8,size);
1574 SIVAL(pdata,16,1); /* ??? */
1575 SIVAL(pdata,20,0); /* ??? */
1580 SIVAL(pdata,0,0x907); /* ??? */
1581 SIVAL(pdata,4,0x690000); /* ??? */
1586 SIVAL(pdata,0,0); /* ??? */
1591 SIVAL(pdata,0,0x12019F); /* ??? */
1596 /* Pathname with leading '\'. */
1601 pstrcpy(new_fname, "\\");
1602 pstrcat(new_fname, fname);
1603 byte_len = dos_PutUniCode(pdata+4,new_fname,max_data_bytes,False);
1604 SIVAL(pdata,0,byte_len);
1605 data_size = 4 + byte_len;
1610 SIVAL(pdata,0,0); /* ??? */
1611 SIVAL(pdata,4,0); /* ??? */
1616 SIVAL(pdata,0,0); /* ??? */
1621 SIVAL(pdata,0,0); /* ??? */
1626 /* Not yet finished... JRA */
1632 put_long_date(pdata,get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(conn))));
1633 put_long_date(pdata+8,sbuf.st_atime);
1634 put_long_date(pdata+16,sbuf.st_mtime); /* write time */
1635 put_long_date(pdata+24,sbuf.st_mtime); /* change time */
1636 SIVAL(pdata,32,mode);
1637 SIVAL(pdata,36,0); /* ??? */
1638 SIVAL(pdata,40,0x20); /* ??? */
1639 SIVAL(pdata,44,0); /* ??? */
1640 SOFF_T(pdata,48,size);
1641 SIVAL(pdata,56,0x1); /* ??? */
1642 SIVAL(pdata,60,0); /* ??? */
1643 SIVAL(pdata,64,0); /* ??? */
1644 SIVAL(pdata,68,length); /* Following string length in bytes. */
1645 dos_PutUniCode(pdata+72,,False);
1651 /* Last component of pathname. */
1653 size_t byte_len = dos_PutUniCode(pdata+4,fname,max_data_bytes,False);
1654 SIVAL(pdata,0,byte_len);
1655 data_size = 4 + byte_len;
1661 size_t byte_len = dos_PutUniCode(pdata+24,"::$DATA", 0xE, False);
1662 SIVAL(pdata,0,0); /* ??? */
1663 SIVAL(pdata,4,byte_len); /* Byte length of unicode string ::$DATA */
1664 SOFF_T(pdata,8,size);
1665 SIVAL(pdata,16,0x20); /* ??? */
1666 SIVAL(pdata,20,0); /* ??? */
1667 data_size = 24 + byte_len;
1672 SOFF_T(pdata,0,size);
1673 SIVAL(pdata,8,0); /* ??? */
1674 SIVAL(pdata,12,0); /* ??? */
1679 put_long_date(pdata,get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(conn))));
1680 put_long_date(pdata+8,sbuf.st_atime);
1681 put_long_date(pdata+16,sbuf.st_mtime); /* write time */
1682 put_long_date(pdata+24,sbuf.st_mtime); /* change time */
1683 SIVAL(pdata,32,0x20); /* ??? */
1684 SIVAL(pdata,36,0); /* ??? */
1685 SOFF_T(pdata,40,size);
1686 SIVAL(pdata,48,mode);
1687 SIVAL(pdata,52,0); /* ??? */
1692 SIVAL(pdata,0,mode);
1698 * End new completely undocumented info levels... JRA.
1702 /* NT4 server just returns "invalid query" to this - if we try to answer
1703 it then NTws gets a BSOD! (tridge) */
1704 case SMB_QUERY_FILE_STREAM_INFO:
1706 SIVAL(pdata,4,size);
1707 SIVAL(pdata,12,size);
1708 len = srvstr_push(outbuf, pdata+24, fname, -1, STR_TERMINATE|STR_CONVERT);
1709 SIVAL(pdata,20,len);
1710 data_size = 24 + len;
1715 return(ERROR(ERRDOS,ERRunknownlevel));
1718 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, data_size);
1723 /****************************************************************************
1724 reply to a TRANS2_SETFILEINFO (set file info by fileid)
1725 ****************************************************************************/
1726 static int call_trans2setfilepathinfo(connection_struct *conn,
1727 char *inbuf, char *outbuf, int length,
1728 int bufsize, char **pparams,
1729 char **ppdata, int total_data)
1731 char *params = *pparams;
1732 char *pdata = *ppdata;
1733 uint16 tran_call = SVAL(inbuf, smb_setup0);
1738 SMB_STRUCT_STAT sbuf;
1741 BOOL bad_path = False;
1742 files_struct *fsp = NULL;
1744 if (tran_call == TRANSACT2_SETFILEINFO) {
1745 fsp = file_fsp(params,0);
1746 info_level = SVAL(params,2);
1748 if(fsp && (fsp->is_directory || fsp->stat_open)) {
1750 * This is actually a SETFILEINFO on a directory
1751 * handle (returned from an NT SMB). NT5.0 seems
1752 * to do this call. JRA.
1754 pstrcpy(fname, fsp->fsp_name);
1755 unix_convert(fname,conn,0,&bad_path,&sbuf);
1756 if (!check_name(fname,conn) || (!VALID_STAT(sbuf))) {
1757 DEBUG(3,("fileinfo of %s failed (%s)\n",fname,strerror(errno)));
1758 if((errno == ENOENT) && bad_path)
1760 unix_ERR_class = ERRDOS;
1761 unix_ERR_code = ERRbadpath;
1763 return(UNIXERROR(ERRDOS,ERRbadpath));
1765 } else if (fsp->print_file) {
1767 * Doing a DELETE_ON_CLOSE should cancel a print job.
1769 if ((info_level == SMB_SET_FILE_DISPOSITION_INFO) && CVAL(pdata,0)) {
1770 fsp->share_mode = FILE_DELETE_ON_CLOSE;
1772 DEBUG(3,("call_trans2setfilepathinfo: Cancelling print job (%s)\n",
1776 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
1781 * Original code - this is an open file.
1783 CHECK_FSP(fsp,conn);
1786 pstrcpy(fname, fsp->fsp_name);
1789 if (vfs_fstat(fsp,fd,&sbuf) != 0) {
1790 DEBUG(3,("fstat of fnum %d failed (%s)\n",fsp->fnum, strerror(errno)));
1791 return(UNIXERROR(ERRDOS,ERRbadfid));
1796 info_level = SVAL(params,0);
1797 srvstr_pull(inbuf, fname, ¶ms[6], sizeof(fname), -1, STR_TERMINATE);
1798 unix_convert(fname,conn,0,&bad_path,&sbuf);
1799 if(!check_name(fname, conn))
1801 if((errno == ENOENT) && bad_path)
1803 unix_ERR_class = ERRDOS;
1804 unix_ERR_code = ERRbadpath;
1806 return(UNIXERROR(ERRDOS,ERRbadpath));
1809 if(!VALID_STAT(sbuf)) {
1810 DEBUG(3,("stat of %s failed (%s)\n", fname, strerror(errno)));
1811 if((errno == ENOENT) && bad_path)
1813 unix_ERR_class = ERRDOS;
1814 unix_ERR_code = ERRbadpath;
1816 return(UNIXERROR(ERRDOS,ERRbadpath));
1820 if (!CAN_WRITE(conn))
1821 return(ERROR(ERRSRV,ERRaccess));
1823 DEBUG(3,("call_trans2setfilepathinfo(%d) %s info_level=%d totdata=%d\n",
1824 tran_call,fname,info_level,total_data));
1826 /* Realloc the parameter and data sizes */
1827 params = Realloc(*pparams,2);
1828 if(params == NULL) {
1829 return(ERROR(ERRDOS,ERRnomem));
1835 size = sbuf.st_size;
1836 tvs.modtime = sbuf.st_mtime;
1837 tvs.actime = sbuf.st_atime;
1838 mode = dos_mode(conn,fname,&sbuf);
1840 if (total_data > 4 && IVAL(pdata,0) == total_data) {
1841 /* uggh, EAs for OS2 */
1842 DEBUG(4,("Rejecting EA request with total_data=%d\n",total_data));
1843 return(ERROR(ERRDOS,ERROR_EAS_NOT_SUPPORTED));
1848 case SMB_INFO_STANDARD:
1849 case SMB_INFO_QUERY_EA_SIZE:
1852 tvs.actime = make_unix_date2(pdata+l1_fdateLastAccess);
1855 tvs.modtime = make_unix_date2(pdata+l1_fdateLastWrite);
1857 mode = SVAL(pdata,l1_attrFile);
1858 size = IVAL(pdata,l1_cbFile);
1862 /* XXXX um, i don't think this is right.
1863 it's also not in the cifs6.txt spec.
1865 case SMB_INFO_QUERY_EAS_FROM_LIST:
1866 tvs.actime = make_unix_date2(pdata+8);
1867 tvs.modtime = make_unix_date2(pdata+12);
1868 size = IVAL(pdata,16);
1869 mode = IVAL(pdata,24);
1872 /* XXXX nor this. not in cifs6.txt, either. */
1873 case SMB_INFO_QUERY_ALL_EAS:
1874 tvs.actime = make_unix_date2(pdata+8);
1875 tvs.modtime = make_unix_date2(pdata+12);
1876 size = IVAL(pdata,16);
1877 mode = IVAL(pdata,24);
1880 case SMB_SET_FILE_BASIC_INFO:
1883 /* Patch to do this correctly from Paul Eggert <eggert@twinsun.com>. */
1885 time_t changed_time;
1887 /* Ignore create time at offset pdata. */
1890 tvs.actime = interpret_long_date(pdata+8);
1892 write_time = interpret_long_date(pdata+16);
1893 changed_time = interpret_long_date(pdata+24);
1895 tvs.modtime = MIN(write_time, changed_time);
1897 /* Prefer a defined time to an undefined one. */
1898 if (tvs.modtime == (time_t)0 || tvs.modtime == (time_t)-1)
1899 tvs.modtime = (write_time == (time_t)0 || write_time == (time_t)-1
1904 mode = IVAL(pdata,32);
1909 * NT seems to use this call with a size of zero
1910 * to mean truncate the file. JRA.
1915 case SMB_SET_FILE_ALLOCATION_INFO:
1917 SMB_OFF_T newsize = IVAL(pdata,0);
1918 #ifdef LARGE_SMB_OFF_T
1919 newsize |= (((SMB_OFF_T)IVAL(pdata,4)) << 32);
1920 #else /* LARGE_SMB_OFF_T */
1921 if (IVAL(pdata,4) != 0) /* more than 32 bits? */
1922 return(ERROR(ERRDOS,ERRunknownlevel));
1923 #endif /* LARGE_SMB_OFF_T */
1924 DEBUG(10,("call_trans2setfilepathinfo: Set file allocation info for file %s to %.0f\n", fname, (double)newsize ));
1930 case SMB_SET_FILE_END_OF_FILE_INFO:
1932 size = IVAL(pdata,0);
1933 #ifdef LARGE_SMB_OFF_T
1934 size |= (((SMB_OFF_T)IVAL(pdata,4)) << 32);
1935 #else /* LARGE_SMB_OFF_T */
1936 if (IVAL(pdata,4) != 0) /* more than 32 bits? */
1937 return(ERROR(ERRDOS,ERRunknownlevel));
1938 #endif /* LARGE_SMB_OFF_T */
1939 DEBUG(10,("call_trans2setfilepathinfo: Set end of file info for file %s to %.0f\n", fname, (double)size ));
1943 case SMB_SET_FILE_DISPOSITION_INFO: /* Set delete on close for open file. */
1945 BOOL delete_on_close = (CVAL(pdata,0) ? True : False);
1947 if (tran_call != TRANSACT2_SETFILEINFO)
1948 return(ERROR(ERRDOS,ERRunknownlevel));
1951 return(UNIXERROR(ERRDOS,ERRbadfid));
1954 * Only allow delete on close for files/directories opened with delete intent.
1957 if (delete_on_close && !GET_DELETE_ACCESS_REQUESTED(fsp->share_mode)) {
1958 DEBUG(10,("call_trans2setfilepathinfo: file %s delete on close flag set but delete access denied.\n",
1960 return(ERROR(ERRDOS,ERRnoaccess));
1963 if(fsp->is_directory) {
1964 fsp->directory_delete_on_close = delete_on_close;
1965 DEBUG(10, ("call_trans2setfilepathinfo: %s delete on close flag for fnum = %d, directory %s\n",
1966 delete_on_close ? "Added" : "Removed", fsp->fnum, fsp->fsp_name ));
1967 } else if(fsp->stat_open) {
1969 DEBUG(10, ("call_trans2setfilepathinfo: %s delete on close flag for fnum = %d, stat open %s\n",
1970 delete_on_close ? "Added" : "Removed", fsp->fnum, fsp->fsp_name ));
1974 files_struct *iterate_fsp;
1977 * Modify the share mode entry for all files open
1978 * on this device and inode to tell other smbds we have
1979 * changed the delete on close flag. This will be noticed
1980 * in the close code, the last closer will delete the file
1984 DEBUG(10,("call_trans2setfilepathinfo: %s delete on close flag for fnum = %d, file %s\n",
1985 delete_on_close ? "Adding" : "Removing", fsp->fnum, fsp->fsp_name ));
1987 if (lock_share_entry_fsp(fsp) == False)
1988 return(ERROR(ERRDOS,ERRnoaccess));
1990 if (!modify_delete_flag(fsp->dev, fsp->inode, delete_on_close)) {
1991 DEBUG(0,("call_trans2setfilepathinfo: failed to change delete on close flag for file %s\n",
1993 unlock_share_entry_fsp(fsp);
1994 return(ERROR(ERRDOS,ERRnoaccess));
2001 unlock_share_entry_fsp(fsp);
2004 * Go through all files we have open on the same device and
2005 * inode (hanging off the same hash bucket) and set the DELETE_ON_CLOSE_FLAG.
2006 * Other smbd's that have this file open will look in the share_mode on close.
2007 * take care of this (rare) case in close_file(). See the comment there.
2008 * NB. JRA. We don't really need to do this anymore - all should be taken
2009 * care of in the share_mode changes in the tdb.
2012 for(iterate_fsp = file_find_di_first(fsp->dev, fsp->inode);
2013 iterate_fsp; iterate_fsp = file_find_di_next(iterate_fsp))
2014 fsp->delete_on_close = delete_on_close;
2017 * Set the delete on close flag in the fsp.
2019 fsp->delete_on_close = delete_on_close;
2021 DEBUG(10, ("call_trans2setfilepathinfo: %s delete on close flag for fnum = %d, file %s\n",
2022 delete_on_close ? "Added" : "Removed", fsp->fnum, fsp->fsp_name ));
2031 return(ERROR(ERRDOS,ERRunknownlevel));
2035 /* get some defaults (no modifications) if any info is zero or -1. */
2036 if (tvs.actime == (time_t)0 || tvs.actime == (time_t)-1)
2037 tvs.actime = sbuf.st_atime;
2039 if (tvs.modtime == (time_t)0 || tvs.modtime == (time_t)-1)
2040 tvs.modtime = sbuf.st_mtime;
2042 DEBUG(6,("actime: %s " , ctime(&tvs.actime)));
2043 DEBUG(6,("modtime: %s ", ctime(&tvs.modtime)));
2044 DEBUG(6,("size: %.0f ", (double)size));
2045 DEBUG(6,("mode: %x\n" , mode));
2047 if(!((info_level == SMB_SET_FILE_END_OF_FILE_INFO) ||
2048 (info_level == SMB_SET_FILE_ALLOCATION_INFO) ||
2049 (info_level == 1019) ||
2050 (info_level == 1020))) {
2052 * Only do this test if we are not explicitly
2053 * changing the size of a file.
2056 size = sbuf.st_size;
2059 /* Try and set the times, size and mode of this file -
2060 if they are different from the current values
2062 if (sbuf.st_mtime != tvs.modtime || sbuf.st_atime != tvs.actime) {
2065 * This was a setfileinfo on an open file.
2066 * NT does this a lot. It's actually pointless
2067 * setting the time here, as it will be overwritten
2068 * on the next write, so we save the request
2069 * away and will set it on file code. JRA.
2072 if (tvs.modtime != (time_t)0 && tvs.modtime != (time_t)-1) {
2073 DEBUG(10,("call_trans2setfilepathinfo: setting pending modtime to %s\n",
2074 ctime(&tvs.modtime) ));
2075 fsp->pending_modtime = tvs.modtime;
2080 DEBUG(10,("call_trans2setfilepathinfo: setting utimes to modified values.\n"));
2082 if(file_utime(conn, fname, &tvs)!=0)
2083 return(UNIXERROR(ERRDOS,ERRnoaccess));
2087 /* check the mode isn't different, before changing it */
2088 if ((mode != 0) && (mode != dos_mode(conn, fname, &sbuf))) {
2090 DEBUG(10,("call_trans2setfilepathinfo: file %s : setting dos mode %x\n",
2093 if(file_chmod(conn, fname, mode, NULL)) {
2094 DEBUG(2,("chmod of %s failed (%s)\n", fname, strerror(errno)));
2095 return(UNIXERROR(ERRDOS,ERRnoaccess));
2099 if(size != sbuf.st_size) {
2101 DEBUG(10,("call_trans2setfilepathinfo: file %s : setting new size to %.0f\n",
2102 fname, (double)size ));
2105 files_struct *new_fsp = NULL;
2106 int access_mode = 0;
2109 if(global_oplock_break) {
2110 /* Queue this file modify as we are the process of an oplock break. */
2112 DEBUG(2,("call_trans2setfilepathinfo: queueing message due to being "));
2113 DEBUGADD(2,( "in oplock break state.\n"));
2115 push_oplock_pending_smb_message(inbuf, length);
2119 new_fsp = open_file_shared(conn, fname, &sbuf,
2120 SET_OPEN_MODE(DOS_OPEN_RDWR),
2121 (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN),
2122 0, 0, &access_mode, &action);
2124 if (new_fsp == NULL)
2125 return(UNIXERROR(ERRDOS,ERRbadpath));
2126 vfs_set_filelen(new_fsp, size);
2127 close_file(new_fsp,True);
2129 vfs_set_filelen(fsp, size);
2135 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
2140 /****************************************************************************
2141 reply to a TRANS2_MKDIR (make directory with extended attributes).
2142 ****************************************************************************/
2143 static int call_trans2mkdir(connection_struct *conn,
2144 char *inbuf, char *outbuf, int length, int bufsize,
2145 char **pparams, char **ppdata)
2147 char *params = *pparams;
2150 SMB_STRUCT_STAT sbuf;
2151 BOOL bad_path = False;
2153 if (!CAN_WRITE(conn))
2154 return(ERROR(ERRSRV,ERRaccess));
2156 srvstr_pull(inbuf, directory, ¶ms[4], sizeof(directory), -1, STR_TERMINATE);
2158 DEBUG(3,("call_trans2mkdir : name = %s\n", directory));
2160 unix_convert(directory,conn,0,&bad_path,&sbuf);
2161 if (check_name(directory,conn))
2162 ret = vfs_mkdir(conn,directory,unix_mode(conn,aDIR,directory));
2166 DEBUG(5,("call_trans2mkdir error (%s)\n", strerror(errno)));
2167 if((errno == ENOENT) && bad_path)
2169 unix_ERR_class = ERRDOS;
2170 unix_ERR_code = ERRbadpath;
2172 return(UNIXERROR(ERRDOS,ERRnoaccess));
2175 /* Realloc the parameter and data sizes */
2176 params = Realloc(*pparams,2);
2177 if(params == NULL) {
2178 return(ERROR(ERRDOS,ERRnomem));
2184 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
2189 /****************************************************************************
2190 reply to a TRANS2_FINDNOTIFYFIRST (start monitoring a directory for changes)
2191 We don't actually do this - we just send a null response.
2192 ****************************************************************************/
2193 static int call_trans2findnotifyfirst(connection_struct *conn,
2194 char *inbuf, char *outbuf,
2195 int length, int bufsize,
2196 char **pparams, char **ppdata)
2198 static uint16 fnf_handle = 257;
2199 char *params = *pparams;
2200 uint16 info_level = SVAL(params,4);
2202 DEBUG(3,("call_trans2findnotifyfirst - info_level %d\n", info_level));
2210 return(ERROR(ERRDOS,ERRunknownlevel));
2213 /* Realloc the parameter and data sizes */
2214 params = Realloc(*pparams,6);
2215 if(params == NULL) {
2216 return(ERROR(ERRDOS,ERRnomem));
2220 SSVAL(params,0,fnf_handle);
2221 SSVAL(params,2,0); /* No changes */
2222 SSVAL(params,4,0); /* No EA errors */
2229 send_trans2_replies(outbuf, bufsize, params, 6, *ppdata, 0);
2234 /****************************************************************************
2235 reply to a TRANS2_FINDNOTIFYNEXT (continue monitoring a directory for
2236 changes). Currently this does nothing.
2237 ****************************************************************************/
2238 static int call_trans2findnotifynext(connection_struct *conn,
2239 char *inbuf, char *outbuf,
2240 int length, int bufsize,
2241 char **pparams, char **ppdata)
2243 char *params = *pparams;
2245 DEBUG(3,("call_trans2findnotifynext\n"));
2247 /* Realloc the parameter and data sizes */
2248 params = Realloc(*pparams,4);
2249 if(params == NULL) {
2250 return(ERROR(ERRDOS,ERRnomem));
2254 SSVAL(params,0,0); /* No changes */
2255 SSVAL(params,2,0); /* No EA errors */
2257 send_trans2_replies(outbuf, bufsize, params, 4, *ppdata, 0);
2262 /****************************************************************************
2263 reply to a TRANS2_GET_DFS_REFERRAL - Shirish Kalele <kalele@veritas.com>
2264 ****************************************************************************/
2265 static int call_trans2getdfsreferral(connection_struct *conn, char* inbuf,
2266 char* outbuf, int length, int bufsize,
2267 char** pparams, char** ppdata)
2269 char *params = *pparams;
2272 int max_referral_level = SVAL(params,0);
2275 DEBUG(10,("call_trans2getdfsreferral\n"));
2277 if(!lp_host_msdfs())
2278 return(ERROR(ERRDOS,ERRbadfunc));
2280 srvstr_pull(inbuf, pathname, ¶ms[2], sizeof(pathname), -1, STR_TERMINATE|STR_CONVERT);
2282 if((reply_size = setup_dfs_referral(pathname,max_referral_level,ppdata)) < 0)
2283 return(ERROR(ERRDOS,ERRbadfile));
2285 SSVAL(outbuf,smb_flg2,SVAL(outbuf,smb_flg2) | FLAGS2_DFS_PATHNAMES);
2286 send_trans2_replies(outbuf,bufsize,0,0,*ppdata,reply_size);
2291 #define LMCAT_SPL 0x53
2292 #define LMFUNC_GETJOBID 0x60
2294 /****************************************************************************
2295 reply to a TRANS2_IOCTL - used for OS/2 printing.
2296 ****************************************************************************/
2298 static int call_trans2ioctl(connection_struct *conn, char* inbuf,
2299 char* outbuf, int length, int bufsize,
2300 char** pparams, char** ppdata)
2302 char *pdata = *ppdata;
2303 files_struct *fsp = file_fsp(inbuf,smb_vwv15);
2305 if ((SVAL(inbuf,(smb_setup+4)) == LMCAT_SPL) &&
2306 (SVAL(inbuf,(smb_setup+6)) == LMFUNC_GETJOBID)) {
2307 pdata = Realloc(*ppdata, 32);
2309 return(ERROR(ERRDOS,ERRnomem));
2313 /* NOTE - THIS IS ASCII ONLY AT THE MOMENT - NOT SURE IF OS/2
2314 CAN ACCEPT THIS IN UNICODE. JRA. */
2316 SSVAL(pdata,0,fsp->print_jobid); /* Job number */
2317 srvstr_push( outbuf, pdata + 2, global_myname, 15, STR_CONVERT|STR_ASCII|STR_TERMINATE); /* Our NetBIOS name */
2318 srvstr_push( outbuf, pdata+18, lp_servicename(SNUM(conn)), 13, STR_CONVERT|STR_ASCII|STR_TERMINATE); /* Service name */
2319 send_trans2_replies(outbuf,bufsize,*pparams,0,*ppdata,32);
2322 DEBUG(2,("Unknown TRANS2_IOCTL\n"));
2323 return(ERROR(ERRSRV,ERRerror));
2327 /****************************************************************************
2328 reply to a SMBfindclose (stop trans2 directory search)
2329 ****************************************************************************/
2330 int reply_findclose(connection_struct *conn,
2331 char *inbuf,char *outbuf,int length,int bufsize)
2334 int dptr_num=SVALS(inbuf,smb_vwv0);
2335 START_PROFILE(SMBfindclose);
2337 DEBUG(3,("reply_findclose, dptr_num = %d\n", dptr_num));
2339 dptr_close(&dptr_num);
2341 outsize = set_message(outbuf,0,0,True);
2343 DEBUG(3,("SMBfindclose dptr_num = %d\n", dptr_num));
2345 END_PROFILE(SMBfindclose);
2349 /****************************************************************************
2350 reply to a SMBfindnclose (stop FINDNOTIFYFIRST directory search)
2351 ****************************************************************************/
2352 int reply_findnclose(connection_struct *conn,
2353 char *inbuf,char *outbuf,int length,int bufsize)
2357 START_PROFILE(SMBfindnclose);
2359 dptr_num = SVAL(inbuf,smb_vwv0);
2361 DEBUG(3,("reply_findnclose, dptr_num = %d\n", dptr_num));
2363 /* We never give out valid handles for a
2364 findnotifyfirst - so any dptr_num is ok here.
2367 outsize = set_message(outbuf,0,0,True);
2369 DEBUG(3,("SMB_findnclose dptr_num = %d\n", dptr_num));
2371 END_PROFILE(SMBfindnclose);
2376 /****************************************************************************
2377 reply to a SMBtranss2 - just ignore it!
2378 ****************************************************************************/
2379 int reply_transs2(connection_struct *conn,
2380 char *inbuf,char *outbuf,int length,int bufsize)
2382 START_PROFILE(SMBtranss2);
2383 DEBUG(4,("Ignoring transs2 of length %d\n",length));
2384 END_PROFILE(SMBtranss2);
2388 /****************************************************************************
2389 reply to a SMBtrans2
2390 ****************************************************************************/
2391 int reply_trans2(connection_struct *conn,
2392 char *inbuf,char *outbuf,int length,int bufsize)
2395 unsigned int total_params = SVAL(inbuf, smb_tpscnt);
2396 unsigned int total_data =SVAL(inbuf, smb_tdscnt);
2398 unsigned int max_param_reply = SVAL(inbuf, smb_mprcnt);
2399 unsigned int max_data_reply = SVAL(inbuf, smb_mdrcnt);
2400 unsigned int max_setup_fields = SVAL(inbuf, smb_msrcnt);
2401 BOOL close_tid = BITSETW(inbuf+smb_flags,0);
2402 BOOL no_final_response = BITSETW(inbuf+smb_flags,1);
2403 int32 timeout = IVALS(inbuf,smb_timeout);
2405 unsigned int suwcnt = SVAL(inbuf, smb_suwcnt);
2406 unsigned int tran_call = SVAL(inbuf, smb_setup0);
2407 char *params = NULL, *data = NULL;
2408 int num_params, num_params_sofar, num_data, num_data_sofar;
2409 START_PROFILE(SMBtrans2);
2411 if(global_oplock_break && (tran_call == TRANSACT2_OPEN)) {
2412 /* Queue this open message as we are the process of an
2415 DEBUG(2,("reply_trans2: queueing message trans2open due to being "));
2416 DEBUGADD(2,( "in oplock break state.\n"));
2418 push_oplock_pending_smb_message(inbuf, length);
2419 END_PROFILE(SMBtrans2);
2423 if (IS_IPC(conn) && (tran_call != TRANSACT2_OPEN)
2424 && (tran_call != TRANSACT2_GET_DFS_REFERRAL)) {
2425 END_PROFILE(SMBtrans2);
2426 return(ERROR(ERRSRV,ERRaccess));
2429 outsize = set_message(outbuf,0,0,True);
2431 /* All trans2 messages we handle have smb_sucnt == 1 - ensure this
2432 is so as a sanity check */
2435 * Need to have rc=0 for ioctl to get job id for OS/2.
2436 * Network printing will fail if function is not successful.
2437 * Similar function in reply.c will be used if protocol
2438 * is LANMAN1.0 instead of LM1.2X002.
2439 * Until DosPrintSetJobInfo with PRJINFO3 is supported,
2440 * outbuf doesn't have to be set(only job id is used).
2442 if ( (suwcnt == 4) && (tran_call == TRANSACT2_IOCTL) &&
2443 (SVAL(inbuf,(smb_setup+4)) == LMCAT_SPL) &&
2444 (SVAL(inbuf,(smb_setup+6)) == LMFUNC_GETJOBID)) {
2445 DEBUG(2,("Got Trans2 DevIOctl jobid\n"));
2447 DEBUG(2,("Invalid smb_sucnt in trans2 call(%d)\n",suwcnt));
2448 DEBUG(2,("Transaction is %d\n",tran_call));
2449 END_PROFILE(SMBtrans2);
2450 return(ERROR(ERRSRV,ERRerror));
2454 /* Allocate the space for the maximum needed parameters and data */
2455 if (total_params > 0)
2456 params = (char *)malloc(total_params);
2458 data = (char *)malloc(total_data);
2460 if ((total_params && !params) || (total_data && !data)) {
2461 DEBUG(2,("Out of memory in reply_trans2\n"));
2466 END_PROFILE(SMBtrans2);
2467 return(ERROR(ERRDOS,ERRnomem));
2470 /* Copy the param and data bytes sent with this request into
2471 the params buffer */
2472 num_params = num_params_sofar = SVAL(inbuf,smb_pscnt);
2473 num_data = num_data_sofar = SVAL(inbuf, smb_dscnt);
2475 if (num_params > total_params || num_data > total_data)
2476 exit_server("invalid params in reply_trans2");
2479 memcpy( params, smb_base(inbuf) + SVAL(inbuf, smb_psoff), num_params);
2481 memcpy( data, smb_base(inbuf) + SVAL(inbuf, smb_dsoff), num_data);
2483 if(num_data_sofar < total_data || num_params_sofar < total_params) {
2484 /* We need to send an interim response then receive the rest
2485 of the parameter/data bytes */
2486 outsize = set_message(outbuf,0,0,True);
2487 if (!send_smb(smbd_server_fd(),outbuf))
2488 exit_server("reply_trans2: send_smb failed.\n");
2490 while (num_data_sofar < total_data ||
2491 num_params_sofar < total_params) {
2494 ret = receive_next_smb(inbuf,bufsize,SMB_SECONDARY_WAIT);
2497 (CVAL(inbuf, smb_com) != SMBtranss2)) || !ret) {
2498 outsize = set_message(outbuf,0,0,True);
2500 DEBUG(0,("reply_trans2: Invalid secondary trans2 packet\n"));
2502 DEBUG(0,("reply_trans2: %s in getting secondary trans2 response.\n",
2503 (smb_read_error == READ_ERROR) ? "error" : "timeout" ));
2508 END_PROFILE(SMBtrans2);
2509 return(ERROR(ERRSRV,ERRerror));
2512 /* Revise total_params and total_data in case
2513 they have changed downwards */
2514 total_params = SVAL(inbuf, smb_tpscnt);
2515 total_data = SVAL(inbuf, smb_tdscnt);
2516 num_params_sofar += (num_params = SVAL(inbuf,smb_spscnt));
2517 num_data_sofar += ( num_data = SVAL(inbuf, smb_sdscnt));
2518 if (num_params_sofar > total_params || num_data_sofar > total_data)
2519 exit_server("data overflow in trans2");
2521 memcpy( ¶ms[ SVAL(inbuf, smb_spsdisp)],
2522 smb_base(inbuf) + SVAL(inbuf, smb_spsoff), num_params);
2523 memcpy( &data[SVAL(inbuf, smb_sdsdisp)],
2524 smb_base(inbuf)+ SVAL(inbuf, smb_sdsoff), num_data);
2528 if (Protocol >= PROTOCOL_NT1) {
2529 SSVAL(outbuf,smb_flg2,SVAL(outbuf,smb_flg2) | 0x40); /* IS_LONG_NAME */
2532 /* Now we must call the relevant TRANS2 function */
2534 case TRANSACT2_OPEN:
2535 START_PROFILE_NESTED(Trans2_open);
2536 outsize = call_trans2open(conn,
2537 inbuf, outbuf, bufsize,
2539 END_PROFILE_NESTED(Trans2_open);
2542 case TRANSACT2_FINDFIRST:
2543 START_PROFILE_NESTED(Trans2_findfirst);
2544 outsize = call_trans2findfirst(conn, inbuf, outbuf,
2545 bufsize, ¶ms, &data);
2546 END_PROFILE_NESTED(Trans2_findfirst);
2549 case TRANSACT2_FINDNEXT:
2550 START_PROFILE_NESTED(Trans2_findnext);
2551 outsize = call_trans2findnext(conn, inbuf, outbuf,
2554 END_PROFILE_NESTED(Trans2_findnext);
2557 case TRANSACT2_QFSINFO:
2558 START_PROFILE_NESTED(Trans2_qfsinfo);
2559 outsize = call_trans2qfsinfo(conn, inbuf, outbuf,
2560 length, bufsize, ¶ms,
2562 END_PROFILE_NESTED(Trans2_qfsinfo);
2565 case TRANSACT2_SETFSINFO:
2566 START_PROFILE_NESTED(Trans2_setfsinfo);
2567 outsize = call_trans2setfsinfo(conn, inbuf, outbuf,
2570 END_PROFILE_NESTED(Trans2_setfsinfo);
2573 case TRANSACT2_QPATHINFO:
2574 case TRANSACT2_QFILEINFO:
2575 START_PROFILE_NESTED(Trans2_qpathinfo);
2576 outsize = call_trans2qfilepathinfo(conn, inbuf, outbuf,
2578 ¶ms, &data, total_data);
2579 END_PROFILE_NESTED(Trans2_qpathinfo);
2581 case TRANSACT2_SETPATHINFO:
2582 case TRANSACT2_SETFILEINFO:
2583 START_PROFILE_NESTED(Trans2_setpathinfo);
2584 outsize = call_trans2setfilepathinfo(conn, inbuf, outbuf,
2588 END_PROFILE_NESTED(Trans2_setpathinfo);
2591 case TRANSACT2_FINDNOTIFYFIRST:
2592 START_PROFILE_NESTED(Trans2_findnotifyfirst);
2593 outsize = call_trans2findnotifyfirst(conn, inbuf, outbuf,
2596 END_PROFILE_NESTED(Trans2_findnotifyfirst);
2599 case TRANSACT2_FINDNOTIFYNEXT:
2600 START_PROFILE_NESTED(Trans2_findnotifynext);
2601 outsize = call_trans2findnotifynext(conn, inbuf, outbuf,
2604 END_PROFILE_NESTED(Trans2_findnotifynext);
2606 case TRANSACT2_MKDIR:
2607 START_PROFILE_NESTED(Trans2_mkdir);
2608 outsize = call_trans2mkdir(conn, inbuf, outbuf, length,
2609 bufsize, ¶ms, &data);
2610 END_PROFILE_NESTED(Trans2_mkdir);
2613 case TRANSACT2_GET_DFS_REFERRAL:
2614 START_PROFILE_NESTED(Trans2_get_dfs_referral);
2615 outsize = call_trans2getdfsreferral(conn,inbuf,outbuf,length,
2616 bufsize, ¶ms, &data);
2617 END_PROFILE_NESTED(Trans2_get_dfs_referral);
2619 case TRANSACT2_IOCTL:
2620 START_PROFILE_NESTED(Trans2_ioctl);
2621 outsize = call_trans2ioctl(conn,inbuf,outbuf,length,
2622 bufsize,¶ms,&data);
2623 END_PROFILE_NESTED(Trans2_ioctl);
2626 /* Error in request */
2627 DEBUG(2,("Unknown request %d in trans2 call\n", tran_call));
2632 END_PROFILE(SMBtrans2);
2633 return (ERROR(ERRSRV,ERRerror));
2636 /* As we do not know how many data packets will need to be
2637 returned here the various call_trans2xxxx calls
2638 must send their own. Thus a call_trans2xxx routine only
2639 returns a value other than -1 when it wants to send
2647 END_PROFILE(SMBtrans2);
2648 return outsize; /* If a correct response was needed the
2649 call_trans2xxx calls have already sent
2650 it. If outsize != -1 then it is returning */