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.
27 extern BOOL case_sensitive;
28 extern int smb_read_error;
29 extern fstring local_machine;
30 extern int global_oplock_break;
31 extern uint32 global_client_caps;
32 extern pstring global_myname;
34 /****************************************************************************
35 Send the required number of replies back.
36 We assume all fields other than the data fields are
37 set correctly for the type of call.
38 HACK ! Always assumes smb_setup field is zero.
39 ****************************************************************************/
40 static int send_trans2_replies(char *outbuf, int bufsize, char *params,
41 int paramsize, char *pdata, int datasize)
43 /* As we are using a protocol > LANMAN1 then the max_send
44 variable must have been set in the sessetupX call.
45 This takes precedence over the max_xmit field in the
46 global struct. These different max_xmit variables should
47 be merged as this is now too confusing */
50 int data_to_send = datasize;
51 int params_to_send = paramsize;
55 int params_sent_thistime, data_sent_thistime, total_sent_thistime;
56 int alignment_offset = 1; /* JRA. This used to be 3. Set to 1 to make netmon parse ok. */
57 int data_alignment_offset = 0;
59 /* Initially set the wcnt area to be 10 - this is true for all
61 set_message(outbuf,10,0,True);
63 /* If there genuinely are no parameters or data to send just send
65 if(params_to_send == 0 && data_to_send == 0)
67 if (!send_smb(smbd_server_fd(),outbuf))
68 exit_server("send_trans2_replies: send_smb failed.");
72 /* When sending params and data ensure that both are nicely aligned */
73 /* Only do this alignment when there is also data to send - else
74 can cause NT redirector problems. */
75 if (((params_to_send % 4) != 0) && (data_to_send != 0))
76 data_alignment_offset = 4 - (params_to_send % 4);
78 /* Space is bufsize minus Netbios over TCP header minus SMB header */
79 /* The alignment_offset is to align the param bytes on an even byte
80 boundary. NT 4.0 Beta needs this to work correctly. */
81 useable_space = bufsize - ((smb_buf(outbuf)+
82 alignment_offset+data_alignment_offset) -
85 /* useable_space can never be more than max_send minus the
87 useable_space = MIN(useable_space,
88 max_send - (alignment_offset+data_alignment_offset));
91 while (params_to_send || data_to_send)
93 /* Calculate whether we will totally or partially fill this packet */
94 total_sent_thistime = params_to_send + data_to_send +
95 alignment_offset + data_alignment_offset;
96 /* We can never send more than useable_space */
98 * Note that 'useable_space' does not include the alignment offsets,
99 * but we must include the alignment offsets in the calculation of
100 * the length of the data we send over the wire, as the alignment offsets
101 * are sent here. Fix from Marc_Jacobsen@hp.com.
103 total_sent_thistime = MIN(total_sent_thistime, useable_space+
104 alignment_offset + data_alignment_offset);
106 set_message(outbuf, 10, total_sent_thistime, True);
108 /* Set total params and data to be sent */
109 SSVAL(outbuf,smb_tprcnt,paramsize);
110 SSVAL(outbuf,smb_tdrcnt,datasize);
112 /* Calculate how many parameters and data we can fit into
113 this packet. Parameters get precedence */
115 params_sent_thistime = MIN(params_to_send,useable_space);
116 data_sent_thistime = useable_space - params_sent_thistime;
117 data_sent_thistime = MIN(data_sent_thistime,data_to_send);
119 SSVAL(outbuf,smb_prcnt, params_sent_thistime);
121 /* smb_proff is the offset from the start of the SMB header to the
122 parameter bytes, however the first 4 bytes of outbuf are
123 the Netbios over TCP header. Thus use smb_base() to subtract
124 them from the calculation */
126 SSVAL(outbuf,smb_proff,((smb_buf(outbuf)+alignment_offset) - smb_base(outbuf)));
128 if(params_sent_thistime == 0)
129 SSVAL(outbuf,smb_prdisp,0);
131 /* Absolute displacement of param bytes sent in this packet */
132 SSVAL(outbuf,smb_prdisp,pp - params);
134 SSVAL(outbuf,smb_drcnt, data_sent_thistime);
135 if(data_sent_thistime == 0)
137 SSVAL(outbuf,smb_droff,0);
138 SSVAL(outbuf,smb_drdisp, 0);
142 /* The offset of the data bytes is the offset of the
143 parameter bytes plus the number of parameters being sent this time */
144 SSVAL(outbuf,smb_droff,((smb_buf(outbuf)+alignment_offset) -
145 smb_base(outbuf)) + params_sent_thistime + data_alignment_offset);
146 SSVAL(outbuf,smb_drdisp, pd - pdata);
149 /* Copy the param bytes into the packet */
150 if(params_sent_thistime)
151 memcpy((smb_buf(outbuf)+alignment_offset),pp,params_sent_thistime);
152 /* Copy in the data bytes */
153 if(data_sent_thistime)
154 memcpy(smb_buf(outbuf)+alignment_offset+params_sent_thistime+
155 data_alignment_offset,pd,data_sent_thistime);
157 DEBUG(9,("t2_rep: params_sent_thistime = %d, data_sent_thistime = %d, useable_space = %d\n",
158 params_sent_thistime, data_sent_thistime, useable_space));
159 DEBUG(9,("t2_rep: params_to_send = %d, data_to_send = %d, paramsize = %d, datasize = %d\n",
160 params_to_send, data_to_send, paramsize, datasize));
162 /* Send the packet */
163 if (!send_smb(smbd_server_fd(),outbuf))
164 exit_server("send_trans2_replies: send_smb failed.");
166 pp += params_sent_thistime;
167 pd += data_sent_thistime;
169 params_to_send -= params_sent_thistime;
170 data_to_send -= data_sent_thistime;
173 if(params_to_send < 0 || data_to_send < 0)
175 DEBUG(0,("send_trans2_replies failed sanity check pts = %d, dts = %d\n!!!",
176 params_to_send, data_to_send));
185 /****************************************************************************
186 reply to a TRANSACT2_OPEN
187 ****************************************************************************/
188 static int call_trans2open(connection_struct *conn, char *inbuf, char *outbuf,
190 char **pparams, char **ppdata)
192 char *params = *pparams;
193 int16 open_mode = SVAL(params, 2);
194 int16 open_attr = SVAL(params,6);
195 BOOL oplock_request = (((SVAL(params,0)|(1<<1))>>1) | ((SVAL(params,0)|(1<<2))>>1));
197 BOOL return_additional_info = BITSETW(params,0);
198 int16 open_sattr = SVAL(params, 4);
199 time_t open_time = make_unix_date3(params+8);
201 int16 open_ofun = SVAL(params,12);
202 int32 open_size = IVAL(params,14);
203 char *pname = ¶ms[28];
207 int fmode=0,mtime=0,rmode;
209 SMB_STRUCT_STAT sbuf;
211 BOOL bad_path = False;
214 srvstr_pull(inbuf, fname, pname, sizeof(fname), -1, STR_TERMINATE);
216 DEBUG(3,("trans2open %s mode=%d attr=%d ofun=%d size=%d\n",
217 fname,open_mode, open_attr, open_ofun, open_size));
220 return(ERROR_DOS(ERRSRV,ERRaccess));
223 /* XXXX we need to handle passed times, sattr and flags */
225 unix_convert(fname,conn,0,&bad_path,&sbuf);
227 if (!check_name(fname,conn))
229 if((errno == ENOENT) && bad_path)
231 unix_ERR_class = ERRDOS;
232 unix_ERR_code = ERRbadpath;
234 return(UNIXERROR(ERRDOS,ERRnoaccess));
237 unixmode = unix_mode(conn,open_attr | aARCH, fname);
239 fsp = open_file_shared(conn,fname,&sbuf,open_mode,open_ofun,unixmode,
240 oplock_request, &rmode,&smb_action);
244 if((errno == ENOENT) && bad_path)
246 unix_ERR_class = ERRDOS;
247 unix_ERR_code = ERRbadpath;
249 return(UNIXERROR(ERRDOS,ERRnoaccess));
253 fmode = dos_mode(conn,fname,&sbuf);
254 mtime = sbuf.st_mtime;
257 close_file(fsp,False);
258 return(ERROR_DOS(ERRDOS,ERRnoaccess));
261 /* Realloc the size of parameters and data we will return */
262 params = Realloc(*pparams, 28);
263 if( params == NULL ) {
264 return(ERROR_DOS(ERRDOS,ERRnomem));
268 memset((char *)params,'\0',28);
269 SSVAL(params,0,fsp->fnum);
270 SSVAL(params,2,fmode);
271 put_dos_date2(params,4, mtime);
272 SIVAL(params,8, (uint32)size);
273 SSVAL(params,12,rmode);
275 if (oplock_request && lp_fake_oplocks(SNUM(conn))) {
276 smb_action |= EXTENDED_OPLOCK_GRANTED;
279 SSVAL(params,18,smb_action);
281 * WARNING - this may need to be changed if SMB_INO_T <> 4 bytes.
283 SIVAL(params,20,inode);
285 /* Send the required number of replies */
286 send_trans2_replies(outbuf, bufsize, params, 28, *ppdata, 0);
291 /*********************************************************
292 * Routine to check if a given string matches exactly.
293 * as a special case a mask of "." does NOT match. That
294 * is required for correct wildcard semantics
295 * Case can be significant or not.
296 **********************************************************/
297 static BOOL exact_match(char *str,char *mask, BOOL case_sig)
299 if (mask[0] == '.' && mask[1] == 0) return False;
300 if (case_sig) return strcmp(str,mask)==0;
301 return strcasecmp(str,mask) == 0;
304 /****************************************************************************
305 get a level dependent lanman2 dir entry.
306 ****************************************************************************/
307 static BOOL get_lanman2_dir_entry(connection_struct *conn,
308 void *inbuf, void *outbuf,
309 char *path_mask,int dirtype,int info_level,
310 int requires_resume_key,
311 BOOL dont_descend,char **ppdata,
312 char *base_data, int space_remaining,
313 BOOL *out_of_space, BOOL *got_exact_match,
318 SMB_STRUCT_STAT sbuf;
322 char *p, *q, *pdata = *ppdata;
328 time_t mdate=0, adate=0, cdate=0;
331 int nt_extmode; /* Used for NT connections instead of mode */
332 BOOL needslash = ( conn->dirpath[strlen(conn->dirpath) -1] != '/');
335 *out_of_space = False;
336 *got_exact_match = False;
341 p = strrchr_m(path_mask,'/');
350 pstrcpy(mask, path_mask);
356 /* Needed if we run out of space */
357 prev_dirpos = TellDir(conn->dirptr);
358 dname = ReadDirName(conn->dirptr);
361 * Due to bugs in NT client redirectors we are not using
362 * resume keys any more - set them to zero.
363 * Check out the related comments in findfirst/findnext.
369 DEBUG(8,("get_lanman2_dir_entry:readdir on dirptr 0x%lx now at offset %d\n",
370 (long)conn->dirptr,TellDir(conn->dirptr)));
375 pstrcpy(fname,dname);
377 if(!(got_match = *got_exact_match = exact_match(fname, mask, case_sensitive))) {
378 got_match = mask_match(fname, mask, case_sensitive);
381 if(!got_match && !is_8_3(fname, False)) {
384 * It turns out that NT matches wildcards against
385 * both long *and* short names. This may explain some
386 * of the wildcard wierdness from old DOS clients
387 * that some people have been seeing.... JRA.
391 pstrcpy( newname, fname);
392 name_map_mangle( newname, True, False, SNUM(conn));
393 if(!(got_match = *got_exact_match = exact_match(newname, mask, case_sensitive)))
394 got_match = mask_match(newname, mask, case_sensitive);
399 BOOL isdots = (strequal(fname,"..") || strequal(fname,"."));
400 if (dont_descend && !isdots)
403 pstrcpy(pathreal,conn->dirpath);
405 pstrcat(pathreal,"/");
406 pstrcat(pathreal,dname);
407 if (vfs_stat(conn,pathreal,&sbuf) != 0)
409 /* Needed to show the msdfs symlinks as directories */
410 if(!lp_host_msdfs() || !lp_msdfs_root(SNUM(conn))
411 || !is_msdfs_link(conn, pathreal))
413 DEBUG(5,("get_lanman2_dir_entry:Couldn't stat [%s] (%s)\n",
414 pathreal,strerror(errno)));
419 DEBUG(5,("get_lanman2_dir_entry: Masquerading msdfs link %s as a directory\n", pathreal));
420 sbuf.st_mode = (sbuf.st_mode & 0xFFF) | S_IFDIR;
424 mode = dos_mode(conn,pathreal,&sbuf);
426 if (!dir_check_ftype(conn,mode,&sbuf,dirtype)) {
427 DEBUG(5,("[%s] attribs didn't match %x\n",fname,dirtype));
432 mdate = sbuf.st_mtime;
433 adate = sbuf.st_atime;
434 cdate = get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(conn)));
436 if (lp_dos_filetime_resolution(SNUM(conn))) {
445 DEBUG(5,("get_lanman2_dir_entry found %s fname=%s\n",pathreal,fname));
451 name_map_mangle(fname,False,True,SNUM(conn));
456 nt_extmode = mode ? mode : FILE_ATTRIBUTE_NORMAL;
461 if(requires_resume_key) {
465 put_dos_date2(p,l1_fdateCreation,cdate);
466 put_dos_date2(p,l1_fdateLastAccess,adate);
467 put_dos_date2(p,l1_fdateLastWrite,mdate);
468 SIVAL(p,l1_cbFile,(uint32)size);
469 SIVAL(p,l1_cbFileAlloc,SMB_ROUNDUP(size,1024));
470 SSVAL(p,l1_attrFile,mode);
473 p += align_string(outbuf, p, 0);
474 len = srvstr_push(outbuf, p, fname, -1, STR_TERMINATE);
475 SCVAL(nameptr, -1, len);
481 if(requires_resume_key) {
485 put_dos_date2(p,l2_fdateCreation,cdate);
486 put_dos_date2(p,l2_fdateLastAccess,adate);
487 put_dos_date2(p,l2_fdateLastWrite,mdate);
488 SIVAL(p,l2_cbFile,(uint32)size);
489 SIVAL(p,l2_cbFileAlloc,SMB_ROUNDUP(size,1024));
490 SSVAL(p,l2_attrFile,mode);
491 SIVAL(p,l2_cbList,0); /* No extended attributes */
494 len = srvstr_push(outbuf, p, fname, -1,
498 *p++ = 0; /* craig from unisys pointed out we need this */
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_DOS(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_DOS(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_DOS(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_DOS(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.
805 if(numentries == 0) {
806 dptr_close(&dptr_num);
807 return ERROR_DOS(ERRDOS,ERRbadfile);
810 /* At this point pdata points to numentries directory entries. */
812 /* Set up the return parameter block */
813 SSVAL(params,0,dptr_num);
814 SSVAL(params,2,numentries);
815 SSVAL(params,4,finished);
816 SSVAL(params,6,0); /* Never an EA error */
817 SSVAL(params,8,last_name_off);
819 send_trans2_replies( outbuf, bufsize, params, 10, pdata, PTR_DIFF(p,pdata));
821 if ((! *directory) && dptr_path(dptr_num))
822 slprintf(directory,sizeof(directory)-1, "(%s)",dptr_path(dptr_num));
824 DEBUG( 4, ( "%s mask=%s directory=%s dirtype=%d numentries=%d\n",
825 smb_fn_name(CVAL(inbuf,smb_com)),
826 mask, directory, dirtype, numentries ) );
829 * Force a name mangle here to ensure that the
830 * mask as an 8.3 name is top of the mangled cache.
831 * The reasons for this are subtle. Don't remove
832 * this code unless you know what you are doing
833 * (see PR#13758). JRA.
836 if(!is_8_3( mask, False))
837 name_map_mangle(mask, True, True, SNUM(conn));
843 /****************************************************************************
844 reply to a TRANS2_FINDNEXT
845 ****************************************************************************/
846 static int call_trans2findnext(connection_struct *conn,
847 char *inbuf, char *outbuf,
848 int length, int bufsize,
849 char **pparams, char **ppdata)
851 /* We must be careful here that we don't return more than the
852 allowed number of data bytes. If this means returning fewer than
853 maxentries then so be it. We assume that the redirector has
854 enough room for the fixed number of parameter bytes it has
856 int max_data_bytes = SVAL(inbuf, smb_mdrcnt);
857 char *params = *pparams;
858 char *pdata = *ppdata;
859 int dptr_num = SVAL(params,0);
860 int maxentries = SVAL(params,2);
861 uint16 info_level = SVAL(params,4);
862 uint32 resume_key = IVAL(params,6);
863 BOOL close_after_request = BITSETW(params+10,0);
864 BOOL close_if_end = BITSETW(params+10,1);
865 BOOL requires_resume_key = BITSETW(params+10,2);
866 BOOL continue_bit = BITSETW(params+10,3);
873 int i, last_name_off=0;
874 BOOL finished = False;
875 BOOL dont_descend = False;
876 BOOL out_of_space = False;
879 *mask = *directory = *resume_name = 0;
881 srvstr_pull(inbuf, resume_name, params+12, sizeof(resume_name), -1, STR_TERMINATE);
883 DEBUG(3,("call_trans2findnext: dirhandle = %d, max_data_bytes = %d, maxentries = %d, \
884 close_after_request=%d, close_if_end = %d requires_resume_key = %d \
885 resume_key = %d resume name = %s continue=%d level = %d\n",
886 dptr_num, max_data_bytes, maxentries, close_after_request, close_if_end,
887 requires_resume_key, resume_key, resume_name, continue_bit, info_level));
895 case SMB_FIND_FILE_DIRECTORY_INFO:
896 case SMB_FIND_FILE_FULL_DIRECTORY_INFO:
897 case SMB_FIND_FILE_NAMES_INFO:
898 case SMB_FIND_FILE_BOTH_DIRECTORY_INFO:
901 return ERROR_DOS(ERRDOS,ERRunknownlevel);
904 pdata = Realloc( *ppdata, max_data_bytes + 1024);
906 return ERROR_DOS(ERRDOS,ERRnomem);
909 memset((char *)pdata,'\0',max_data_bytes + 1024);
911 /* Realloc the params space */
912 params = Realloc(*pparams, 6*SIZEOFWORD);
913 if( params == NULL ) {
914 return ERROR_DOS(ERRDOS,ERRnomem);
918 /* Check that the dptr is valid */
919 if(!(conn->dirptr = dptr_fetch_lanman2(dptr_num)))
920 return ERROR_DOS(ERRDOS,ERRnofiles);
922 string_set(&conn->dirpath,dptr_path(dptr_num));
924 /* Get the wildcard mask from the dptr */
925 if((p = dptr_wcard(dptr_num))== NULL) {
926 DEBUG(2,("dptr_num %d has no wildcard\n", dptr_num));
927 return ERROR_DOS(ERRDOS,ERRnofiles);
930 pstrcpy(directory,conn->dirpath);
932 /* Get the attr mask from the dptr */
933 dirtype = dptr_attr(dptr_num);
935 DEBUG(3,("dptr_num is %d, mask = %s, attr = %x, dirptr=(0x%lX,%d)\n",
936 dptr_num, mask, dirtype,
938 TellDir(conn->dirptr)));
940 /* We don't need to check for VOL here as this is returned by
941 a different TRANS2 call. */
943 DEBUG(8,("dirpath=<%s> dontdescend=<%s>\n",conn->dirpath,lp_dontdescend(SNUM(conn))));
944 if (in_list(conn->dirpath,lp_dontdescend(SNUM(conn)),case_sensitive))
948 space_remaining = max_data_bytes;
949 out_of_space = False;
952 * Seek to the correct position. We no longer use the resume key but
953 * depend on the last file name instead.
955 if(requires_resume_key && *resume_name && !continue_bit)
958 * Fix for NT redirector problem triggered by resume key indexes
959 * changing between directory scans. We now return a resume key of 0
960 * and instead look for the filename to continue from (also given
961 * to us by NT/95/smbfs/smbclient). If no other scans have been done between the
962 * findfirst/findnext (as is usual) then the directory pointer
963 * should already be at the correct place. Check this by scanning
964 * backwards looking for an exact (ie. case sensitive) filename match.
965 * If we get to the beginning of the directory and haven't found it then scan
966 * forwards again looking for a match. JRA.
969 int current_pos, start_pos;
971 void *dirptr = conn->dirptr;
972 start_pos = TellDir(dirptr);
973 for(current_pos = start_pos; current_pos >= 0; current_pos--)
975 DEBUG(7,("call_trans2findnext: seeking to pos %d\n", current_pos));
977 SeekDir(dirptr, current_pos);
978 dname = ReadDirName(dirptr);
981 * Remember, name_map_mangle is called by
982 * get_lanman2_dir_entry(), so the resume name
983 * could be mangled. Ensure we do the same
988 name_map_mangle( dname, False, True, SNUM(conn));
990 if(dname && strcsequal( resume_name, dname))
992 SeekDir(dirptr, current_pos+1);
993 DEBUG(7,("call_trans2findnext: got match at pos %d\n", current_pos+1 ));
999 * Scan forward from start if not found going backwards.
1004 DEBUG(7,("call_trans2findnext: notfound: seeking to pos %d\n", start_pos));
1005 SeekDir(dirptr, start_pos);
1006 for(current_pos = start_pos; (dname = ReadDirName(dirptr)) != NULL; SeekDir(dirptr,++current_pos))
1009 * Remember, name_map_mangle is called by
1010 * get_lanman2_dir_entry(), so the resume name
1011 * could be mangled. Ensure we do the same
1016 name_map_mangle( dname, False, True, SNUM(conn));
1018 if(dname && strcsequal( resume_name, dname))
1020 SeekDir(dirptr, current_pos+1);
1021 DEBUG(7,("call_trans2findnext: got match at pos %d\n", current_pos+1 ));
1025 } /* end if current_pos */
1026 } /* end if requires_resume_key && !continue_bit */
1028 for (i=0;(i<(int)maxentries) && !finished && !out_of_space ;i++)
1030 BOOL got_exact_match = False;
1032 /* this is a heuristic to avoid seeking the dirptr except when
1033 absolutely necessary. It allows for a filename of about 40 chars */
1034 if (space_remaining < DIRLEN_GUESS && numentries > 0)
1036 out_of_space = True;
1041 finished = !get_lanman2_dir_entry(conn,
1043 mask,dirtype,info_level,
1044 requires_resume_key,dont_descend,
1045 &p,pdata,space_remaining, &out_of_space, &got_exact_match,
1049 if (finished && out_of_space)
1052 if (!finished && !out_of_space)
1056 * As an optimisation if we know we aren't looking
1057 * for a wildcard name (ie. the name matches the wildcard exactly)
1058 * then we can finish on any (first) match.
1059 * This speeds up large directory searches. JRA.
1065 space_remaining = max_data_bytes - PTR_DIFF(p,pdata);
1068 /* Check if we can close the dirptr */
1069 if(close_after_request || (finished && close_if_end))
1071 DEBUG(5,("call_trans2findnext: closing dptr_num = %d\n", dptr_num));
1072 dptr_close(&dptr_num); /* This frees up the saved mask */
1076 /* Set up the return parameter block */
1077 SSVAL(params,0,numentries);
1078 SSVAL(params,2,finished);
1079 SSVAL(params,4,0); /* Never an EA error */
1080 SSVAL(params,6,last_name_off);
1082 send_trans2_replies( outbuf, bufsize, params, 8, pdata, PTR_DIFF(p,pdata));
1084 if ((! *directory) && dptr_path(dptr_num))
1085 slprintf(directory,sizeof(directory)-1, "(%s)",dptr_path(dptr_num));
1087 DEBUG( 3, ( "%s mask=%s directory=%s dirtype=%d numentries=%d\n",
1088 smb_fn_name(CVAL(inbuf,smb_com)),
1089 mask, directory, dirtype, numentries ) );
1094 /****************************************************************************
1095 reply to a TRANS2_QFSINFO (query filesystem info)
1096 ****************************************************************************/
1098 static int call_trans2qfsinfo(connection_struct *conn,
1099 char *inbuf, char *outbuf,
1100 int length, int bufsize,
1101 char **pparams, char **ppdata)
1103 int max_data_bytes = SVAL(inbuf, smb_mdrcnt);
1104 char *pdata = *ppdata;
1105 char *params = *pparams;
1106 uint16 info_level = SVAL(params,0);
1109 char *vname = volume_label(SNUM(conn));
1110 int snum = SNUM(conn);
1111 char *fstype = lp_fstype(SNUM(conn));
1113 DEBUG(3,("call_trans2qfsinfo: level = %d\n", info_level));
1115 if(vfs_stat(conn,".",&st)!=0) {
1116 DEBUG(2,("call_trans2qfsinfo: stat of . failed (%s)\n", strerror(errno)));
1117 return ERROR_DOS(ERRSRV,ERRinvdevice);
1120 pdata = Realloc(*ppdata, max_data_bytes + 1024);
1121 if ( pdata == NULL ) {
1122 return ERROR_DOS(ERRDOS,ERRnomem);
1125 memset((char *)pdata,'\0',max_data_bytes + 1024);
1131 SMB_BIG_UINT dfree,dsize,bsize;
1133 conn->vfs_ops.disk_free(conn,".",False,&bsize,&dfree,&dsize);
1134 SIVAL(pdata,l1_idFileSystem,st.st_dev);
1135 SIVAL(pdata,l1_cSectorUnit,bsize/512);
1136 SIVAL(pdata,l1_cUnit,dsize);
1137 SIVAL(pdata,l1_cUnitAvail,dfree);
1138 SSVAL(pdata,l1_cbSector,512);
1139 DEBUG(5,("call_trans2qfsinfo : bsize=%u, id=%x, cSectorUnit=%u, cUnit=%u, cUnitAvail=%u, cbSector=%d\n",
1140 (unsigned int)bsize, (unsigned int)st.st_dev, ((unsigned int)bsize)/512, (unsigned int)dsize,
1141 (unsigned int)dfree, 512));
1145 /* Return volume name */
1147 * Add volume serial number - hash of a combination of
1148 * the called hostname and the service name.
1150 SIVAL(pdata,0,str_checksum(lp_servicename(snum)) ^ (str_checksum(local_machine)<<16) );
1151 len = srvstr_push(outbuf, pdata+l2_vol_szVolLabel, vname, -1,
1153 SCVAL(pdata,l2_vol_cch,len);
1154 data_len = l2_vol_szVolLabel + len;
1155 DEBUG(5,("call_trans2qfsinfo : time = %x, namelen = %d, name = %s\n",
1156 (unsigned)st.st_ctime, len, vname));
1159 case SMB_QUERY_FS_ATTRIBUTE_INFO:
1160 SIVAL(pdata,0,FILE_CASE_PRESERVED_NAMES|FILE_CASE_SENSITIVE_SEARCH|
1161 (lp_nt_acl_support(SNUM(conn)) ? FILE_PERSISTENT_ACLS : 0)); /* FS ATTRIBUTES */
1162 SIVAL(pdata,4,255); /* Max filename component length */
1163 len = srvstr_push(outbuf, pdata+12, fstype, -1, STR_TERMINATE);
1165 data_len = 12 + len;
1168 case SMB_QUERY_FS_LABEL_INFO:
1169 len = srvstr_push(outbuf, pdata+4, vname, -1, STR_TERMINATE);
1173 case SMB_QUERY_FS_VOLUME_INFO:
1175 * Add volume serial number - hash of a combination of
1176 * the called hostname and the service name.
1178 SIVAL(pdata,8,str_checksum(lp_servicename(snum)) ^
1179 (str_checksum(local_machine)<<16));
1181 len = srvstr_push(outbuf, pdata+18, vname, -1, STR_TERMINATE);
1182 SIVAL(pdata,12,len);
1184 DEBUG(5,("call_trans2qfsinfo : SMB_QUERY_FS_VOLUME_INFO namelen = %d, vol=%s serv=%s\n",
1185 (int)strlen(vname),vname, lp_servicename(snum)));
1187 case SMB_QUERY_FS_SIZE_INFO:
1189 SMB_BIG_UINT dfree,dsize,bsize;
1191 conn->vfs_ops.disk_free(conn,".",False,&bsize,&dfree,&dsize);
1192 SBIG_UINT(pdata,0,dsize);
1193 SBIG_UINT(pdata,8,dfree);
1194 SIVAL(pdata,16,bsize/512);
1195 SIVAL(pdata,20,512);
1198 case SMB_QUERY_FS_DEVICE_INFO:
1200 SIVAL(pdata,0,0); /* dev type */
1201 SIVAL(pdata,4,0); /* characteristics */
1203 case SMB_MAC_QUERY_FS_INFO:
1205 * Thursby MAC extension... ONLY on NTFS filesystems
1206 * once we do streams then we don't need this
1208 if (strequal(lp_fstype(SNUM(conn)),"NTFS")) {
1210 SIVAL(pdata,84,0x100); /* Don't support mac... */
1215 return ERROR_DOS(ERRDOS,ERRunknownlevel);
1219 send_trans2_replies( outbuf, bufsize, params, 0, pdata, data_len);
1221 DEBUG( 4, ( "%s info_level = %d\n",
1222 smb_fn_name(CVAL(inbuf,smb_com)), info_level) );
1227 /****************************************************************************
1228 reply to a TRANS2_SETFSINFO (set filesystem info)
1229 ****************************************************************************/
1230 static int call_trans2setfsinfo(connection_struct *conn,
1231 char *inbuf, char *outbuf, int length,
1233 char **pparams, char **ppdata)
1235 /* Just say yes we did it - there is nothing that
1236 can be set here so it doesn't matter. */
1238 DEBUG(3,("call_trans2setfsinfo\n"));
1240 if (!CAN_WRITE(conn))
1241 return ERROR_DOS(ERRSRV,ERRaccess);
1243 outsize = set_message(outbuf,10,0,True);
1248 /****************************************************************************
1249 Reply to a TRANS2_QFILEPATHINFO or TRANSACT2_QFILEINFO (query file info by
1250 file name or file id).
1251 ****************************************************************************/
1253 static int call_trans2qfilepathinfo(connection_struct *conn,
1254 char *inbuf, char *outbuf, int length,
1256 char **pparams,char **ppdata,
1259 int max_data_bytes = SVAL(inbuf, smb_mdrcnt);
1260 char *params = *pparams;
1261 char *pdata = *ppdata;
1262 uint16 tran_call = SVAL(inbuf, smb_setup0);
1266 unsigned int data_size;
1267 SMB_STRUCT_STAT sbuf;
1272 BOOL bad_path = False;
1273 BOOL delete_pending = False;
1277 if (tran_call == TRANSACT2_QFILEINFO) {
1278 files_struct *fsp = file_fsp(params,0);
1279 info_level = SVAL(params,2);
1281 DEBUG(3,("call_trans2qfilepathinfo: TRANSACT2_QFILEINFO: level = %d\n", info_level));
1283 if(fsp && (fsp->is_directory || fsp->stat_open)) {
1285 * This is actually a QFILEINFO on a directory
1286 * handle (returned from an NT SMB). NT5.0 seems
1287 * to do this call. JRA.
1289 pstrcpy(fname, fsp->fsp_name);
1290 unix_convert(fname,conn,0,&bad_path,&sbuf);
1291 if (!check_name(fname,conn) ||
1292 (!VALID_STAT(sbuf) && vfs_stat(conn,fname,&sbuf))) {
1293 DEBUG(3,("fileinfo of %s failed (%s)\n",fname,strerror(errno)));
1294 if((errno == ENOENT) && bad_path) {
1295 unix_ERR_class = ERRDOS;
1296 unix_ERR_code = ERRbadpath;
1298 return(UNIXERROR(ERRDOS,ERRbadpath));
1301 delete_pending = fsp->directory_delete_on_close;
1304 * Original code - this is an open file.
1306 CHECK_FSP(fsp,conn);
1308 pstrcpy(fname, fsp->fsp_name);
1309 if (vfs_fstat(fsp,fsp->fd,&sbuf) != 0) {
1310 DEBUG(3,("fstat of fnum %d failed (%s)\n",
1311 fsp->fnum, strerror(errno)));
1312 return(UNIXERROR(ERRDOS,ERRbadfid));
1314 if((pos = fsp->conn->vfs_ops.lseek(fsp,fsp->fd,0,SEEK_CUR)) == -1)
1315 return(UNIXERROR(ERRDOS,ERRnoaccess));
1317 delete_pending = fsp->delete_on_close;
1321 info_level = SVAL(params,0);
1323 DEBUG(3,("call_trans2qfilepathinfo: TRANSACT2_QPATHINFO: level = %d\n",
1326 srvstr_pull(inbuf, fname, ¶ms[6], sizeof(fname), -1, STR_TERMINATE);
1328 RESOLVE_DFSPATH(fname, conn, inbuf, outbuf);
1330 unix_convert(fname,conn,0,&bad_path,&sbuf);
1331 if (!check_name(fname,conn) ||
1332 (!VALID_STAT(sbuf) && vfs_stat(conn,fname,&sbuf))) {
1333 DEBUG(3,("fileinfo of %s failed (%s)\n",fname,strerror(errno)));
1334 if((errno == ENOENT) && bad_path) {
1335 unix_ERR_class = ERRDOS;
1336 unix_ERR_code = ERRbadpath;
1338 return(UNIXERROR(ERRDOS,ERRbadpath));
1343 DEBUG(3,("call_trans2qfilepathinfo %s level=%d call=%d total_data=%d\n",
1344 fname,info_level,tran_call,total_data));
1346 p = strrchr_m(fname,'/');
1353 mode = dos_mode(conn,fname,&sbuf);
1354 size = sbuf.st_size;
1355 if (mode & aDIR) size = 0;
1357 params = Realloc(*pparams,2);
1358 if (params == NULL) {
1359 return ERROR_DOS(ERRDOS,ERRnomem);
1362 memset((char *)params,'\0',2);
1363 data_size = max_data_bytes + 1024;
1364 pdata = Realloc(*ppdata, data_size);
1365 if ( pdata == NULL ) {
1366 return ERROR_DOS(ERRDOS,ERRnomem);
1370 if (total_data > 0 && IVAL(pdata,0) == total_data) {
1371 /* uggh, EAs for OS2 */
1372 DEBUG(4,("Rejecting EA request with total_data=%d\n",total_data));
1373 return ERROR_DOS(ERRDOS,ERReasnotsupported);
1376 memset((char *)pdata,'\0',data_size);
1378 c_time = get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(conn)));
1380 if (lp_dos_filetime_resolution(SNUM(conn))) {
1382 sbuf.st_atime &= ~1;
1383 sbuf.st_mtime &= ~1;
1384 sbuf.st_mtime &= ~1;
1389 case SMB_INFO_STANDARD:
1390 case SMB_INFO_QUERY_EA_SIZE:
1391 data_size = (info_level==1?22:26);
1392 put_dos_date2(pdata,l1_fdateCreation,c_time);
1393 put_dos_date2(pdata,l1_fdateLastAccess,sbuf.st_atime);
1394 put_dos_date2(pdata,l1_fdateLastWrite,sbuf.st_mtime); /* write time */
1395 SIVAL(pdata,l1_cbFile,(uint32)size);
1396 SIVAL(pdata,l1_cbFileAlloc,SMB_ROUNDUP(size,1024));
1397 SSVAL(pdata,l1_attrFile,mode);
1398 SIVAL(pdata,l1_attrFile+2,4); /* this is what OS2 does */
1401 case SMB_INFO_QUERY_EAS_FROM_LIST:
1403 put_dos_date2(pdata,0,c_time);
1404 put_dos_date2(pdata,4,sbuf.st_atime);
1405 put_dos_date2(pdata,8,sbuf.st_mtime);
1406 SIVAL(pdata,12,(uint32)size);
1407 SIVAL(pdata,16,SMB_ROUNDUP(size,1024));
1408 SIVAL(pdata,20,mode);
1411 case SMB_INFO_QUERY_ALL_EAS:
1413 SIVAL(pdata,0,data_size);
1417 return ERROR_DOS(ERRDOS,ERRbadfunc); /* os/2 needs this */
1419 case SMB_FILE_BASIC_INFORMATION:
1420 case SMB_QUERY_FILE_BASIC_INFO:
1422 if (info_level == SMB_QUERY_FILE_BASIC_INFO)
1423 data_size = 36; /* w95 returns 40 bytes not 36 - why ?. */
1428 put_long_date(pdata,c_time);
1429 put_long_date(pdata+8,sbuf.st_atime);
1430 put_long_date(pdata+16,sbuf.st_mtime); /* write time */
1431 put_long_date(pdata+24,sbuf.st_mtime); /* change time */
1432 SIVAL(pdata,32,mode);
1434 DEBUG(5,("SMB_QFBI - "));
1436 time_t create_time = c_time;
1437 DEBUG(5,("create: %s ", ctime(&create_time)));
1439 DEBUG(5,("access: %s ", ctime(&sbuf.st_atime)));
1440 DEBUG(5,("write: %s ", ctime(&sbuf.st_mtime)));
1441 DEBUG(5,("change: %s ", ctime(&sbuf.st_mtime)));
1442 DEBUG(5,("mode: %x\n", mode));
1446 case SMB_FILE_STANDARD_INFORMATION:
1447 case SMB_QUERY_FILE_STANDARD_INFO:
1449 /* Fake up allocation size. */
1450 SOFF_T(pdata,0,SMB_ROUNDUP(size + 1, ((SMB_OFF_T)0x100000)));
1451 SOFF_T(pdata,8,size);
1452 SIVAL(pdata,16,sbuf.st_nlink);
1454 CVAL(pdata,21) = (mode&aDIR)?1:0;
1457 case SMB_FILE_EA_INFORMATION:
1458 case SMB_QUERY_FILE_EA_INFO:
1462 /* Get the 8.3 name - used if NT SMB was negotiated. */
1463 case SMB_QUERY_FILE_ALT_NAME_INFO:
1467 pstrcpy(short_name,base_name);
1468 /* Mangle if not already 8.3 */
1469 if(!is_8_3(short_name, True))
1471 if(!name_map_mangle(short_name,True,True,SNUM(conn)))
1474 len = srvstr_push(outbuf, pdata+4, short_name, -1,
1475 STR_TERMINATE|STR_UPPER);
1476 data_size = 4 + len;
1481 case SMB_QUERY_FILE_NAME_INFO:
1483 * The first part of this code is essential
1484 * to get security descriptors to work on mapped
1485 * drives. Don't ask how I discovered this unless
1486 * you like hearing about me suffering.... :-). JRA.
1488 if(strequal(".", fname)) {
1489 len = srvstr_push(outbuf, pdata+4, "\\", -1, STR_TERMINATE);
1491 len = srvstr_push(outbuf, pdata+4, fname, -1, STR_TERMINATE);
1493 data_size = 4 + len;
1497 case SMB_FILE_ALLOCATION_INFORMATION:
1498 case SMB_FILE_END_OF_FILE_INFORMATION:
1499 case SMB_QUERY_FILE_ALLOCATION_INFO:
1500 case SMB_QUERY_FILE_END_OF_FILEINFO:
1502 SOFF_T(pdata,0,size);
1505 case SMB_QUERY_FILE_ALL_INFO:
1506 put_long_date(pdata,c_time);
1507 put_long_date(pdata+8,sbuf.st_atime);
1508 put_long_date(pdata+16,sbuf.st_mtime); /* write time */
1509 put_long_date(pdata+24,sbuf.st_mtime); /* change time */
1510 SIVAL(pdata,32,mode);
1512 SOFF_T(pdata,0,size);
1513 SOFF_T(pdata,8,size);
1514 SIVAL(pdata,16,sbuf.st_nlink);
1515 CVAL(pdata,20) = delete_pending;
1516 CVAL(pdata,21) = (mode&aDIR)?1:0;
1518 SINO_T(pdata,0,(SMB_INO_T)sbuf.st_ino);
1519 pdata += 8; /* index number */
1520 pdata += 4; /* EA info */
1522 SIVAL(pdata,0,0xA9);
1524 SIVAL(pdata,0,0xd01BF);
1526 SOFF_T(pdata,0,pos); /* current offset */
1528 SIVAL(pdata,0,mode); /* is this the right sort of mode info? */
1530 pdata += 4; /* alignment */
1531 len = srvstr_push(outbuf, pdata+4, fname, -1, STR_TERMINATE);
1534 data_size = PTR_DIFF(pdata,(*ppdata));
1537 case SMB_FILE_INTERNAL_INFORMATION:
1538 /* This should be an index number - looks like dev/ino to me :-) */
1539 SIVAL(pdata,0,sbuf.st_dev);
1540 SIVAL(pdata,4,sbuf.st_ino);
1544 case SMB_FILE_ACCESS_INFORMATION:
1545 SIVAL(pdata,0,0x12019F); /* ??? */
1549 case SMB_FILE_NAME_INFORMATION:
1550 /* Pathname with leading '\'. */
1555 pstrcpy(new_fname, "\\");
1556 pstrcat(new_fname, fname);
1557 byte_len = dos_PutUniCode(pdata+4,new_fname,max_data_bytes,False);
1558 SIVAL(pdata,0,byte_len);
1559 data_size = 4 + byte_len;
1563 case SMB_FILE_DISPOSITION_INFORMATION:
1565 CVAL(pdata,0) = delete_pending;
1568 case SMB_FILE_POSITION_INFORMATION:
1570 SOFF_T(pdata,0,pos);
1573 case SMB_FILE_MODE_INFORMATION:
1574 SIVAL(pdata,0,mode);
1578 case SMB_FILE_ALIGNMENT_INFORMATION:
1579 SIVAL(pdata,0,0); /* No alignment needed. */
1584 /* Not yet finished... JRA */
1590 put_long_date(pdata,c_time);
1591 put_long_date(pdata+8,sbuf.st_atime);
1592 put_long_date(pdata+16,sbuf.st_mtime); /* write time */
1593 put_long_date(pdata+24,sbuf.st_mtime); /* change time */
1594 SIVAL(pdata,32,mode);
1595 SIVAL(pdata,36,0); /* ??? */
1596 SIVAL(pdata,40,0x20); /* ??? */
1597 SIVAL(pdata,44,0); /* ??? */
1598 SOFF_T(pdata,48,size);
1599 SIVAL(pdata,56,0x1); /* ??? */
1600 SIVAL(pdata,60,0); /* ??? */
1601 SIVAL(pdata,64,0); /* ??? */
1602 SIVAL(pdata,68,length); /* Following string length in bytes. */
1603 dos_PutUniCode(pdata+72,,False);
1608 case SMB_FILE_ALTERNATE_NAME_INFORMATION:
1609 /* Last component of pathname. */
1611 size_t byte_len = dos_PutUniCode(pdata+4,fname,max_data_bytes,False);
1612 SIVAL(pdata,0,byte_len);
1613 data_size = 4 + byte_len;
1617 case SMB_FILE_STREAM_INFORMATION:
1621 size_t byte_len = dos_PutUniCode(pdata+24,"::$DATA", 0xE, False);
1622 SIVAL(pdata,0,0); /* ??? */
1623 SIVAL(pdata,4,byte_len); /* Byte length of unicode string ::$DATA */
1624 SOFF_T(pdata,8,size);
1625 SIVAL(pdata,16,0x20); /* ??? */
1626 SIVAL(pdata,20,0); /* ??? */
1627 data_size = 24 + byte_len;
1631 case SMB_FILE_COMPRESSION_INFORMATION:
1632 SOFF_T(pdata,0,size);
1633 SIVAL(pdata,8,0); /* ??? */
1634 SIVAL(pdata,12,0); /* ??? */
1638 case SMB_FILE_NETWORK_OPEN_INFORMATION:
1639 put_long_date(pdata,c_time);
1640 put_long_date(pdata+8,sbuf.st_atime);
1641 put_long_date(pdata+16,sbuf.st_mtime); /* write time */
1642 put_long_date(pdata+24,sbuf.st_mtime); /* change time */
1643 SIVAL(pdata,32,0x20); /* ??? */
1644 SIVAL(pdata,36,0); /* ??? */
1645 SOFF_T(pdata,40,size);
1646 SIVAL(pdata,48,mode);
1647 SIVAL(pdata,52,0); /* ??? */
1651 case SMB_FILE_ATTRIBUTE_TAG_INFORMATION:
1652 SIVAL(pdata,0,mode);
1658 * End new completely undocumented info levels... JRA.
1662 /* NT4 server just returns "invalid query" to this - if we try to answer
1663 it then NTws gets a BSOD! (tridge) */
1664 case SMB_QUERY_FILE_STREAM_INFO:
1666 SIVAL(pdata,4,size);
1667 SIVAL(pdata,12,size);
1668 len = srvstr_push(outbuf, pdata+24, fname, -1, STR_TERMINATE);
1669 SIVAL(pdata,20,len);
1670 data_size = 24 + len;
1675 return ERROR_DOS(ERRDOS,ERRunknownlevel);
1678 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, data_size);
1683 /****************************************************************************
1684 reply to a TRANS2_SETFILEINFO (set file info by fileid)
1685 ****************************************************************************/
1686 static int call_trans2setfilepathinfo(connection_struct *conn,
1687 char *inbuf, char *outbuf, int length,
1688 int bufsize, char **pparams,
1689 char **ppdata, int total_data)
1691 char *params = *pparams;
1692 char *pdata = *ppdata;
1693 uint16 tran_call = SVAL(inbuf, smb_setup0);
1698 SMB_STRUCT_STAT sbuf;
1701 BOOL bad_path = False;
1702 files_struct *fsp = NULL;
1704 if (tran_call == TRANSACT2_SETFILEINFO) {
1705 fsp = file_fsp(params,0);
1706 info_level = SVAL(params,2);
1708 if(fsp && (fsp->is_directory || fsp->stat_open)) {
1710 * This is actually a SETFILEINFO on a directory
1711 * handle (returned from an NT SMB). NT5.0 seems
1712 * to do this call. JRA.
1714 pstrcpy(fname, fsp->fsp_name);
1715 unix_convert(fname,conn,0,&bad_path,&sbuf);
1716 if (!check_name(fname,conn) || (!VALID_STAT(sbuf))) {
1717 DEBUG(3,("fileinfo of %s failed (%s)\n",fname,strerror(errno)));
1718 if((errno == ENOENT) && bad_path)
1720 unix_ERR_class = ERRDOS;
1721 unix_ERR_code = ERRbadpath;
1723 return(UNIXERROR(ERRDOS,ERRbadpath));
1725 } else if (fsp && fsp->print_file) {
1727 * Doing a DELETE_ON_CLOSE should cancel a print job.
1729 if ((info_level == SMB_SET_FILE_DISPOSITION_INFO) && CVAL(pdata,0)) {
1730 fsp->share_mode = FILE_DELETE_ON_CLOSE;
1732 DEBUG(3,("call_trans2setfilepathinfo: Cancelling print job (%s)\n",
1736 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
1741 * Original code - this is an open file.
1743 CHECK_FSP(fsp,conn);
1745 pstrcpy(fname, fsp->fsp_name);
1748 if (vfs_fstat(fsp,fd,&sbuf) != 0) {
1749 DEBUG(3,("fstat of fnum %d failed (%s)\n",fsp->fnum, strerror(errno)));
1750 return(UNIXERROR(ERRDOS,ERRbadfid));
1755 info_level = SVAL(params,0);
1756 srvstr_pull(inbuf, fname, ¶ms[6], sizeof(fname), -1, STR_TERMINATE);
1757 unix_convert(fname,conn,0,&bad_path,&sbuf);
1758 if(!check_name(fname, conn))
1760 if((errno == ENOENT) && bad_path)
1762 unix_ERR_class = ERRDOS;
1763 unix_ERR_code = ERRbadpath;
1765 return(UNIXERROR(ERRDOS,ERRbadpath));
1768 if(!VALID_STAT(sbuf)) {
1769 DEBUG(3,("stat of %s failed (%s)\n", fname, strerror(errno)));
1770 if((errno == ENOENT) && bad_path)
1772 unix_ERR_class = ERRDOS;
1773 unix_ERR_code = ERRbadpath;
1775 return(UNIXERROR(ERRDOS,ERRbadpath));
1779 if (!CAN_WRITE(conn))
1780 return ERROR_DOS(ERRSRV,ERRaccess);
1782 DEBUG(3,("call_trans2setfilepathinfo(%d) %s info_level=%d totdata=%d\n",
1783 tran_call,fname,info_level,total_data));
1785 /* Realloc the parameter and data sizes */
1786 params = Realloc(*pparams,2);
1787 if(params == NULL) {
1788 return ERROR_DOS(ERRDOS,ERRnomem);
1794 size = sbuf.st_size;
1795 tvs.modtime = sbuf.st_mtime;
1796 tvs.actime = sbuf.st_atime;
1797 mode = dos_mode(conn,fname,&sbuf);
1799 if (total_data > 4 && IVAL(pdata,0) == total_data) {
1800 /* uggh, EAs for OS2 */
1801 DEBUG(4,("Rejecting EA request with total_data=%d\n",total_data));
1802 return ERROR_DOS(ERRDOS,ERReasnotsupported);
1807 case SMB_INFO_STANDARD:
1808 case SMB_INFO_QUERY_EA_SIZE:
1811 tvs.actime = make_unix_date2(pdata+l1_fdateLastAccess);
1814 tvs.modtime = make_unix_date2(pdata+l1_fdateLastWrite);
1816 mode = SVAL(pdata,l1_attrFile);
1817 size = IVAL(pdata,l1_cbFile);
1821 /* XXXX um, i don't think this is right.
1822 it's also not in the cifs6.txt spec.
1824 case SMB_INFO_QUERY_EAS_FROM_LIST:
1825 tvs.actime = make_unix_date2(pdata+8);
1826 tvs.modtime = make_unix_date2(pdata+12);
1827 size = IVAL(pdata,16);
1828 mode = IVAL(pdata,24);
1831 /* XXXX nor this. not in cifs6.txt, either. */
1832 case SMB_INFO_QUERY_ALL_EAS:
1833 tvs.actime = make_unix_date2(pdata+8);
1834 tvs.modtime = make_unix_date2(pdata+12);
1835 size = IVAL(pdata,16);
1836 mode = IVAL(pdata,24);
1839 case SMB_SET_FILE_BASIC_INFO:
1840 case SMB_FILE_BASIC_INFORMATION:
1842 /* Patch to do this correctly from Paul Eggert <eggert@twinsun.com>. */
1844 time_t changed_time;
1846 /* Ignore create time at offset pdata. */
1849 tvs.actime = interpret_long_date(pdata+8);
1851 write_time = interpret_long_date(pdata+16);
1852 changed_time = interpret_long_date(pdata+24);
1854 tvs.modtime = MIN(write_time, changed_time);
1856 /* Prefer a defined time to an undefined one. */
1857 if (tvs.modtime == (time_t)0 || tvs.modtime == (time_t)-1)
1858 tvs.modtime = (write_time == (time_t)0 || write_time == (time_t)-1
1863 mode = IVAL(pdata,32);
1869 case SMB_SET_FILE_ALLOCATION_INFO:
1872 size = IVAL(pdata,0);
1873 #ifdef LARGE_SMB_OFF_T
1874 size |= (((SMB_OFF_T)IVAL(pdata,4)) << 32);
1875 #else /* LARGE_SMB_OFF_T */
1876 if (IVAL(pdata,4) != 0) /* more than 32 bits? */
1877 return ERROR_DOS(ERRDOS,ERRunknownlevel);
1878 #endif /* LARGE_SMB_OFF_T */
1879 DEBUG(10,("call_trans2setfilepathinfo: Set file allocation info for file %s to %.0f\n",
1880 fname, (double)size ));
1882 if(size != sbuf.st_size) {
1884 DEBUG(10,("call_trans2setfilepathinfo: file %s : setting new size to %.0f\n",
1885 fname, (double)size ));
1888 files_struct *new_fsp = NULL;
1889 int access_mode = 0;
1892 if(global_oplock_break) {
1893 /* Queue this file modify as we are the process of an oplock break. */
1895 DEBUG(2,("call_trans2setfilepathinfo: queueing message due to being "));
1896 DEBUGADD(2,( "in oplock break state.\n"));
1898 push_oplock_pending_smb_message(inbuf, length);
1902 new_fsp = open_file_shared(conn, fname, &sbuf,
1903 SET_OPEN_MODE(DOS_OPEN_RDWR),
1904 (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN),
1905 0, 0, &access_mode, &action);
1907 if (new_fsp == NULL)
1908 return(UNIXERROR(ERRDOS,ERRbadpath));
1909 ret = vfs_allocate_file_space(new_fsp, size);
1910 close_file(new_fsp,True);
1912 ret = vfs_allocate_file_space(fsp, size);
1914 if (ret == -1) return ERROR_NT(NT_STATUS_DISK_FULL);
1916 sbuf.st_size = size;
1922 case SMB_SET_FILE_END_OF_FILE_INFO:
1924 size = IVAL(pdata,0);
1925 #ifdef LARGE_SMB_OFF_T
1926 size |= (((SMB_OFF_T)IVAL(pdata,4)) << 32);
1927 #else /* LARGE_SMB_OFF_T */
1928 if (IVAL(pdata,4) != 0) /* more than 32 bits? */
1929 return ERROR_DOS(ERRDOS,ERRunknownlevel);
1930 #endif /* LARGE_SMB_OFF_T */
1931 DEBUG(10,("call_trans2setfilepathinfo: Set end of file info for file %s to %.0f\n", fname, (double)size ));
1935 case SMB_FILE_DISPOSITION_INFORMATION:
1936 case SMB_SET_FILE_DISPOSITION_INFO: /* Set delete on close for open file. */
1938 BOOL delete_on_close = (CVAL(pdata,0) ? True : False);
1940 if (tran_call != TRANSACT2_SETFILEINFO)
1941 return ERROR_DOS(ERRDOS,ERRunknownlevel);
1944 return(UNIXERROR(ERRDOS,ERRbadfid));
1947 * Only allow delete on close for files/directories opened with delete intent.
1950 if (delete_on_close && !GET_DELETE_ACCESS_REQUESTED(fsp->share_mode)) {
1951 DEBUG(10,("call_trans2setfilepathinfo: file %s delete on close flag set but delete access denied.\n",
1953 return ERROR_DOS(ERRDOS,ERRnoaccess);
1956 if(fsp->is_directory) {
1957 fsp->directory_delete_on_close = delete_on_close;
1958 DEBUG(10, ("call_trans2setfilepathinfo: %s delete on close flag for fnum = %d, directory %s\n",
1959 delete_on_close ? "Added" : "Removed", fsp->fnum, fsp->fsp_name ));
1960 } else if(fsp->stat_open) {
1962 DEBUG(10, ("call_trans2setfilepathinfo: %s delete on close flag for fnum = %d, stat open %s\n",
1963 delete_on_close ? "Added" : "Removed", fsp->fnum, fsp->fsp_name ));
1967 files_struct *iterate_fsp;
1970 * Modify the share mode entry for all files open
1971 * on this device and inode to tell other smbds we have
1972 * changed the delete on close flag. This will be noticed
1973 * in the close code, the last closer will delete the file
1977 DEBUG(10,("call_trans2setfilepathinfo: %s delete on close flag for fnum = %d, file %s\n",
1978 delete_on_close ? "Adding" : "Removing", fsp->fnum, fsp->fsp_name ));
1980 if (lock_share_entry_fsp(fsp) == False)
1981 return ERROR_DOS(ERRDOS,ERRnoaccess);
1983 if (!modify_delete_flag(fsp->dev, fsp->inode, delete_on_close)) {
1984 DEBUG(0,("call_trans2setfilepathinfo: failed to change delete on close flag for file %s\n",
1986 unlock_share_entry_fsp(fsp);
1987 return ERROR_DOS(ERRDOS,ERRnoaccess);
1994 unlock_share_entry_fsp(fsp);
1997 * Go through all files we have open on the same device and
1998 * inode (hanging off the same hash bucket) and set the DELETE_ON_CLOSE_FLAG.
1999 * Other smbd's that have this file open will look in the share_mode on close.
2000 * take care of this (rare) case in close_file(). See the comment there.
2001 * NB. JRA. We don't really need to do this anymore - all should be taken
2002 * care of in the share_mode changes in the tdb.
2005 for(iterate_fsp = file_find_di_first(fsp->dev, fsp->inode);
2006 iterate_fsp; iterate_fsp = file_find_di_next(iterate_fsp))
2007 fsp->delete_on_close = delete_on_close;
2010 * Set the delete on close flag in the fsp.
2012 fsp->delete_on_close = delete_on_close;
2014 DEBUG(10, ("call_trans2setfilepathinfo: %s delete on close flag for fnum = %d, file %s\n",
2015 delete_on_close ? "Added" : "Removed", fsp->fnum, fsp->fsp_name ));
2024 return ERROR_DOS(ERRDOS,ERRunknownlevel);
2028 /* get some defaults (no modifications) if any info is zero or -1. */
2029 if (tvs.actime == (time_t)0 || tvs.actime == (time_t)-1)
2030 tvs.actime = sbuf.st_atime;
2032 if (tvs.modtime == (time_t)0 || tvs.modtime == (time_t)-1)
2033 tvs.modtime = sbuf.st_mtime;
2035 DEBUG(6,("actime: %s " , ctime(&tvs.actime)));
2036 DEBUG(6,("modtime: %s ", ctime(&tvs.modtime)));
2037 DEBUG(6,("size: %.0f ", (double)size));
2038 DEBUG(6,("mode: %x\n" , mode));
2040 if(!((info_level == SMB_SET_FILE_END_OF_FILE_INFO) ||
2041 (info_level == SMB_SET_FILE_ALLOCATION_INFO) ||
2042 (info_level == SMB_FILE_ALLOCATION_INFORMATION) ||
2043 (info_level == SMB_FILE_END_OF_FILE_INFORMATION))) {
2045 * Only do this test if we are not explicitly
2046 * changing the size of a file.
2049 size = sbuf.st_size;
2052 /* Try and set the times, size and mode of this file -
2053 if they are different from the current values
2055 if (sbuf.st_mtime != tvs.modtime || sbuf.st_atime != tvs.actime) {
2058 * This was a setfileinfo on an open file.
2059 * NT does this a lot. It's actually pointless
2060 * setting the time here, as it will be overwritten
2061 * on the next write, so we save the request
2062 * away and will set it on file code. JRA.
2065 if (tvs.modtime != (time_t)0 && tvs.modtime != (time_t)-1) {
2066 DEBUG(10,("call_trans2setfilepathinfo: setting pending modtime to %s\n",
2067 ctime(&tvs.modtime) ));
2068 fsp->pending_modtime = tvs.modtime;
2073 DEBUG(10,("call_trans2setfilepathinfo: setting utimes to modified values.\n"));
2075 if(file_utime(conn, fname, &tvs)!=0)
2076 return(UNIXERROR(ERRDOS,ERRnoaccess));
2080 /* check the mode isn't different, before changing it */
2081 if ((mode != 0) && (mode != dos_mode(conn, fname, &sbuf))) {
2083 DEBUG(10,("call_trans2setfilepathinfo: file %s : setting dos mode %x\n",
2086 if(file_chmod(conn, fname, mode, NULL)) {
2087 DEBUG(2,("chmod of %s failed (%s)\n", fname, strerror(errno)));
2088 return(UNIXERROR(ERRDOS,ERRnoaccess));
2092 if(size != sbuf.st_size) {
2094 DEBUG(10,("call_trans2setfilepathinfo: file %s : setting new size to %.0f\n",
2095 fname, (double)size ));
2098 files_struct *new_fsp = NULL;
2099 int access_mode = 0;
2102 if(global_oplock_break) {
2103 /* Queue this file modify as we are the process of an oplock break. */
2105 DEBUG(2,("call_trans2setfilepathinfo: queueing message due to being "));
2106 DEBUGADD(2,( "in oplock break state.\n"));
2108 push_oplock_pending_smb_message(inbuf, length);
2112 new_fsp = open_file_shared(conn, fname, &sbuf,
2113 SET_OPEN_MODE(DOS_OPEN_RDWR),
2114 (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN),
2115 0, 0, &access_mode, &action);
2117 if (new_fsp == NULL)
2118 return(UNIXERROR(ERRDOS,ERRbadpath));
2119 vfs_set_filelen(new_fsp, size);
2120 close_file(new_fsp,True);
2122 vfs_set_filelen(fsp, size);
2128 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
2133 /****************************************************************************
2134 reply to a TRANS2_MKDIR (make directory with extended attributes).
2135 ****************************************************************************/
2136 static int call_trans2mkdir(connection_struct *conn,
2137 char *inbuf, char *outbuf, int length, int bufsize,
2138 char **pparams, char **ppdata)
2140 char *params = *pparams;
2143 SMB_STRUCT_STAT sbuf;
2144 BOOL bad_path = False;
2146 if (!CAN_WRITE(conn))
2147 return ERROR_DOS(ERRSRV,ERRaccess);
2149 srvstr_pull(inbuf, directory, ¶ms[4], sizeof(directory), -1, STR_TERMINATE);
2151 DEBUG(3,("call_trans2mkdir : name = %s\n", directory));
2153 unix_convert(directory,conn,0,&bad_path,&sbuf);
2154 if (check_name(directory,conn))
2155 ret = vfs_mkdir(conn,directory,unix_mode(conn,aDIR,directory));
2159 DEBUG(5,("call_trans2mkdir error (%s)\n", strerror(errno)));
2160 if((errno == ENOENT) && bad_path)
2162 unix_ERR_class = ERRDOS;
2163 unix_ERR_code = ERRbadpath;
2165 return(UNIXERROR(ERRDOS,ERRnoaccess));
2168 /* Realloc the parameter and data sizes */
2169 params = Realloc(*pparams,2);
2170 if(params == NULL) {
2171 return ERROR_DOS(ERRDOS,ERRnomem);
2177 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
2182 /****************************************************************************
2183 reply to a TRANS2_FINDNOTIFYFIRST (start monitoring a directory for changes)
2184 We don't actually do this - we just send a null response.
2185 ****************************************************************************/
2186 static int call_trans2findnotifyfirst(connection_struct *conn,
2187 char *inbuf, char *outbuf,
2188 int length, int bufsize,
2189 char **pparams, char **ppdata)
2191 static uint16 fnf_handle = 257;
2192 char *params = *pparams;
2193 uint16 info_level = SVAL(params,4);
2195 DEBUG(3,("call_trans2findnotifyfirst - info_level %d\n", info_level));
2203 return ERROR_DOS(ERRDOS,ERRunknownlevel);
2206 /* Realloc the parameter and data sizes */
2207 params = Realloc(*pparams,6);
2208 if(params == NULL) {
2209 return ERROR_DOS(ERRDOS,ERRnomem);
2213 SSVAL(params,0,fnf_handle);
2214 SSVAL(params,2,0); /* No changes */
2215 SSVAL(params,4,0); /* No EA errors */
2222 send_trans2_replies(outbuf, bufsize, params, 6, *ppdata, 0);
2227 /****************************************************************************
2228 reply to a TRANS2_FINDNOTIFYNEXT (continue monitoring a directory for
2229 changes). Currently this does nothing.
2230 ****************************************************************************/
2231 static int call_trans2findnotifynext(connection_struct *conn,
2232 char *inbuf, char *outbuf,
2233 int length, int bufsize,
2234 char **pparams, char **ppdata)
2236 char *params = *pparams;
2238 DEBUG(3,("call_trans2findnotifynext\n"));
2240 /* Realloc the parameter and data sizes */
2241 params = Realloc(*pparams,4);
2242 if(params == NULL) {
2243 return ERROR_DOS(ERRDOS,ERRnomem);
2247 SSVAL(params,0,0); /* No changes */
2248 SSVAL(params,2,0); /* No EA errors */
2250 send_trans2_replies(outbuf, bufsize, params, 4, *ppdata, 0);
2255 /****************************************************************************
2256 reply to a TRANS2_GET_DFS_REFERRAL - Shirish Kalele <kalele@veritas.com>
2257 ****************************************************************************/
2258 static int call_trans2getdfsreferral(connection_struct *conn, char* inbuf,
2259 char* outbuf, int length, int bufsize,
2260 char** pparams, char** ppdata)
2262 char *params = *pparams;
2265 int max_referral_level = SVAL(params,0);
2268 DEBUG(10,("call_trans2getdfsreferral\n"));
2270 if(!lp_host_msdfs())
2271 return ERROR_DOS(ERRDOS,ERRbadfunc);
2273 srvstr_pull(inbuf, pathname, ¶ms[2], sizeof(pathname), -1, STR_TERMINATE);
2275 if((reply_size = setup_dfs_referral(pathname,max_referral_level,ppdata)) < 0)
2276 return ERROR_DOS(ERRDOS,ERRbadfile);
2278 SSVAL(outbuf,smb_flg2,SVAL(outbuf,smb_flg2) | FLAGS2_DFS_PATHNAMES);
2279 send_trans2_replies(outbuf,bufsize,0,0,*ppdata,reply_size);
2284 #define LMCAT_SPL 0x53
2285 #define LMFUNC_GETJOBID 0x60
2287 /****************************************************************************
2288 reply to a TRANS2_IOCTL - used for OS/2 printing.
2289 ****************************************************************************/
2291 static int call_trans2ioctl(connection_struct *conn, char* inbuf,
2292 char* outbuf, int length, int bufsize,
2293 char** pparams, char** ppdata)
2295 char *pdata = *ppdata;
2296 files_struct *fsp = file_fsp(inbuf,smb_vwv15);
2298 if ((SVAL(inbuf,(smb_setup+4)) == LMCAT_SPL) &&
2299 (SVAL(inbuf,(smb_setup+6)) == LMFUNC_GETJOBID)) {
2300 pdata = Realloc(*ppdata, 32);
2302 return ERROR_DOS(ERRDOS,ERRnomem);
2306 /* NOTE - THIS IS ASCII ONLY AT THE MOMENT - NOT SURE IF OS/2
2307 CAN ACCEPT THIS IN UNICODE. JRA. */
2309 SSVAL(pdata,0,fsp->print_jobid); /* Job number */
2310 srvstr_push( outbuf, pdata + 2, global_myname, 15, STR_ASCII|STR_TERMINATE); /* Our NetBIOS name */
2311 srvstr_push( outbuf, pdata+18, lp_servicename(SNUM(conn)), 13, STR_ASCII|STR_TERMINATE); /* Service name */
2312 send_trans2_replies(outbuf,bufsize,*pparams,0,*ppdata,32);
2315 DEBUG(2,("Unknown TRANS2_IOCTL\n"));
2316 return ERROR_DOS(ERRSRV,ERRerror);
2320 /****************************************************************************
2321 reply to a SMBfindclose (stop trans2 directory search)
2322 ****************************************************************************/
2323 int reply_findclose(connection_struct *conn,
2324 char *inbuf,char *outbuf,int length,int bufsize)
2327 int dptr_num=SVALS(inbuf,smb_vwv0);
2328 START_PROFILE(SMBfindclose);
2330 DEBUG(3,("reply_findclose, dptr_num = %d\n", dptr_num));
2332 dptr_close(&dptr_num);
2334 outsize = set_message(outbuf,0,0,True);
2336 DEBUG(3,("SMBfindclose dptr_num = %d\n", dptr_num));
2338 END_PROFILE(SMBfindclose);
2342 /****************************************************************************
2343 reply to a SMBfindnclose (stop FINDNOTIFYFIRST directory search)
2344 ****************************************************************************/
2345 int reply_findnclose(connection_struct *conn,
2346 char *inbuf,char *outbuf,int length,int bufsize)
2350 START_PROFILE(SMBfindnclose);
2352 dptr_num = SVAL(inbuf,smb_vwv0);
2354 DEBUG(3,("reply_findnclose, dptr_num = %d\n", dptr_num));
2356 /* We never give out valid handles for a
2357 findnotifyfirst - so any dptr_num is ok here.
2360 outsize = set_message(outbuf,0,0,True);
2362 DEBUG(3,("SMB_findnclose dptr_num = %d\n", dptr_num));
2364 END_PROFILE(SMBfindnclose);
2369 /****************************************************************************
2370 reply to a SMBtranss2 - just ignore it!
2371 ****************************************************************************/
2372 int reply_transs2(connection_struct *conn,
2373 char *inbuf,char *outbuf,int length,int bufsize)
2375 START_PROFILE(SMBtranss2);
2376 DEBUG(4,("Ignoring transs2 of length %d\n",length));
2377 END_PROFILE(SMBtranss2);
2381 /****************************************************************************
2382 reply to a SMBtrans2
2383 ****************************************************************************/
2384 int reply_trans2(connection_struct *conn,
2385 char *inbuf,char *outbuf,int length,int bufsize)
2388 unsigned int total_params = SVAL(inbuf, smb_tpscnt);
2389 unsigned int total_data =SVAL(inbuf, smb_tdscnt);
2391 unsigned int max_param_reply = SVAL(inbuf, smb_mprcnt);
2392 unsigned int max_data_reply = SVAL(inbuf, smb_mdrcnt);
2393 unsigned int max_setup_fields = SVAL(inbuf, smb_msrcnt);
2394 BOOL close_tid = BITSETW(inbuf+smb_flags,0);
2395 BOOL no_final_response = BITSETW(inbuf+smb_flags,1);
2396 int32 timeout = IVALS(inbuf,smb_timeout);
2398 unsigned int suwcnt = SVAL(inbuf, smb_suwcnt);
2399 unsigned int tran_call = SVAL(inbuf, smb_setup0);
2400 char *params = NULL, *data = NULL;
2401 int num_params, num_params_sofar, num_data, num_data_sofar;
2402 START_PROFILE(SMBtrans2);
2404 if(global_oplock_break && (tran_call == TRANSACT2_OPEN)) {
2405 /* Queue this open message as we are the process of an
2408 DEBUG(2,("reply_trans2: queueing message trans2open due to being "));
2409 DEBUGADD(2,( "in oplock break state.\n"));
2411 push_oplock_pending_smb_message(inbuf, length);
2412 END_PROFILE(SMBtrans2);
2416 if (IS_IPC(conn) && (tran_call != TRANSACT2_OPEN)
2417 && (tran_call != TRANSACT2_GET_DFS_REFERRAL)) {
2418 END_PROFILE(SMBtrans2);
2419 return ERROR_DOS(ERRSRV,ERRaccess);
2422 outsize = set_message(outbuf,0,0,True);
2424 /* All trans2 messages we handle have smb_sucnt == 1 - ensure this
2425 is so as a sanity check */
2428 * Need to have rc=0 for ioctl to get job id for OS/2.
2429 * Network printing will fail if function is not successful.
2430 * Similar function in reply.c will be used if protocol
2431 * is LANMAN1.0 instead of LM1.2X002.
2432 * Until DosPrintSetJobInfo with PRJINFO3 is supported,
2433 * outbuf doesn't have to be set(only job id is used).
2435 if ( (suwcnt == 4) && (tran_call == TRANSACT2_IOCTL) &&
2436 (SVAL(inbuf,(smb_setup+4)) == LMCAT_SPL) &&
2437 (SVAL(inbuf,(smb_setup+6)) == LMFUNC_GETJOBID)) {
2438 DEBUG(2,("Got Trans2 DevIOctl jobid\n"));
2440 DEBUG(2,("Invalid smb_sucnt in trans2 call(%d)\n",suwcnt));
2441 DEBUG(2,("Transaction is %d\n",tran_call));
2442 END_PROFILE(SMBtrans2);
2443 return ERROR_DOS(ERRSRV,ERRerror);
2447 /* Allocate the space for the maximum needed parameters and data */
2448 if (total_params > 0)
2449 params = (char *)malloc(total_params);
2451 data = (char *)malloc(total_data);
2453 if ((total_params && !params) || (total_data && !data)) {
2454 DEBUG(2,("Out of memory in reply_trans2\n"));
2457 END_PROFILE(SMBtrans2);
2458 return ERROR_DOS(ERRDOS,ERRnomem);
2461 /* Copy the param and data bytes sent with this request into
2462 the params buffer */
2463 num_params = num_params_sofar = SVAL(inbuf,smb_pscnt);
2464 num_data = num_data_sofar = SVAL(inbuf, smb_dscnt);
2466 if (num_params > total_params || num_data > total_data)
2467 exit_server("invalid params in reply_trans2");
2470 memcpy( params, smb_base(inbuf) + SVAL(inbuf, smb_psoff), num_params);
2472 memcpy( data, smb_base(inbuf) + SVAL(inbuf, smb_dsoff), num_data);
2474 if(num_data_sofar < total_data || num_params_sofar < total_params) {
2475 /* We need to send an interim response then receive the rest
2476 of the parameter/data bytes */
2477 outsize = set_message(outbuf,0,0,True);
2478 if (!send_smb(smbd_server_fd(),outbuf))
2479 exit_server("reply_trans2: send_smb failed.");
2481 while (num_data_sofar < total_data ||
2482 num_params_sofar < total_params) {
2485 ret = receive_next_smb(inbuf,bufsize,SMB_SECONDARY_WAIT);
2488 (CVAL(inbuf, smb_com) != SMBtranss2)) || !ret) {
2489 outsize = set_message(outbuf,0,0,True);
2491 DEBUG(0,("reply_trans2: Invalid secondary trans2 packet\n"));
2493 DEBUG(0,("reply_trans2: %s in getting secondary trans2 response.\n",
2494 (smb_read_error == READ_ERROR) ? "error" : "timeout" ));
2497 END_PROFILE(SMBtrans2);
2498 return ERROR_DOS(ERRSRV,ERRerror);
2501 /* Revise total_params and total_data in case
2502 they have changed downwards */
2503 total_params = SVAL(inbuf, smb_tpscnt);
2504 total_data = SVAL(inbuf, smb_tdscnt);
2505 num_params_sofar += (num_params = SVAL(inbuf,smb_spscnt));
2506 num_data_sofar += ( num_data = SVAL(inbuf, smb_sdscnt));
2507 if (num_params_sofar > total_params || num_data_sofar > total_data)
2508 exit_server("data overflow in trans2");
2510 memcpy( ¶ms[ SVAL(inbuf, smb_spsdisp)],
2511 smb_base(inbuf) + SVAL(inbuf, smb_spsoff), num_params);
2512 memcpy( &data[SVAL(inbuf, smb_sdsdisp)],
2513 smb_base(inbuf)+ SVAL(inbuf, smb_sdsoff), num_data);
2517 if (Protocol >= PROTOCOL_NT1) {
2518 SSVAL(outbuf,smb_flg2,SVAL(outbuf,smb_flg2) | 0x40); /* IS_LONG_NAME */
2521 /* Now we must call the relevant TRANS2 function */
2523 case TRANSACT2_OPEN:
2524 START_PROFILE_NESTED(Trans2_open);
2525 outsize = call_trans2open(conn,
2526 inbuf, outbuf, bufsize,
2528 END_PROFILE_NESTED(Trans2_open);
2531 case TRANSACT2_FINDFIRST:
2532 START_PROFILE_NESTED(Trans2_findfirst);
2533 outsize = call_trans2findfirst(conn, inbuf, outbuf,
2534 bufsize, ¶ms, &data);
2535 END_PROFILE_NESTED(Trans2_findfirst);
2538 case TRANSACT2_FINDNEXT:
2539 START_PROFILE_NESTED(Trans2_findnext);
2540 outsize = call_trans2findnext(conn, inbuf, outbuf,
2543 END_PROFILE_NESTED(Trans2_findnext);
2546 case TRANSACT2_QFSINFO:
2547 START_PROFILE_NESTED(Trans2_qfsinfo);
2548 outsize = call_trans2qfsinfo(conn, inbuf, outbuf,
2549 length, bufsize, ¶ms,
2551 END_PROFILE_NESTED(Trans2_qfsinfo);
2554 case TRANSACT2_SETFSINFO:
2555 START_PROFILE_NESTED(Trans2_setfsinfo);
2556 outsize = call_trans2setfsinfo(conn, inbuf, outbuf,
2559 END_PROFILE_NESTED(Trans2_setfsinfo);
2562 case TRANSACT2_QPATHINFO:
2563 case TRANSACT2_QFILEINFO:
2564 START_PROFILE_NESTED(Trans2_qpathinfo);
2565 outsize = call_trans2qfilepathinfo(conn, inbuf, outbuf,
2567 ¶ms, &data, total_data);
2568 END_PROFILE_NESTED(Trans2_qpathinfo);
2570 case TRANSACT2_SETPATHINFO:
2571 case TRANSACT2_SETFILEINFO:
2572 START_PROFILE_NESTED(Trans2_setpathinfo);
2573 outsize = call_trans2setfilepathinfo(conn, inbuf, outbuf,
2577 END_PROFILE_NESTED(Trans2_setpathinfo);
2580 case TRANSACT2_FINDNOTIFYFIRST:
2581 START_PROFILE_NESTED(Trans2_findnotifyfirst);
2582 outsize = call_trans2findnotifyfirst(conn, inbuf, outbuf,
2585 END_PROFILE_NESTED(Trans2_findnotifyfirst);
2588 case TRANSACT2_FINDNOTIFYNEXT:
2589 START_PROFILE_NESTED(Trans2_findnotifynext);
2590 outsize = call_trans2findnotifynext(conn, inbuf, outbuf,
2593 END_PROFILE_NESTED(Trans2_findnotifynext);
2595 case TRANSACT2_MKDIR:
2596 START_PROFILE_NESTED(Trans2_mkdir);
2597 outsize = call_trans2mkdir(conn, inbuf, outbuf, length,
2598 bufsize, ¶ms, &data);
2599 END_PROFILE_NESTED(Trans2_mkdir);
2602 case TRANSACT2_GET_DFS_REFERRAL:
2603 START_PROFILE_NESTED(Trans2_get_dfs_referral);
2604 outsize = call_trans2getdfsreferral(conn,inbuf,outbuf,length,
2605 bufsize, ¶ms, &data);
2606 END_PROFILE_NESTED(Trans2_get_dfs_referral);
2608 case TRANSACT2_IOCTL:
2609 START_PROFILE_NESTED(Trans2_ioctl);
2610 outsize = call_trans2ioctl(conn,inbuf,outbuf,length,
2611 bufsize,¶ms,&data);
2612 END_PROFILE_NESTED(Trans2_ioctl);
2615 /* Error in request */
2616 DEBUG(2,("Unknown request %d in trans2 call\n", tran_call));
2619 END_PROFILE(SMBtrans2);
2620 return ERROR_DOS(ERRSRV,ERRerror);
2623 /* As we do not know how many data packets will need to be
2624 returned here the various call_trans2xxxx calls
2625 must send their own. Thus a call_trans2xxx routine only
2626 returns a value other than -1 when it wants to send
2632 END_PROFILE(SMBtrans2);
2633 return outsize; /* If a correct response was needed the
2634 call_trans2xxx calls have already sent
2635 it. If outsize != -1 then it is returning */