2 Unix SMB/Netbios implementation.
4 SMB transaction2 handling
5 Copyright (C) Jeremy Allison 1994-2001
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 ****************************************************************************/
41 static int send_trans2_replies(char *outbuf, int bufsize, char *params,
42 int paramsize, char *pdata, int datasize)
44 /* As we are using a protocol > LANMAN1 then the max_send
45 variable must have been set in the sessetupX call.
46 This takes precedence over the max_xmit field in the
47 global struct. These different max_xmit variables should
48 be merged as this is now too confusing */
51 int data_to_send = datasize;
52 int params_to_send = paramsize;
56 int params_sent_thistime, data_sent_thistime, total_sent_thistime;
57 int alignment_offset = 1; /* JRA. This used to be 3. Set to 1 to make netmon parse ok. */
58 int data_alignment_offset = 0;
60 /* Initially set the wcnt area to be 10 - this is true for all
62 set_message(outbuf,10,0,True);
64 /* If there genuinely are no parameters or data to send just send
66 if(params_to_send == 0 && data_to_send == 0)
68 if (!send_smb(smbd_server_fd(),outbuf))
69 exit_server("send_trans2_replies: send_smb failed.");
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.");
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));
185 /****************************************************************************
186 Reply to a TRANSACT2_OPEN.
187 ****************************************************************************/
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_DOS(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_DOS(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_DOS(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 **********************************************************/
299 static BOOL exact_match(char *str,char *mask, BOOL case_sig)
301 if (mask[0] == '.' && mask[1] == 0)
304 return strcmp(str,mask)==0;
305 return strcasecmp(str,mask) == 0;
308 /****************************************************************************
309 Get a level dependent lanman2 dir entry.
310 ****************************************************************************/
312 static BOOL get_lanman2_dir_entry(connection_struct *conn,
313 void *inbuf, void *outbuf,
314 char *path_mask,int dirtype,int info_level,
315 int requires_resume_key,
316 BOOL dont_descend,char **ppdata,
317 char *base_data, int space_remaining,
318 BOOL *out_of_space, BOOL *got_exact_match,
323 SMB_STRUCT_STAT sbuf;
327 char *p, *q, *pdata = *ppdata;
332 SMB_OFF_T allocation_size = 0;
334 time_t mdate=0, adate=0, cdate=0;
337 int nt_extmode; /* Used for NT connections instead of mode */
338 BOOL needslash = ( conn->dirpath[strlen(conn->dirpath) -1] != '/');
341 *out_of_space = False;
342 *got_exact_match = False;
347 p = strrchr_m(path_mask,'/');
354 pstrcpy(mask, path_mask);
359 /* Needed if we run out of space */
360 prev_dirpos = TellDir(conn->dirptr);
361 dname = ReadDirName(conn->dirptr);
364 * Due to bugs in NT client redirectors we are not using
365 * resume keys any more - set them to zero.
366 * Check out the related comments in findfirst/findnext.
372 DEBUG(8,("get_lanman2_dir_entry:readdir on dirptr 0x%lx now at offset %d\n",
373 (long)conn->dirptr,TellDir(conn->dirptr)));
378 pstrcpy(fname,dname);
380 if(!(got_match = *got_exact_match = exact_match(fname, mask, case_sensitive)))
381 got_match = mask_match(fname, mask, case_sensitive);
383 if(!got_match && !is_8_3(fname, False)) {
386 * It turns out that NT matches wildcards against
387 * both long *and* short names. This may explain some
388 * of the wildcard wierdness from old DOS clients
389 * that some people have been seeing.... JRA.
393 pstrcpy( newname, fname);
394 name_map_mangle( newname, True, False, SNUM(conn));
395 if(!(got_match = *got_exact_match = exact_match(newname, mask, case_sensitive)))
396 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);
409 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)) {
413 DEBUG(5,("get_lanman2_dir_entry:Couldn't stat [%s] (%s)\n",
414 pathreal,strerror(errno)));
417 DEBUG(5,("get_lanman2_dir_entry: Masquerading msdfs link %s as a directory\n",
419 sbuf.st_mode = (sbuf.st_mode & 0xFFF) | S_IFDIR;
423 mode = dos_mode(conn,pathreal,&sbuf);
425 if (!dir_check_ftype(conn,mode,&sbuf,dirtype)) {
426 DEBUG(5,("[%s] attribs didn't match %x\n",fname,dirtype));
431 allocation_size = SMB_ROUNDUP_ALLOCATION(sbuf.st_size);
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;
458 switch (info_level) {
460 if(requires_resume_key) {
464 put_dos_date2(p,l1_fdateCreation,cdate);
465 put_dos_date2(p,l1_fdateLastAccess,adate);
466 put_dos_date2(p,l1_fdateLastWrite,mdate);
467 SIVAL(p,l1_cbFile,(uint32)size);
468 SIVAL(p,l1_cbFileAlloc,(uint32)allocation_size);
469 SSVAL(p,l1_attrFile,mode);
472 p += align_string(outbuf, p, 0);
473 len = srvstr_push(outbuf, p, fname, -1, STR_TERMINATE);
474 SCVAL(nameptr, -1, len);
479 if(requires_resume_key) {
483 put_dos_date2(p,l2_fdateCreation,cdate);
484 put_dos_date2(p,l2_fdateLastAccess,adate);
485 put_dos_date2(p,l2_fdateLastWrite,mdate);
486 SIVAL(p,l2_cbFile,(uint32)size);
487 SIVAL(p,l2_cbFileAlloc,(uint32)allocation_size);
488 SSVAL(p,l2_attrFile,mode);
489 SIVAL(p,l2_cbList,0); /* No extended attributes */
492 len = srvstr_push(outbuf, p, fname, -1, STR_NOALIGN);
495 *p++ = 0; /* craig from unisys pointed out we need this */
498 case SMB_FIND_FILE_BOTH_DIRECTORY_INFO:
499 was_8_3 = is_8_3(fname, True);
501 SIVAL(p,0,reskey); p += 4;
502 put_long_date(p,cdate); p += 8;
503 put_long_date(p,adate); p += 8;
504 put_long_date(p,mdate); p += 8;
505 put_long_date(p,mdate); p += 8;
507 SOFF_T(p,8,allocation_size);
509 SIVAL(p,0,nt_extmode); p += 4;
511 SIVAL(p,0,0); p += 4;
513 pstring mangled_name;
514 pstrcpy(mangled_name, fname);
515 name_map_mangle(mangled_name,True,True,SNUM(conn));
516 mangled_name[12] = 0;
517 len = srvstr_push(outbuf, p+2, mangled_name, 24, STR_UPPER);
524 len = srvstr_push(outbuf, p, fname, -1, STR_TERMINATE);
527 len = PTR_DIFF(p, pdata);
528 len = (len + 3) & ~3;
533 case SMB_FIND_FILE_DIRECTORY_INFO:
535 SIVAL(p,0,reskey); p += 4;
536 put_long_date(p,cdate); p += 8;
537 put_long_date(p,adate); p += 8;
538 put_long_date(p,mdate); p += 8;
539 put_long_date(p,mdate); p += 8;
541 SOFF_T(p,8,allocation_size);
543 SIVAL(p,0,nt_extmode); p += 4;
545 len = srvstr_push(outbuf, p, fname, -1, STR_TERMINATE);
548 len = PTR_DIFF(p, pdata);
549 len = (len + 3) & ~3;
554 case SMB_FIND_FILE_FULL_DIRECTORY_INFO:
556 SIVAL(p,0,reskey); p += 4;
557 put_long_date(p,cdate); p += 8;
558 put_long_date(p,adate); p += 8;
559 put_long_date(p,mdate); p += 8;
560 put_long_date(p,mdate); p += 8;
562 SOFF_T(p,8,allocation_size);
564 SIVAL(p,0,nt_extmode); p += 4;
566 SIVAL(p,0,0); p += 4;
568 len = srvstr_push(outbuf, p, fname, -1, STR_TERMINATE);
572 len = PTR_DIFF(p, pdata);
573 len = (len + 3) & ~3;
578 case SMB_FIND_FILE_NAMES_INFO:
580 SIVAL(p,0,reskey); p += 4;
582 len = srvstr_push(outbuf, p, fname, -1, STR_TERMINATE);
585 len = PTR_DIFF(p, pdata);
586 len = (len + 3) & ~3;
596 if (PTR_DIFF(p,pdata) > space_remaining) {
597 /* Move the dirptr back to prev_dirpos */
598 SeekDir(conn->dirptr, prev_dirpos);
599 *out_of_space = True;
600 DEBUG(9,("get_lanman2_dir_entry: out of space\n"));
601 return False; /* Not finished - just out of space */
604 /* Setup the last_filename pointer, as an offset from base_data */
605 *last_name_off = PTR_DIFF(nameptr,base_data);
606 /* Advance the data pointer to the next slot */
612 /****************************************************************************
613 Reply to a TRANS2_FINDFIRST.
614 ****************************************************************************/
616 static int call_trans2findfirst(connection_struct *conn,
617 char *inbuf, char *outbuf, int bufsize,
618 char **pparams, char **ppdata)
620 /* We must be careful here that we don't return more than the
621 allowed number of data bytes. If this means returning fewer than
622 maxentries then so be it. We assume that the redirector has
623 enough room for the fixed number of parameter bytes it has
625 uint32 max_data_bytes = SVAL(inbuf, smb_mdrcnt);
626 char *params = *pparams;
627 char *pdata = *ppdata;
628 int dirtype = SVAL(params,0);
629 int maxentries = SVAL(params,2);
630 BOOL close_after_first = BITSETW(params+4,0);
631 BOOL close_if_end = BITSETW(params+4,1);
632 BOOL requires_resume_key = BITSETW(params+4,2);
633 int info_level = SVAL(params,6);
641 BOOL finished = False;
642 BOOL dont_descend = False;
643 BOOL out_of_space = False;
645 BOOL bad_path = False;
646 SMB_STRUCT_STAT sbuf;
648 *directory = *mask = 0;
650 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",
651 dirtype, maxentries, close_after_first, close_if_end, requires_resume_key,
652 info_level, max_data_bytes));
660 case SMB_FIND_FILE_DIRECTORY_INFO:
661 case SMB_FIND_FILE_FULL_DIRECTORY_INFO:
662 case SMB_FIND_FILE_NAMES_INFO:
663 case SMB_FIND_FILE_BOTH_DIRECTORY_INFO:
666 return(ERROR_DOS(ERRDOS,ERRunknownlevel));
669 srvstr_pull(inbuf, directory, params+12, sizeof(directory), -1, STR_TERMINATE);
671 RESOLVE_FINDFIRST_DFSPATH(directory, conn, inbuf, outbuf);
673 unix_convert(directory,conn,0,&bad_path,&sbuf);
674 if(!check_name(directory,conn)) {
675 if((errno == ENOENT) && bad_path)
677 unix_ERR_class = ERRDOS;
678 unix_ERR_code = ERRbadpath;
682 /* Ugly - NT specific hack - maybe not needed ? (JRA) */
683 if((errno == ENOTDIR) && (Protocol >= PROTOCOL_NT1) &&
684 (get_remote_arch() == RA_WINNT))
686 unix_ERR_class = ERRDOS;
687 unix_ERR_code = ERRbaddirectory;
691 return(UNIXERROR(ERRDOS,ERRbadpath));
694 p = strrchr_m(directory,'/');
696 pstrcpy(mask,directory);
697 pstrcpy(directory,"./");
703 DEBUG(5,("dir=%s, mask = %s\n",directory, mask));
705 pdata = Realloc(*ppdata, max_data_bytes + 1024);
706 if( pdata == NULL ) {
707 return(ERROR_DOS(ERRDOS,ERRnomem));
710 memset((char *)pdata,'\0',max_data_bytes + 1024);
712 /* Realloc the params space */
713 params = Realloc(*pparams, 10);
714 if (params == NULL) {
715 return ERROR_DOS(ERRDOS,ERRnomem);
719 dptr_num = dptr_create(conn,directory, False, True ,SVAL(inbuf,smb_pid));
721 return(UNIXERROR(ERRDOS,ERRbadfile));
723 /* Save the wildcard match and attribs we are using on this directory -
724 needed as lanman2 assumes these are being saved between calls */
726 if(!(wcard = strdup(mask))) {
727 dptr_close(&dptr_num);
728 return ERROR_DOS(ERRDOS,ERRnomem);
731 dptr_set_wcard(dptr_num, wcard);
732 dptr_set_attr(dptr_num, dirtype);
734 DEBUG(4,("dptr_num is %d, wcard = %s, attr = %d\n",dptr_num, wcard, dirtype));
736 /* We don't need to check for VOL here as this is returned by
737 a different TRANS2 call. */
739 DEBUG(8,("dirpath=<%s> dontdescend=<%s>\n",
740 conn->dirpath,lp_dontdescend(SNUM(conn))));
741 if (in_list(conn->dirpath,lp_dontdescend(SNUM(conn)),case_sensitive))
745 space_remaining = max_data_bytes;
746 out_of_space = False;
748 for (i=0;(i<maxentries) && !finished && !out_of_space;i++)
750 BOOL got_exact_match = False;
752 /* this is a heuristic to avoid seeking the dirptr except when
753 absolutely necessary. It allows for a filename of about 40 chars */
754 if (space_remaining < DIRLEN_GUESS && numentries > 0)
761 finished = !get_lanman2_dir_entry(conn,
763 mask,dirtype,info_level,
764 requires_resume_key,dont_descend,
765 &p,pdata,space_remaining, &out_of_space, &got_exact_match,
769 if (finished && out_of_space)
772 if (!finished && !out_of_space)
776 * As an optimisation if we know we aren't looking
777 * for a wildcard name (ie. the name matches the wildcard exactly)
778 * then we can finish on any (first) match.
779 * This speeds up large directory searches. JRA.
785 space_remaining = max_data_bytes - PTR_DIFF(p,pdata);
788 /* Check if we can close the dirptr */
789 if(close_after_first || (finished && close_if_end))
791 DEBUG(5,("call_trans2findfirst - (2) closing dptr_num %d\n", dptr_num));
792 dptr_close(&dptr_num);
796 * If there are no matching entries we must return ERRDOS/ERRbadfile -
797 * from observation of NT.
800 if(numentries == 0) {
801 dptr_close(&dptr_num);
802 return ERROR_DOS(ERRDOS,ERRbadfile);
805 /* At this point pdata points to numentries directory entries. */
807 /* Set up the return parameter block */
808 SSVAL(params,0,dptr_num);
809 SSVAL(params,2,numentries);
810 SSVAL(params,4,finished);
811 SSVAL(params,6,0); /* Never an EA error */
812 SSVAL(params,8,last_name_off);
814 send_trans2_replies( outbuf, bufsize, params, 10, pdata, PTR_DIFF(p,pdata));
816 if ((! *directory) && dptr_path(dptr_num))
817 slprintf(directory,sizeof(directory)-1, "(%s)",dptr_path(dptr_num));
819 DEBUG( 4, ( "%s mask=%s directory=%s dirtype=%d numentries=%d\n",
820 smb_fn_name(CVAL(inbuf,smb_com)),
821 mask, directory, dirtype, numentries ) );
824 * Force a name mangle here to ensure that the
825 * mask as an 8.3 name is top of the mangled cache.
826 * The reasons for this are subtle. Don't remove
827 * this code unless you know what you are doing
828 * (see PR#13758). JRA.
831 if(!is_8_3( mask, False))
832 name_map_mangle(mask, True, True, SNUM(conn));
837 /****************************************************************************
838 Reply to a TRANS2_FINDNEXT.
839 ****************************************************************************/
841 static int call_trans2findnext(connection_struct *conn,
842 char *inbuf, char *outbuf,
843 int length, int bufsize,
844 char **pparams, char **ppdata)
846 /* We must be careful here that we don't return more than the
847 allowed number of data bytes. If this means returning fewer than
848 maxentries then so be it. We assume that the redirector has
849 enough room for the fixed number of parameter bytes it has
851 int max_data_bytes = SVAL(inbuf, smb_mdrcnt);
852 char *params = *pparams;
853 char *pdata = *ppdata;
854 int dptr_num = SVAL(params,0);
855 int maxentries = SVAL(params,2);
856 uint16 info_level = SVAL(params,4);
857 uint32 resume_key = IVAL(params,6);
858 BOOL close_after_request = BITSETW(params+10,0);
859 BOOL close_if_end = BITSETW(params+10,1);
860 BOOL requires_resume_key = BITSETW(params+10,2);
861 BOOL continue_bit = BITSETW(params+10,3);
868 int i, last_name_off=0;
869 BOOL finished = False;
870 BOOL dont_descend = False;
871 BOOL out_of_space = False;
874 *mask = *directory = *resume_name = 0;
876 srvstr_pull(inbuf, resume_name, params+12, sizeof(resume_name), -1, STR_TERMINATE);
878 DEBUG(3,("call_trans2findnext: dirhandle = %d, max_data_bytes = %d, maxentries = %d, \
879 close_after_request=%d, close_if_end = %d requires_resume_key = %d \
880 resume_key = %d resume name = %s continue=%d level = %d\n",
881 dptr_num, max_data_bytes, maxentries, close_after_request, close_if_end,
882 requires_resume_key, resume_key, resume_name, continue_bit, info_level));
890 case SMB_FIND_FILE_DIRECTORY_INFO:
891 case SMB_FIND_FILE_FULL_DIRECTORY_INFO:
892 case SMB_FIND_FILE_NAMES_INFO:
893 case SMB_FIND_FILE_BOTH_DIRECTORY_INFO:
896 return ERROR_DOS(ERRDOS,ERRunknownlevel);
899 pdata = Realloc( *ppdata, max_data_bytes + 1024);
901 return ERROR_DOS(ERRDOS,ERRnomem);
904 memset((char *)pdata,'\0',max_data_bytes + 1024);
906 /* Realloc the params space */
907 params = Realloc(*pparams, 6*SIZEOFWORD);
908 if( params == NULL ) {
909 return ERROR_DOS(ERRDOS,ERRnomem);
913 /* Check that the dptr is valid */
914 if(!(conn->dirptr = dptr_fetch_lanman2(dptr_num)))
915 return ERROR_DOS(ERRDOS,ERRnofiles);
917 string_set(&conn->dirpath,dptr_path(dptr_num));
919 /* Get the wildcard mask from the dptr */
920 if((p = dptr_wcard(dptr_num))== NULL) {
921 DEBUG(2,("dptr_num %d has no wildcard\n", dptr_num));
922 return ERROR_DOS(ERRDOS,ERRnofiles);
925 pstrcpy(directory,conn->dirpath);
927 /* Get the attr mask from the dptr */
928 dirtype = dptr_attr(dptr_num);
930 DEBUG(3,("dptr_num is %d, mask = %s, attr = %x, dirptr=(0x%lX,%d)\n",
931 dptr_num, mask, dirtype,
933 TellDir(conn->dirptr)));
935 /* We don't need to check for VOL here as this is returned by
936 a different TRANS2 call. */
938 DEBUG(8,("dirpath=<%s> dontdescend=<%s>\n",conn->dirpath,lp_dontdescend(SNUM(conn))));
939 if (in_list(conn->dirpath,lp_dontdescend(SNUM(conn)),case_sensitive))
943 space_remaining = max_data_bytes;
944 out_of_space = False;
947 * Seek to the correct position. We no longer use the resume key but
948 * depend on the last file name instead.
950 if(requires_resume_key && *resume_name && !continue_bit)
953 * Fix for NT redirector problem triggered by resume key indexes
954 * changing between directory scans. We now return a resume key of 0
955 * and instead look for the filename to continue from (also given
956 * to us by NT/95/smbfs/smbclient). If no other scans have been done between the
957 * findfirst/findnext (as is usual) then the directory pointer
958 * should already be at the correct place. Check this by scanning
959 * backwards looking for an exact (ie. case sensitive) filename match.
960 * If we get to the beginning of the directory and haven't found it then scan
961 * forwards again looking for a match. JRA.
964 int current_pos, start_pos;
966 void *dirptr = conn->dirptr;
967 start_pos = TellDir(dirptr);
968 for(current_pos = start_pos; current_pos >= 0; current_pos--)
970 DEBUG(7,("call_trans2findnext: seeking to pos %d\n", current_pos));
972 SeekDir(dirptr, current_pos);
973 dname = ReadDirName(dirptr);
976 * Remember, name_map_mangle is called by
977 * get_lanman2_dir_entry(), so the resume name
978 * could be mangled. Ensure we do the same
983 name_map_mangle( dname, False, True, SNUM(conn));
985 if(dname && strcsequal( resume_name, dname))
987 SeekDir(dirptr, current_pos+1);
988 DEBUG(7,("call_trans2findnext: got match at pos %d\n", current_pos+1 ));
994 * Scan forward from start if not found going backwards.
999 DEBUG(7,("call_trans2findnext: notfound: seeking to pos %d\n", start_pos));
1000 SeekDir(dirptr, start_pos);
1001 for(current_pos = start_pos; (dname = ReadDirName(dirptr)) != NULL; SeekDir(dirptr,++current_pos))
1004 * Remember, name_map_mangle is called by
1005 * get_lanman2_dir_entry(), so the resume name
1006 * could be mangled. Ensure we do the same
1011 name_map_mangle( dname, False, True, SNUM(conn));
1013 if(dname && strcsequal( resume_name, dname))
1015 SeekDir(dirptr, current_pos+1);
1016 DEBUG(7,("call_trans2findnext: got match at pos %d\n", current_pos+1 ));
1020 } /* end if current_pos */
1021 } /* end if requires_resume_key && !continue_bit */
1023 for (i=0;(i<(int)maxentries) && !finished && !out_of_space ;i++)
1025 BOOL got_exact_match = False;
1027 /* this is a heuristic to avoid seeking the dirptr except when
1028 absolutely necessary. It allows for a filename of about 40 chars */
1029 if (space_remaining < DIRLEN_GUESS && numentries > 0)
1031 out_of_space = True;
1036 finished = !get_lanman2_dir_entry(conn,
1038 mask,dirtype,info_level,
1039 requires_resume_key,dont_descend,
1040 &p,pdata,space_remaining, &out_of_space, &got_exact_match,
1044 if (finished && out_of_space)
1047 if (!finished && !out_of_space)
1051 * As an optimisation if we know we aren't looking
1052 * for a wildcard name (ie. the name matches the wildcard exactly)
1053 * then we can finish on any (first) match.
1054 * This speeds up large directory searches. JRA.
1060 space_remaining = max_data_bytes - PTR_DIFF(p,pdata);
1063 /* Check if we can close the dirptr */
1064 if(close_after_request || (finished && close_if_end))
1066 DEBUG(5,("call_trans2findnext: closing dptr_num = %d\n", dptr_num));
1067 dptr_close(&dptr_num); /* This frees up the saved mask */
1071 /* Set up the return parameter block */
1072 SSVAL(params,0,numentries);
1073 SSVAL(params,2,finished);
1074 SSVAL(params,4,0); /* Never an EA error */
1075 SSVAL(params,6,last_name_off);
1077 send_trans2_replies( outbuf, bufsize, params, 8, pdata, PTR_DIFF(p,pdata));
1079 if ((! *directory) && dptr_path(dptr_num))
1080 slprintf(directory,sizeof(directory)-1, "(%s)",dptr_path(dptr_num));
1082 DEBUG( 3, ( "%s mask=%s directory=%s dirtype=%d numentries=%d\n",
1083 smb_fn_name(CVAL(inbuf,smb_com)),
1084 mask, directory, dirtype, numentries ) );
1089 /****************************************************************************
1090 Reply to a TRANS2_QFSINFO (query filesystem info).
1091 ****************************************************************************/
1093 static int call_trans2qfsinfo(connection_struct *conn,
1094 char *inbuf, char *outbuf,
1095 int length, int bufsize,
1096 char **pparams, char **ppdata)
1098 int max_data_bytes = SVAL(inbuf, smb_mdrcnt);
1099 char *pdata = *ppdata;
1100 char *params = *pparams;
1101 uint16 info_level = SVAL(params,0);
1104 char *vname = volume_label(SNUM(conn));
1105 int snum = SNUM(conn);
1106 char *fstype = lp_fstype(SNUM(conn));
1108 DEBUG(3,("call_trans2qfsinfo: level = %d\n", info_level));
1110 if(vfs_stat(conn,".",&st)!=0) {
1111 DEBUG(2,("call_trans2qfsinfo: stat of . failed (%s)\n", strerror(errno)));
1112 return ERROR_DOS(ERRSRV,ERRinvdevice);
1115 pdata = Realloc(*ppdata, max_data_bytes + 1024);
1116 if ( pdata == NULL ) {
1117 return ERROR_DOS(ERRDOS,ERRnomem);
1120 memset((char *)pdata,'\0',max_data_bytes + 1024);
1126 SMB_BIG_UINT dfree,dsize,bsize;
1128 conn->vfs_ops.disk_free(conn,".",False,&bsize,&dfree,&dsize);
1129 SIVAL(pdata,l1_idFileSystem,st.st_dev);
1130 SIVAL(pdata,l1_cSectorUnit,bsize/512);
1131 SIVAL(pdata,l1_cUnit,dsize);
1132 SIVAL(pdata,l1_cUnitAvail,dfree);
1133 SSVAL(pdata,l1_cbSector,512);
1134 DEBUG(5,("call_trans2qfsinfo : bsize=%u, id=%x, cSectorUnit=%u, cUnit=%u, cUnitAvail=%u, cbSector=%d\n",
1135 (unsigned int)bsize, (unsigned int)st.st_dev, ((unsigned int)bsize)/512, (unsigned int)dsize,
1136 (unsigned int)dfree, 512));
1140 /* Return volume name */
1142 * Add volume serial number - hash of a combination of
1143 * the called hostname and the service name.
1145 SIVAL(pdata,0,str_checksum(lp_servicename(snum)) ^ (str_checksum(local_machine)<<16) );
1146 len = srvstr_push(outbuf, pdata+l2_vol_szVolLabel, vname, -1,
1148 SCVAL(pdata,l2_vol_cch,len);
1149 data_len = l2_vol_szVolLabel + len;
1150 DEBUG(5,("call_trans2qfsinfo : time = %x, namelen = %d, name = %s\n",
1151 (unsigned)st.st_ctime, len, vname));
1154 case SMB_QUERY_FS_ATTRIBUTE_INFO:
1155 SIVAL(pdata,0,FILE_CASE_PRESERVED_NAMES|FILE_CASE_SENSITIVE_SEARCH|
1156 (lp_nt_acl_support(SNUM(conn)) ? FILE_PERSISTENT_ACLS : 0)); /* FS ATTRIBUTES */
1157 SIVAL(pdata,4,255); /* Max filename component length */
1158 /* NOTE! the fstype must *not* be null terminated or win98 won't recognise it
1159 and will think we can't do long filenames */
1160 len = srvstr_push(outbuf, pdata+12, fstype, -1, 0);
1162 data_len = 12 + len;
1165 case SMB_QUERY_FS_LABEL_INFO:
1166 len = srvstr_push(outbuf, pdata+4, vname, -1, STR_TERMINATE);
1170 case SMB_QUERY_FS_VOLUME_INFO:
1172 * Add volume serial number - hash of a combination of
1173 * the called hostname and the service name.
1175 SIVAL(pdata,8,str_checksum(lp_servicename(snum)) ^
1176 (str_checksum(local_machine)<<16));
1178 len = srvstr_push(outbuf, pdata+18, vname, -1, STR_TERMINATE);
1179 SIVAL(pdata,12,len);
1181 DEBUG(5,("call_trans2qfsinfo : SMB_QUERY_FS_VOLUME_INFO namelen = %d, vol=%s serv=%s\n",
1182 (int)strlen(vname),vname, lp_servicename(snum)));
1184 case SMB_QUERY_FS_SIZE_INFO:
1186 SMB_BIG_UINT dfree,dsize,bsize;
1188 conn->vfs_ops.disk_free(conn,".",False,&bsize,&dfree,&dsize);
1189 SBIG_UINT(pdata,0,dsize);
1190 SBIG_UINT(pdata,8,dfree);
1191 SIVAL(pdata,16,bsize/512);
1192 SIVAL(pdata,20,512);
1195 case SMB_QUERY_FS_DEVICE_INFO:
1197 SIVAL(pdata,0,0); /* dev type */
1198 SIVAL(pdata,4,0); /* characteristics */
1200 case SMB_MAC_QUERY_FS_INFO:
1202 * Thursby MAC extension... ONLY on NTFS filesystems
1203 * once we do streams then we don't need this
1205 if (strequal(lp_fstype(SNUM(conn)),"NTFS")) {
1207 SIVAL(pdata,84,0x100); /* Don't support mac... */
1212 return ERROR_DOS(ERRDOS,ERRunknownlevel);
1216 send_trans2_replies( outbuf, bufsize, params, 0, pdata, data_len);
1218 DEBUG( 4, ( "%s info_level = %d\n",
1219 smb_fn_name(CVAL(inbuf,smb_com)), info_level) );
1224 /****************************************************************************
1225 Reply to a TRANS2_SETFSINFO (set filesystem info).
1226 ****************************************************************************/
1228 static int call_trans2setfsinfo(connection_struct *conn,
1229 char *inbuf, char *outbuf, int length,
1231 char **pparams, char **ppdata)
1233 /* Just say yes we did it - there is nothing that
1234 can be set here so it doesn't matter. */
1236 DEBUG(3,("call_trans2setfsinfo\n"));
1238 if (!CAN_WRITE(conn))
1239 return ERROR_DOS(ERRSRV,ERRaccess);
1241 outsize = set_message(outbuf,10,0,True);
1246 /****************************************************************************
1247 Reply to a TRANS2_QFILEPATHINFO or TRANSACT2_QFILEINFO (query file info by
1248 file name or file id).
1249 ****************************************************************************/
1251 static int call_trans2qfilepathinfo(connection_struct *conn,
1252 char *inbuf, char *outbuf, int length,
1254 char **pparams,char **ppdata,
1257 int max_data_bytes = SVAL(inbuf, smb_mdrcnt);
1258 char *params = *pparams;
1259 char *pdata = *ppdata;
1260 uint16 tran_call = SVAL(inbuf, smb_setup0);
1264 SMB_OFF_T allocation_size=0;
1265 unsigned int data_size;
1266 SMB_STRUCT_STAT sbuf;
1271 BOOL bad_path = False;
1272 BOOL delete_pending = False;
1276 if (tran_call == TRANSACT2_QFILEINFO) {
1277 files_struct *fsp = file_fsp(params,0);
1278 info_level = SVAL(params,2);
1280 DEBUG(3,("call_trans2qfilepathinfo: TRANSACT2_QFILEINFO: level = %d\n", info_level));
1282 if(fsp && (fsp->is_directory || fsp->stat_open)) {
1284 * This is actually a QFILEINFO on a directory
1285 * handle (returned from an NT SMB). NT5.0 seems
1286 * to do this call. JRA.
1288 pstrcpy(fname, fsp->fsp_name);
1289 unix_convert(fname,conn,0,&bad_path,&sbuf);
1290 if (!check_name(fname,conn) ||
1291 (!VALID_STAT(sbuf) && vfs_stat(conn,fname,&sbuf))) {
1292 DEBUG(3,("fileinfo of %s failed (%s)\n",fname,strerror(errno)));
1293 if((errno == ENOENT) && bad_path) {
1294 unix_ERR_class = ERRDOS;
1295 unix_ERR_code = ERRbadpath;
1297 return(UNIXERROR(ERRDOS,ERRbadpath));
1300 delete_pending = fsp->directory_delete_on_close;
1303 * Original code - this is an open file.
1305 CHECK_FSP(fsp,conn);
1307 pstrcpy(fname, fsp->fsp_name);
1308 if (vfs_fstat(fsp,fsp->fd,&sbuf) != 0) {
1309 DEBUG(3,("fstat of fnum %d failed (%s)\n", fsp->fnum, strerror(errno)));
1310 return(UNIXERROR(ERRDOS,ERRbadfid));
1312 if((pos = fsp->conn->vfs_ops.lseek(fsp,fsp->fd,0,SEEK_CUR)) == -1)
1313 return(UNIXERROR(ERRDOS,ERRnoaccess));
1315 delete_pending = fsp->delete_on_close;
1319 info_level = SVAL(params,0);
1321 DEBUG(3,("call_trans2qfilepathinfo: TRANSACT2_QPATHINFO: level = %d\n", info_level));
1323 srvstr_pull(inbuf, fname, ¶ms[6], sizeof(fname), -1, STR_TERMINATE);
1325 RESOLVE_DFSPATH(fname, conn, inbuf, outbuf);
1327 unix_convert(fname,conn,0,&bad_path,&sbuf);
1328 if (!check_name(fname,conn) ||
1329 (!VALID_STAT(sbuf) && vfs_stat(conn,fname,&sbuf))) {
1330 DEBUG(3,("fileinfo of %s failed (%s)\n",fname,strerror(errno)));
1331 if((errno == ENOENT) && bad_path) {
1332 unix_ERR_class = ERRDOS;
1333 unix_ERR_code = ERRbadpath;
1335 return(UNIXERROR(ERRDOS,ERRbadpath));
1340 DEBUG(3,("call_trans2qfilepathinfo %s level=%d call=%d total_data=%d\n",
1341 fname,info_level,tran_call,total_data));
1343 p = strrchr_m(fname,'/');
1349 mode = dos_mode(conn,fname,&sbuf);
1350 size = sbuf.st_size;
1351 allocation_size = SMB_ROUNDUP_ALLOCATION(sbuf.st_size);
1356 params = Realloc(*pparams,2);
1358 return ERROR_DOS(ERRDOS,ERRnomem);
1360 memset((char *)params,'\0',2);
1361 data_size = max_data_bytes + 1024;
1362 pdata = Realloc(*ppdata, data_size);
1363 if ( pdata == NULL )
1364 return ERROR_DOS(ERRDOS,ERRnomem);
1367 if (total_data > 0 && IVAL(pdata,0) == total_data) {
1368 /* uggh, EAs for OS2 */
1369 DEBUG(4,("Rejecting EA request with total_data=%d\n",total_data));
1370 return ERROR_DOS(ERRDOS,ERReasnotsupported);
1373 memset((char *)pdata,'\0',data_size);
1375 c_time = get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(conn)));
1377 if (lp_dos_filetime_resolution(SNUM(conn))) {
1379 sbuf.st_atime &= ~1;
1380 sbuf.st_mtime &= ~1;
1381 sbuf.st_mtime &= ~1;
1384 switch (info_level) {
1385 case SMB_INFO_STANDARD:
1386 case SMB_INFO_QUERY_EA_SIZE:
1387 data_size = (info_level==1?22:26);
1388 put_dos_date2(pdata,l1_fdateCreation,c_time);
1389 put_dos_date2(pdata,l1_fdateLastAccess,sbuf.st_atime);
1390 put_dos_date2(pdata,l1_fdateLastWrite,sbuf.st_mtime); /* write time */
1391 SIVAL(pdata,l1_cbFile,(uint32)size);
1392 SIVAL(pdata,l1_cbFileAlloc,(uint32)allocation_size);
1393 SSVAL(pdata,l1_attrFile,mode);
1394 SIVAL(pdata,l1_attrFile+2,4); /* this is what OS2 does */
1397 case SMB_INFO_QUERY_EAS_FROM_LIST:
1399 put_dos_date2(pdata,0,c_time);
1400 put_dos_date2(pdata,4,sbuf.st_atime);
1401 put_dos_date2(pdata,8,sbuf.st_mtime);
1402 SIVAL(pdata,12,(uint32)size);
1403 SIVAL(pdata,16,(uint32)allocation_size);
1404 SIVAL(pdata,20,mode);
1407 case SMB_INFO_QUERY_ALL_EAS:
1409 SIVAL(pdata,0,data_size);
1413 return ERROR_DOS(ERRDOS,ERRbadfunc); /* os/2 needs this */
1415 case SMB_FILE_BASIC_INFORMATION:
1416 case SMB_QUERY_FILE_BASIC_INFO:
1418 if (info_level == SMB_QUERY_FILE_BASIC_INFO)
1419 data_size = 36; /* w95 returns 40 bytes not 36 - why ?. */
1424 put_long_date(pdata,c_time);
1425 put_long_date(pdata+8,sbuf.st_atime);
1426 put_long_date(pdata+16,sbuf.st_mtime); /* write time */
1427 put_long_date(pdata+24,sbuf.st_mtime); /* change time */
1428 SIVAL(pdata,32,mode);
1430 DEBUG(5,("SMB_QFBI - "));
1432 time_t create_time = c_time;
1433 DEBUG(5,("create: %s ", ctime(&create_time)));
1435 DEBUG(5,("access: %s ", ctime(&sbuf.st_atime)));
1436 DEBUG(5,("write: %s ", ctime(&sbuf.st_mtime)));
1437 DEBUG(5,("change: %s ", ctime(&sbuf.st_mtime)));
1438 DEBUG(5,("mode: %x\n", mode));
1442 case SMB_FILE_STANDARD_INFORMATION:
1443 case SMB_QUERY_FILE_STANDARD_INFO:
1445 /* Fake up allocation size. */
1446 SOFF_T(pdata,0,allocation_size);
1447 SOFF_T(pdata,8,size);
1448 SIVAL(pdata,16,sbuf.st_nlink);
1450 CVAL(pdata,21) = (mode&aDIR)?1:0;
1453 case SMB_FILE_EA_INFORMATION:
1454 case SMB_QUERY_FILE_EA_INFO:
1458 /* Get the 8.3 name - used if NT SMB was negotiated. */
1459 case SMB_QUERY_FILE_ALT_NAME_INFO:
1463 pstrcpy(short_name,base_name);
1464 /* Mangle if not already 8.3 */
1465 if(!is_8_3(short_name, True)) {
1466 if(!name_map_mangle(short_name,True,True,SNUM(conn)))
1469 len = srvstr_push(outbuf, pdata+4, short_name, -1, STR_TERMINATE|STR_UPPER);
1470 data_size = 4 + len;
1475 case SMB_QUERY_FILE_NAME_INFO:
1477 * The first part of this code is essential
1478 * to get security descriptors to work on mapped
1479 * drives. Don't ask how I discovered this unless
1480 * you like hearing about me suffering.... :-). JRA.
1482 if(strequal(".", fname)) {
1483 len = srvstr_push(outbuf, pdata+4, "\\", -1, STR_TERMINATE);
1485 len = srvstr_push(outbuf, pdata+4, fname, -1, STR_TERMINATE);
1487 data_size = 4 + len;
1491 case SMB_FILE_END_OF_FILE_INFORMATION:
1492 case SMB_QUERY_FILE_END_OF_FILEINFO:
1494 SOFF_T(pdata,0,size);
1497 case SMB_FILE_ALLOCATION_INFORMATION:
1498 case SMB_QUERY_FILE_ALLOCATION_INFO:
1500 SOFF_T(pdata,0,allocation_size);
1503 case SMB_QUERY_FILE_ALL_INFO:
1504 put_long_date(pdata,c_time);
1505 put_long_date(pdata+8,sbuf.st_atime);
1506 put_long_date(pdata+16,sbuf.st_mtime); /* write time */
1507 put_long_date(pdata+24,sbuf.st_mtime); /* change time */
1508 SIVAL(pdata,32,mode);
1510 SOFF_T(pdata,0,allocation_size);
1511 SOFF_T(pdata,8,size);
1512 SIVAL(pdata,16,sbuf.st_nlink);
1513 CVAL(pdata,20) = delete_pending;
1514 CVAL(pdata,21) = (mode&aDIR)?1:0;
1516 SINO_T(pdata,0,(SMB_INO_T)sbuf.st_ino);
1517 pdata += 8; /* index number */
1518 pdata += 4; /* EA info */
1520 SIVAL(pdata,0,0xA9);
1522 SIVAL(pdata,0,0xd01BF);
1524 SOFF_T(pdata,0,pos); /* current offset */
1526 SIVAL(pdata,0,mode); /* is this the right sort of mode info? */
1528 pdata += 4; /* alignment */
1529 len = srvstr_push(outbuf, pdata+4, fname, -1, STR_TERMINATE);
1532 data_size = PTR_DIFF(pdata,(*ppdata));
1535 case SMB_FILE_INTERNAL_INFORMATION:
1536 /* This should be an index number - looks like dev/ino to me :-) */
1537 SIVAL(pdata,0,sbuf.st_dev);
1538 SIVAL(pdata,4,sbuf.st_ino);
1542 case SMB_FILE_ACCESS_INFORMATION:
1543 SIVAL(pdata,0,0x12019F); /* ??? */
1547 case SMB_FILE_NAME_INFORMATION:
1548 /* Pathname with leading '\'. */
1553 pstrcpy(new_fname, "\\");
1554 pstrcat(new_fname, fname);
1555 byte_len = dos_PutUniCode(pdata+4,new_fname,max_data_bytes,False);
1556 SIVAL(pdata,0,byte_len);
1557 data_size = 4 + byte_len;
1561 case SMB_FILE_DISPOSITION_INFORMATION:
1563 CVAL(pdata,0) = delete_pending;
1566 case SMB_FILE_POSITION_INFORMATION:
1568 SOFF_T(pdata,0,pos);
1571 case SMB_FILE_MODE_INFORMATION:
1572 SIVAL(pdata,0,mode);
1576 case SMB_FILE_ALIGNMENT_INFORMATION:
1577 SIVAL(pdata,0,0); /* No alignment needed. */
1582 /* Not yet finished... JRA */
1588 put_long_date(pdata,c_time);
1589 put_long_date(pdata+8,sbuf.st_atime);
1590 put_long_date(pdata+16,sbuf.st_mtime); /* write time */
1591 put_long_date(pdata+24,sbuf.st_mtime); /* change time */
1592 SIVAL(pdata,32,mode);
1593 SIVAL(pdata,36,0); /* ??? */
1594 SIVAL(pdata,40,0x20); /* ??? */
1595 SIVAL(pdata,44,0); /* ??? */
1596 SOFF_T(pdata,48,size);
1597 SIVAL(pdata,56,0x1); /* ??? */
1598 SIVAL(pdata,60,0); /* ??? */
1599 SIVAL(pdata,64,0); /* ??? */
1600 SIVAL(pdata,68,length); /* Following string length in bytes. */
1601 dos_PutUniCode(pdata+72,,False);
1606 case SMB_FILE_ALTERNATE_NAME_INFORMATION:
1607 /* Last component of pathname. */
1609 size_t byte_len = dos_PutUniCode(pdata+4,fname,max_data_bytes,False);
1610 SIVAL(pdata,0,byte_len);
1611 data_size = 4 + byte_len;
1615 case SMB_FILE_STREAM_INFORMATION:
1619 size_t byte_len = dos_PutUniCode(pdata+24,"::$DATA", 0xE, False);
1620 SIVAL(pdata,0,0); /* ??? */
1621 SIVAL(pdata,4,byte_len); /* Byte length of unicode string ::$DATA */
1622 SOFF_T(pdata,8,size);
1623 SIVAL(pdata,16,allocation_size);
1624 SIVAL(pdata,20,0); /* ??? */
1625 data_size = 24 + byte_len;
1629 case SMB_FILE_COMPRESSION_INFORMATION:
1630 SOFF_T(pdata,0,size);
1631 SIVAL(pdata,8,0); /* ??? */
1632 SIVAL(pdata,12,0); /* ??? */
1636 case SMB_FILE_NETWORK_OPEN_INFORMATION:
1637 put_long_date(pdata,c_time);
1638 put_long_date(pdata+8,sbuf.st_atime);
1639 put_long_date(pdata+16,sbuf.st_mtime); /* write time */
1640 put_long_date(pdata+24,sbuf.st_mtime); /* change time */
1641 SIVAL(pdata,32,allocation_size);
1642 SOFF_T(pdata,40,size);
1643 SIVAL(pdata,48,mode);
1644 SIVAL(pdata,52,0); /* ??? */
1648 case SMB_FILE_ATTRIBUTE_TAG_INFORMATION:
1649 SIVAL(pdata,0,mode);
1655 /* NT4 server just returns "invalid query" to this - if we try to answer
1656 it then NTws gets a BSOD! (tridge) */
1657 case SMB_QUERY_FILE_STREAM_INFO:
1659 SIVAL(pdata,4,(uint32)size);
1660 SIVAL(pdata,12,(uint32)allocation_size);
1661 len = srvstr_push(outbuf, pdata+24, fname, -1, STR_TERMINATE);
1662 SIVAL(pdata,20,len);
1663 data_size = 24 + len;
1668 return ERROR_DOS(ERRDOS,ERRunknownlevel);
1671 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, data_size);
1676 /****************************************************************************
1677 Deal with the internal needs of setting the delete on close flag. Note that
1678 as the tdb locking is recursive, it is safe to call this from within
1679 open_file_shared. JRA.
1680 ****************************************************************************/
1682 NTSTATUS set_delete_on_close_internal(files_struct *fsp, BOOL delete_on_close)
1685 * Only allow delete on close for writable shares.
1688 if (delete_on_close && !CAN_WRITE(fsp->conn)) {
1689 DEBUG(10,("set_delete_on_close_internal: file %s delete on close flag set but write access denied on share.\n",
1691 return NT_STATUS_ACCESS_DENIED;
1694 * Only allow delete on close for files/directories opened with delete intent.
1697 if (delete_on_close && !GET_DELETE_ACCESS_REQUESTED(fsp->share_mode)) {
1698 DEBUG(10,("set_delete_on_close_internal: file %s delete on close flag set but delete access denied.\n",
1700 return NT_STATUS_ACCESS_DENIED;
1703 if(fsp->is_directory) {
1704 fsp->directory_delete_on_close = delete_on_close;
1705 DEBUG(10, ("set_delete_on_close_internal: %s delete on close flag for fnum = %d, directory %s\n",
1706 delete_on_close ? "Added" : "Removed", fsp->fnum, fsp->fsp_name ));
1707 } else if(fsp->stat_open) {
1709 DEBUG(10, ("set_delete_on_close_internal: %s delete on close flag for fnum = %d, stat open %s\n",
1710 delete_on_close ? "Added" : "Removed", fsp->fnum, fsp->fsp_name ));
1714 files_struct *iterate_fsp;
1717 * Modify the share mode entry for all files open
1718 * on this device and inode to tell other smbds we have
1719 * changed the delete on close flag. This will be noticed
1720 * in the close code, the last closer will delete the file
1724 DEBUG(10,("set_delete_on_close_internal: %s delete on close flag for fnum = %d, file %s\n",
1725 delete_on_close ? "Adding" : "Removing", fsp->fnum, fsp->fsp_name ));
1727 if (lock_share_entry_fsp(fsp) == False)
1728 return NT_STATUS_ACCESS_DENIED;
1730 if (!modify_delete_flag(fsp->dev, fsp->inode, delete_on_close)) {
1731 DEBUG(0,("set_delete_on_close_internal: failed to change delete on close flag for file %s\n",
1733 unlock_share_entry_fsp(fsp);
1734 return NT_STATUS_ACCESS_DENIED;
1741 unlock_share_entry_fsp(fsp);
1744 * Go through all files we have open on the same device and
1745 * inode (hanging off the same hash bucket) and set the DELETE_ON_CLOSE_FLAG.
1746 * Other smbd's that have this file open will look in the share_mode on close.
1747 * take care of this (rare) case in close_file(). See the comment there.
1748 * NB. JRA. We don't really need to do this anymore - all should be taken
1749 * care of in the share_mode changes in the tdb.
1752 for(iterate_fsp = file_find_di_first(fsp->dev, fsp->inode);
1753 iterate_fsp; iterate_fsp = file_find_di_next(iterate_fsp))
1754 fsp->delete_on_close = delete_on_close;
1757 * Set the delete on close flag in the fsp.
1759 fsp->delete_on_close = delete_on_close;
1761 DEBUG(10, ("set_delete_on_close_internal: %s delete on close flag for fnum = %d, file %s\n",
1762 delete_on_close ? "Added" : "Removed", fsp->fnum, fsp->fsp_name ));
1766 return NT_STATUS_OK;
1769 /****************************************************************************
1770 Reply to a TRANS2_SETFILEINFO (set file info by fileid).
1771 ****************************************************************************/
1773 static int call_trans2setfilepathinfo(connection_struct *conn,
1774 char *inbuf, char *outbuf, int length,
1775 int bufsize, char **pparams,
1776 char **ppdata, int total_data)
1778 char *params = *pparams;
1779 char *pdata = *ppdata;
1780 uint16 tran_call = SVAL(inbuf, smb_setup0);
1785 SMB_STRUCT_STAT sbuf;
1788 BOOL bad_path = False;
1789 files_struct *fsp = NULL;
1791 if (tran_call == TRANSACT2_SETFILEINFO) {
1792 fsp = file_fsp(params,0);
1793 info_level = SVAL(params,2);
1795 if(fsp && (fsp->is_directory || fsp->stat_open)) {
1797 * This is actually a SETFILEINFO on a directory
1798 * handle (returned from an NT SMB). NT5.0 seems
1799 * to do this call. JRA.
1801 pstrcpy(fname, fsp->fsp_name);
1802 unix_convert(fname,conn,0,&bad_path,&sbuf);
1803 if (!check_name(fname,conn) || (!VALID_STAT(sbuf))) {
1804 DEBUG(3,("fileinfo of %s failed (%s)\n",fname,strerror(errno)));
1805 if((errno == ENOENT) && bad_path) {
1806 unix_ERR_class = ERRDOS;
1807 unix_ERR_code = ERRbadpath;
1809 return(UNIXERROR(ERRDOS,ERRbadpath));
1811 } else if (fsp && fsp->print_file) {
1813 * Doing a DELETE_ON_CLOSE should cancel a print job.
1815 if ((info_level == SMB_SET_FILE_DISPOSITION_INFO) && CVAL(pdata,0)) {
1816 fsp->share_mode = FILE_DELETE_ON_CLOSE;
1818 DEBUG(3,("call_trans2setfilepathinfo: Cancelling print job (%s)\n", fsp->fsp_name ));
1821 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
1826 * Original code - this is an open file.
1828 CHECK_FSP(fsp,conn);
1830 pstrcpy(fname, fsp->fsp_name);
1833 if (vfs_fstat(fsp,fd,&sbuf) != 0) {
1834 DEBUG(3,("fstat of fnum %d failed (%s)\n",fsp->fnum, strerror(errno)));
1835 return(UNIXERROR(ERRDOS,ERRbadfid));
1840 info_level = SVAL(params,0);
1841 srvstr_pull(inbuf, fname, ¶ms[6], sizeof(fname), -1, STR_TERMINATE);
1842 unix_convert(fname,conn,0,&bad_path,&sbuf);
1843 if(!check_name(fname, conn)) {
1844 if((errno == ENOENT) && bad_path) {
1845 unix_ERR_class = ERRDOS;
1846 unix_ERR_code = ERRbadpath;
1848 return(UNIXERROR(ERRDOS,ERRbadpath));
1851 if(!VALID_STAT(sbuf)) {
1852 DEBUG(3,("stat of %s failed (%s)\n", fname, strerror(errno)));
1853 if((errno == ENOENT) && bad_path) {
1854 unix_ERR_class = ERRDOS;
1855 unix_ERR_code = ERRbadpath;
1857 return(UNIXERROR(ERRDOS,ERRbadpath));
1861 if (!CAN_WRITE(conn))
1862 return ERROR_DOS(ERRSRV,ERRaccess);
1864 DEBUG(3,("call_trans2setfilepathinfo(%d) %s info_level=%d totdata=%d\n",
1865 tran_call,fname,info_level,total_data));
1867 /* Realloc the parameter and data sizes */
1868 params = Realloc(*pparams,2);
1870 return ERROR_DOS(ERRDOS,ERRnomem);
1875 size = sbuf.st_size;
1876 tvs.modtime = sbuf.st_mtime;
1877 tvs.actime = sbuf.st_atime;
1878 mode = dos_mode(conn,fname,&sbuf);
1880 if (total_data > 4 && IVAL(pdata,0) == total_data) {
1881 /* uggh, EAs for OS2 */
1882 DEBUG(4,("Rejecting EA request with total_data=%d\n",total_data));
1883 return ERROR_DOS(ERRDOS,ERReasnotsupported);
1886 switch (info_level) {
1887 case SMB_INFO_STANDARD:
1888 case SMB_INFO_QUERY_EA_SIZE:
1891 tvs.actime = make_unix_date2(pdata+l1_fdateLastAccess);
1894 tvs.modtime = make_unix_date2(pdata+l1_fdateLastWrite);
1896 mode = SVAL(pdata,l1_attrFile);
1897 size = IVAL(pdata,l1_cbFile);
1901 /* XXXX um, i don't think this is right.
1902 it's also not in the cifs6.txt spec.
1904 case SMB_INFO_QUERY_EAS_FROM_LIST:
1905 tvs.actime = make_unix_date2(pdata+8);
1906 tvs.modtime = make_unix_date2(pdata+12);
1907 size = IVAL(pdata,16);
1908 mode = IVAL(pdata,24);
1911 /* XXXX nor this. not in cifs6.txt, either. */
1912 case SMB_INFO_QUERY_ALL_EAS:
1913 tvs.actime = make_unix_date2(pdata+8);
1914 tvs.modtime = make_unix_date2(pdata+12);
1915 size = IVAL(pdata,16);
1916 mode = IVAL(pdata,24);
1919 case SMB_SET_FILE_BASIC_INFO:
1920 case SMB_FILE_BASIC_INFORMATION:
1922 /* Patch to do this correctly from Paul Eggert <eggert@twinsun.com>. */
1924 time_t changed_time;
1926 /* Ignore create time at offset pdata. */
1929 tvs.actime = interpret_long_date(pdata+8);
1931 write_time = interpret_long_date(pdata+16);
1932 changed_time = interpret_long_date(pdata+24);
1934 tvs.modtime = MIN(write_time, changed_time);
1936 /* Prefer a defined time to an undefined one. */
1937 if (tvs.modtime == (time_t)0 || tvs.modtime == (time_t)-1)
1938 tvs.modtime = (write_time == (time_t)0 || write_time == (time_t)-1
1939 ? changed_time : write_time);
1942 mode = IVAL(pdata,32);
1946 case SMB_FILE_ALLOCATION_INFORMATION:
1947 case SMB_SET_FILE_ALLOCATION_INFO:
1950 SMB_OFF_T allocation_size = IVAL(pdata,0);
1951 #ifdef LARGE_SMB_OFF_T
1952 allocation_size |= (((SMB_OFF_T)IVAL(pdata,4)) << 32);
1953 #else /* LARGE_SMB_OFF_T */
1954 if (IVAL(pdata,4) != 0) /* more than 32 bits? */
1955 return ERROR_DOS(ERRDOS,ERRunknownlevel);
1956 #endif /* LARGE_SMB_OFF_T */
1957 DEBUG(10,("call_trans2setfilepathinfo: Set file allocation info for file %s to %.0f\n",
1958 fname, (double)allocation_size ));
1960 if(allocation_size != sbuf.st_size) {
1961 SMB_STRUCT_STAT new_sbuf;
1963 DEBUG(10,("call_trans2setfilepathinfo: file %s : setting new allocation size to %.0f\n",
1964 fname, (double)allocation_size ));
1967 files_struct *new_fsp = NULL;
1968 int access_mode = 0;
1971 if(global_oplock_break) {
1972 /* Queue this file modify as we are the process of an oplock break. */
1974 DEBUG(2,("call_trans2setfilepathinfo: queueing message due to being "));
1975 DEBUGADD(2,( "in oplock break state.\n"));
1977 push_oplock_pending_smb_message(inbuf, length);
1981 new_fsp = open_file_shared(conn, fname, &sbuf,
1982 SET_OPEN_MODE(DOS_OPEN_RDWR),
1983 (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN),
1984 0, 0, &access_mode, &action);
1986 if (new_fsp == NULL)
1987 return(UNIXERROR(ERRDOS,ERRbadpath));
1988 ret = vfs_allocate_file_space(new_fsp, allocation_size);
1989 if (vfs_fstat(new_fsp,new_fsp->fd,&new_sbuf) != 0) {
1990 DEBUG(3,("fstat of fnum %d failed (%s)\n",new_fsp->fnum, strerror(errno)));
1993 close_file(new_fsp,True);
1995 ret = vfs_allocate_file_space(fsp, size);
1996 if (vfs_fstat(fsp,fd,&new_sbuf) != 0) {
1997 DEBUG(3,("fstat of fnum %d failed (%s)\n",fsp->fnum, strerror(errno)));
2002 return ERROR_NT(NT_STATUS_DISK_FULL);
2004 /* Allocate can trucate size... */
2005 size = new_sbuf.st_size;
2011 case SMB_FILE_END_OF_FILE_INFORMATION:
2012 case SMB_SET_FILE_END_OF_FILE_INFO:
2014 size = IVAL(pdata,0);
2015 #ifdef LARGE_SMB_OFF_T
2016 size |= (((SMB_OFF_T)IVAL(pdata,4)) << 32);
2017 #else /* LARGE_SMB_OFF_T */
2018 if (IVAL(pdata,4) != 0) /* more than 32 bits? */
2019 return ERROR_DOS(ERRDOS,ERRunknownlevel);
2020 #endif /* LARGE_SMB_OFF_T */
2021 DEBUG(10,("call_trans2setfilepathinfo: Set end of file info for file %s to %.0f\n", fname, (double)size ));
2025 case SMB_FILE_DISPOSITION_INFORMATION:
2026 case SMB_SET_FILE_DISPOSITION_INFO: /* Set delete on close for open file. */
2028 BOOL delete_on_close = (CVAL(pdata,0) ? True : False);
2031 if (tran_call != TRANSACT2_SETFILEINFO)
2032 return ERROR_DOS(ERRDOS,ERRunknownlevel);
2035 return(UNIXERROR(ERRDOS,ERRbadfid));
2037 status = set_delete_on_close_internal(fsp, delete_on_close);
2039 if (NT_STATUS_V(status) != NT_STATUS_V(NT_STATUS_OK))
2040 return ERROR_NT(status);
2046 return ERROR_DOS(ERRDOS,ERRunknownlevel);
2049 /* get some defaults (no modifications) if any info is zero or -1. */
2050 if (tvs.actime == (time_t)0 || tvs.actime == (time_t)-1)
2051 tvs.actime = sbuf.st_atime;
2053 if (tvs.modtime == (time_t)0 || tvs.modtime == (time_t)-1)
2054 tvs.modtime = sbuf.st_mtime;
2056 DEBUG(6,("actime: %s " , ctime(&tvs.actime)));
2057 DEBUG(6,("modtime: %s ", ctime(&tvs.modtime)));
2058 DEBUG(6,("size: %.0f ", (double)size));
2059 DEBUG(6,("mode: %x\n" , mode));
2061 if(!((info_level == SMB_SET_FILE_END_OF_FILE_INFO) ||
2062 (info_level == SMB_SET_FILE_ALLOCATION_INFO) ||
2063 (info_level == SMB_FILE_ALLOCATION_INFORMATION) ||
2064 (info_level == SMB_FILE_END_OF_FILE_INFORMATION))) {
2067 * Only do this test if we are not explicitly
2068 * changing the size of a file.
2071 size = sbuf.st_size;
2075 * Try and set the times, size and mode of this file -
2076 * if they are different from the current values
2078 if (sbuf.st_mtime != tvs.modtime || sbuf.st_atime != tvs.actime) {
2081 * This was a setfileinfo on an open file.
2082 * NT does this a lot. It's actually pointless
2083 * setting the time here, as it will be overwritten
2084 * on the next write, so we save the request
2085 * away and will set it on file code. JRA.
2088 if (tvs.modtime != (time_t)0 && tvs.modtime != (time_t)-1) {
2089 DEBUG(10,("call_trans2setfilepathinfo: setting pending modtime to %s\n", ctime(&tvs.modtime) ));
2090 fsp->pending_modtime = tvs.modtime;
2095 DEBUG(10,("call_trans2setfilepathinfo: setting utimes to modified values.\n"));
2097 if(file_utime(conn, fname, &tvs)!=0)
2098 return(UNIXERROR(ERRDOS,ERRnoaccess));
2102 /* check the mode isn't different, before changing it */
2103 if ((mode != 0) && (mode != dos_mode(conn, fname, &sbuf))) {
2105 DEBUG(10,("call_trans2setfilepathinfo: file %s : setting dos mode %x\n", fname, mode ));
2107 if(file_chmod(conn, fname, mode, NULL)) {
2108 DEBUG(2,("chmod of %s failed (%s)\n", fname, strerror(errno)));
2109 return(UNIXERROR(ERRDOS,ERRnoaccess));
2113 if(size != sbuf.st_size) {
2115 DEBUG(10,("call_trans2setfilepathinfo: file %s : setting new size to %.0f\n",
2116 fname, (double)size ));
2119 files_struct *new_fsp = NULL;
2120 int access_mode = 0;
2123 if(global_oplock_break) {
2124 /* Queue this file modify as we are the process of an oplock break. */
2126 DEBUG(2,("call_trans2setfilepathinfo: queueing message due to being "));
2127 DEBUGADD(2,( "in oplock break state.\n"));
2129 push_oplock_pending_smb_message(inbuf, length);
2133 new_fsp = open_file_shared(conn, fname, &sbuf,
2134 SET_OPEN_MODE(DOS_OPEN_RDWR),
2135 (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN),
2136 0, 0, &access_mode, &action);
2138 if (new_fsp == NULL)
2139 return(UNIXERROR(ERRDOS,ERRbadpath));
2140 vfs_set_filelen(new_fsp, size);
2141 close_file(new_fsp,True);
2143 vfs_set_filelen(fsp, size);
2149 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
2154 /****************************************************************************
2155 Reply to a TRANS2_MKDIR (make directory with extended attributes).
2156 ****************************************************************************/
2158 static int call_trans2mkdir(connection_struct *conn,
2159 char *inbuf, char *outbuf, int length, int bufsize,
2160 char **pparams, char **ppdata)
2162 char *params = *pparams;
2165 SMB_STRUCT_STAT sbuf;
2166 BOOL bad_path = False;
2168 if (!CAN_WRITE(conn))
2169 return ERROR_DOS(ERRSRV,ERRaccess);
2171 srvstr_pull(inbuf, directory, ¶ms[4], sizeof(directory), -1, STR_TERMINATE);
2173 DEBUG(3,("call_trans2mkdir : name = %s\n", directory));
2175 unix_convert(directory,conn,0,&bad_path,&sbuf);
2176 if (check_name(directory,conn))
2177 ret = vfs_mkdir(conn,directory,unix_mode(conn,aDIR,directory));
2181 DEBUG(5,("call_trans2mkdir error (%s)\n", strerror(errno)));
2182 if((errno == ENOENT) && bad_path)
2184 unix_ERR_class = ERRDOS;
2185 unix_ERR_code = ERRbadpath;
2187 return(UNIXERROR(ERRDOS,ERRnoaccess));
2190 /* Realloc the parameter and data sizes */
2191 params = Realloc(*pparams,2);
2192 if(params == NULL) {
2193 return ERROR_DOS(ERRDOS,ERRnomem);
2199 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
2204 /****************************************************************************
2205 Reply to a TRANS2_FINDNOTIFYFIRST (start monitoring a directory for changes).
2206 We don't actually do this - we just send a null response.
2207 ****************************************************************************/
2209 static int call_trans2findnotifyfirst(connection_struct *conn,
2210 char *inbuf, char *outbuf,
2211 int length, int bufsize,
2212 char **pparams, char **ppdata)
2214 static uint16 fnf_handle = 257;
2215 char *params = *pparams;
2216 uint16 info_level = SVAL(params,4);
2218 DEBUG(3,("call_trans2findnotifyfirst - info_level %d\n", info_level));
2226 return ERROR_DOS(ERRDOS,ERRunknownlevel);
2229 /* Realloc the parameter and data sizes */
2230 params = Realloc(*pparams,6);
2231 if(params == NULL) {
2232 return ERROR_DOS(ERRDOS,ERRnomem);
2236 SSVAL(params,0,fnf_handle);
2237 SSVAL(params,2,0); /* No changes */
2238 SSVAL(params,4,0); /* No EA errors */
2245 send_trans2_replies(outbuf, bufsize, params, 6, *ppdata, 0);
2250 /****************************************************************************
2251 Reply to a TRANS2_FINDNOTIFYNEXT (continue monitoring a directory for
2252 changes). Currently this does nothing.
2253 ****************************************************************************/
2255 static int call_trans2findnotifynext(connection_struct *conn,
2256 char *inbuf, char *outbuf,
2257 int length, int bufsize,
2258 char **pparams, char **ppdata)
2260 char *params = *pparams;
2262 DEBUG(3,("call_trans2findnotifynext\n"));
2264 /* Realloc the parameter and data sizes */
2265 params = Realloc(*pparams,4);
2266 if(params == NULL) {
2267 return ERROR_DOS(ERRDOS,ERRnomem);
2271 SSVAL(params,0,0); /* No changes */
2272 SSVAL(params,2,0); /* No EA errors */
2274 send_trans2_replies(outbuf, bufsize, params, 4, *ppdata, 0);
2279 /****************************************************************************
2280 Reply to a TRANS2_GET_DFS_REFERRAL - Shirish Kalele <kalele@veritas.com>.
2281 ****************************************************************************/
2283 static int call_trans2getdfsreferral(connection_struct *conn, char* inbuf,
2284 char* outbuf, int length, int bufsize,
2285 char** pparams, char** ppdata)
2287 char *params = *pparams;
2290 int max_referral_level = SVAL(params,0);
2293 DEBUG(10,("call_trans2getdfsreferral\n"));
2295 if(!lp_host_msdfs())
2296 return ERROR_DOS(ERRDOS,ERRbadfunc);
2298 srvstr_pull(inbuf, pathname, ¶ms[2], sizeof(pathname), -1, STR_TERMINATE);
2300 if((reply_size = setup_dfs_referral(pathname,max_referral_level,ppdata)) < 0)
2301 return ERROR_DOS(ERRDOS,ERRbadfile);
2303 SSVAL(outbuf,smb_flg2,SVAL(outbuf,smb_flg2) | FLAGS2_DFS_PATHNAMES);
2304 send_trans2_replies(outbuf,bufsize,0,0,*ppdata,reply_size);
2309 #define LMCAT_SPL 0x53
2310 #define LMFUNC_GETJOBID 0x60
2312 /****************************************************************************
2313 Reply to a TRANS2_IOCTL - used for OS/2 printing.
2314 ****************************************************************************/
2316 static int call_trans2ioctl(connection_struct *conn, char* inbuf,
2317 char* outbuf, int length, int bufsize,
2318 char** pparams, char** ppdata)
2320 char *pdata = *ppdata;
2321 files_struct *fsp = file_fsp(inbuf,smb_vwv15);
2323 if ((SVAL(inbuf,(smb_setup+4)) == LMCAT_SPL) &&
2324 (SVAL(inbuf,(smb_setup+6)) == LMFUNC_GETJOBID)) {
2325 pdata = Realloc(*ppdata, 32);
2327 return ERROR_DOS(ERRDOS,ERRnomem);
2331 /* NOTE - THIS IS ASCII ONLY AT THE MOMENT - NOT SURE IF OS/2
2332 CAN ACCEPT THIS IN UNICODE. JRA. */
2334 SSVAL(pdata,0,fsp->print_jobid); /* Job number */
2335 srvstr_push( outbuf, pdata + 2, global_myname, 15, STR_ASCII|STR_TERMINATE); /* Our NetBIOS name */
2336 srvstr_push( outbuf, pdata+18, lp_servicename(SNUM(conn)), 13, STR_ASCII|STR_TERMINATE); /* Service name */
2337 send_trans2_replies(outbuf,bufsize,*pparams,0,*ppdata,32);
2340 DEBUG(2,("Unknown TRANS2_IOCTL\n"));
2341 return ERROR_DOS(ERRSRV,ERRerror);
2345 /****************************************************************************
2346 Reply to a SMBfindclose (stop trans2 directory search).
2347 ****************************************************************************/
2349 int reply_findclose(connection_struct *conn,
2350 char *inbuf,char *outbuf,int length,int bufsize)
2353 int dptr_num=SVALS(inbuf,smb_vwv0);
2354 START_PROFILE(SMBfindclose);
2356 DEBUG(3,("reply_findclose, dptr_num = %d\n", dptr_num));
2358 dptr_close(&dptr_num);
2360 outsize = set_message(outbuf,0,0,True);
2362 DEBUG(3,("SMBfindclose dptr_num = %d\n", dptr_num));
2364 END_PROFILE(SMBfindclose);
2368 /****************************************************************************
2369 Reply to a SMBfindnclose (stop FINDNOTIFYFIRST directory search).
2370 ****************************************************************************/
2372 int reply_findnclose(connection_struct *conn,
2373 char *inbuf,char *outbuf,int length,int bufsize)
2377 START_PROFILE(SMBfindnclose);
2379 dptr_num = SVAL(inbuf,smb_vwv0);
2381 DEBUG(3,("reply_findnclose, dptr_num = %d\n", dptr_num));
2383 /* We never give out valid handles for a
2384 findnotifyfirst - so any dptr_num is ok here.
2387 outsize = set_message(outbuf,0,0,True);
2389 DEBUG(3,("SMB_findnclose dptr_num = %d\n", dptr_num));
2391 END_PROFILE(SMBfindnclose);
2395 /****************************************************************************
2396 Reply to a SMBtranss2 - just ignore it!
2397 ****************************************************************************/
2399 int reply_transs2(connection_struct *conn,
2400 char *inbuf,char *outbuf,int length,int bufsize)
2402 START_PROFILE(SMBtranss2);
2403 DEBUG(4,("Ignoring transs2 of length %d\n",length));
2404 END_PROFILE(SMBtranss2);
2408 /****************************************************************************
2409 Reply to a SMBtrans2.
2410 ****************************************************************************/
2412 int reply_trans2(connection_struct *conn,
2413 char *inbuf,char *outbuf,int length,int bufsize)
2416 unsigned int total_params = SVAL(inbuf, smb_tpscnt);
2417 unsigned int total_data =SVAL(inbuf, smb_tdscnt);
2419 unsigned int max_param_reply = SVAL(inbuf, smb_mprcnt);
2420 unsigned int max_data_reply = SVAL(inbuf, smb_mdrcnt);
2421 unsigned int max_setup_fields = SVAL(inbuf, smb_msrcnt);
2422 BOOL close_tid = BITSETW(inbuf+smb_flags,0);
2423 BOOL no_final_response = BITSETW(inbuf+smb_flags,1);
2424 int32 timeout = IVALS(inbuf,smb_timeout);
2426 unsigned int suwcnt = SVAL(inbuf, smb_suwcnt);
2427 unsigned int tran_call = SVAL(inbuf, smb_setup0);
2428 char *params = NULL, *data = NULL;
2429 int num_params, num_params_sofar, num_data, num_data_sofar;
2430 START_PROFILE(SMBtrans2);
2432 if(global_oplock_break && (tran_call == TRANSACT2_OPEN)) {
2433 /* Queue this open message as we are the process of an
2436 DEBUG(2,("reply_trans2: queueing message trans2open due to being "));
2437 DEBUGADD(2,( "in oplock break state.\n"));
2439 push_oplock_pending_smb_message(inbuf, length);
2440 END_PROFILE(SMBtrans2);
2444 if (IS_IPC(conn) && (tran_call != TRANSACT2_OPEN)
2445 && (tran_call != TRANSACT2_GET_DFS_REFERRAL)) {
2446 END_PROFILE(SMBtrans2);
2447 return ERROR_DOS(ERRSRV,ERRaccess);
2450 outsize = set_message(outbuf,0,0,True);
2452 /* All trans2 messages we handle have smb_sucnt == 1 - ensure this
2453 is so as a sanity check */
2456 * Need to have rc=0 for ioctl to get job id for OS/2.
2457 * Network printing will fail if function is not successful.
2458 * Similar function in reply.c will be used if protocol
2459 * is LANMAN1.0 instead of LM1.2X002.
2460 * Until DosPrintSetJobInfo with PRJINFO3 is supported,
2461 * outbuf doesn't have to be set(only job id is used).
2463 if ( (suwcnt == 4) && (tran_call == TRANSACT2_IOCTL) &&
2464 (SVAL(inbuf,(smb_setup+4)) == LMCAT_SPL) &&
2465 (SVAL(inbuf,(smb_setup+6)) == LMFUNC_GETJOBID)) {
2466 DEBUG(2,("Got Trans2 DevIOctl jobid\n"));
2468 DEBUG(2,("Invalid smb_sucnt in trans2 call(%d)\n",suwcnt));
2469 DEBUG(2,("Transaction is %d\n",tran_call));
2470 END_PROFILE(SMBtrans2);
2471 return ERROR_DOS(ERRSRV,ERRerror);
2475 /* Allocate the space for the maximum needed parameters and data */
2476 if (total_params > 0)
2477 params = (char *)malloc(total_params);
2479 data = (char *)malloc(total_data);
2481 if ((total_params && !params) || (total_data && !data)) {
2482 DEBUG(2,("Out of memory in reply_trans2\n"));
2485 END_PROFILE(SMBtrans2);
2486 return ERROR_DOS(ERRDOS,ERRnomem);
2489 /* Copy the param and data bytes sent with this request into
2490 the params buffer */
2491 num_params = num_params_sofar = SVAL(inbuf,smb_pscnt);
2492 num_data = num_data_sofar = SVAL(inbuf, smb_dscnt);
2494 if (num_params > total_params || num_data > total_data)
2495 exit_server("invalid params in reply_trans2");
2498 memcpy( params, smb_base(inbuf) + SVAL(inbuf, smb_psoff), num_params);
2500 memcpy( data, smb_base(inbuf) + SVAL(inbuf, smb_dsoff), num_data);
2502 if(num_data_sofar < total_data || num_params_sofar < total_params) {
2503 /* We need to send an interim response then receive the rest
2504 of the parameter/data bytes */
2505 outsize = set_message(outbuf,0,0,True);
2506 if (!send_smb(smbd_server_fd(),outbuf))
2507 exit_server("reply_trans2: send_smb failed.");
2509 while (num_data_sofar < total_data ||
2510 num_params_sofar < total_params) {
2513 ret = receive_next_smb(inbuf,bufsize,SMB_SECONDARY_WAIT);
2516 (CVAL(inbuf, smb_com) != SMBtranss2)) || !ret) {
2517 outsize = set_message(outbuf,0,0,True);
2519 DEBUG(0,("reply_trans2: Invalid secondary trans2 packet\n"));
2521 DEBUG(0,("reply_trans2: %s in getting secondary trans2 response.\n",
2522 (smb_read_error == READ_ERROR) ? "error" : "timeout" ));
2525 END_PROFILE(SMBtrans2);
2526 return ERROR_DOS(ERRSRV,ERRerror);
2529 /* Revise total_params and total_data in case
2530 they have changed downwards */
2531 total_params = SVAL(inbuf, smb_tpscnt);
2532 total_data = SVAL(inbuf, smb_tdscnt);
2533 num_params_sofar += (num_params = SVAL(inbuf,smb_spscnt));
2534 num_data_sofar += ( num_data = SVAL(inbuf, smb_sdscnt));
2535 if (num_params_sofar > total_params || num_data_sofar > total_data)
2536 exit_server("data overflow in trans2");
2538 memcpy( ¶ms[ SVAL(inbuf, smb_spsdisp)],
2539 smb_base(inbuf) + SVAL(inbuf, smb_spsoff), num_params);
2540 memcpy( &data[SVAL(inbuf, smb_sdsdisp)],
2541 smb_base(inbuf)+ SVAL(inbuf, smb_sdsoff), num_data);
2545 if (Protocol >= PROTOCOL_NT1) {
2546 SSVAL(outbuf,smb_flg2,SVAL(outbuf,smb_flg2) | 0x40); /* IS_LONG_NAME */
2549 /* Now we must call the relevant TRANS2 function */
2551 case TRANSACT2_OPEN:
2552 START_PROFILE_NESTED(Trans2_open);
2553 outsize = call_trans2open(conn,
2554 inbuf, outbuf, bufsize,
2556 END_PROFILE_NESTED(Trans2_open);
2559 case TRANSACT2_FINDFIRST:
2560 START_PROFILE_NESTED(Trans2_findfirst);
2561 outsize = call_trans2findfirst(conn, inbuf, outbuf,
2562 bufsize, ¶ms, &data);
2563 END_PROFILE_NESTED(Trans2_findfirst);
2566 case TRANSACT2_FINDNEXT:
2567 START_PROFILE_NESTED(Trans2_findnext);
2568 outsize = call_trans2findnext(conn, inbuf, outbuf,
2571 END_PROFILE_NESTED(Trans2_findnext);
2574 case TRANSACT2_QFSINFO:
2575 START_PROFILE_NESTED(Trans2_qfsinfo);
2576 outsize = call_trans2qfsinfo(conn, inbuf, outbuf,
2577 length, bufsize, ¶ms,
2579 END_PROFILE_NESTED(Trans2_qfsinfo);
2582 case TRANSACT2_SETFSINFO:
2583 START_PROFILE_NESTED(Trans2_setfsinfo);
2584 outsize = call_trans2setfsinfo(conn, inbuf, outbuf,
2587 END_PROFILE_NESTED(Trans2_setfsinfo);
2590 case TRANSACT2_QPATHINFO:
2591 case TRANSACT2_QFILEINFO:
2592 START_PROFILE_NESTED(Trans2_qpathinfo);
2593 outsize = call_trans2qfilepathinfo(conn, inbuf, outbuf,
2595 ¶ms, &data, total_data);
2596 END_PROFILE_NESTED(Trans2_qpathinfo);
2598 case TRANSACT2_SETPATHINFO:
2599 case TRANSACT2_SETFILEINFO:
2600 START_PROFILE_NESTED(Trans2_setpathinfo);
2601 outsize = call_trans2setfilepathinfo(conn, inbuf, outbuf,
2605 END_PROFILE_NESTED(Trans2_setpathinfo);
2608 case TRANSACT2_FINDNOTIFYFIRST:
2609 START_PROFILE_NESTED(Trans2_findnotifyfirst);
2610 outsize = call_trans2findnotifyfirst(conn, inbuf, outbuf,
2613 END_PROFILE_NESTED(Trans2_findnotifyfirst);
2616 case TRANSACT2_FINDNOTIFYNEXT:
2617 START_PROFILE_NESTED(Trans2_findnotifynext);
2618 outsize = call_trans2findnotifynext(conn, inbuf, outbuf,
2621 END_PROFILE_NESTED(Trans2_findnotifynext);
2623 case TRANSACT2_MKDIR:
2624 START_PROFILE_NESTED(Trans2_mkdir);
2625 outsize = call_trans2mkdir(conn, inbuf, outbuf, length,
2626 bufsize, ¶ms, &data);
2627 END_PROFILE_NESTED(Trans2_mkdir);
2630 case TRANSACT2_GET_DFS_REFERRAL:
2631 START_PROFILE_NESTED(Trans2_get_dfs_referral);
2632 outsize = call_trans2getdfsreferral(conn,inbuf,outbuf,length,
2633 bufsize, ¶ms, &data);
2634 END_PROFILE_NESTED(Trans2_get_dfs_referral);
2636 case TRANSACT2_IOCTL:
2637 START_PROFILE_NESTED(Trans2_ioctl);
2638 outsize = call_trans2ioctl(conn,inbuf,outbuf,length,
2639 bufsize,¶ms,&data);
2640 END_PROFILE_NESTED(Trans2_ioctl);
2643 /* Error in request */
2644 DEBUG(2,("Unknown request %d in trans2 call\n", tran_call));
2647 END_PROFILE(SMBtrans2);
2648 return ERROR_DOS(ERRSRV,ERRerror);
2651 /* As we do not know how many data packets will need to be
2652 returned here the various call_trans2xxxx calls
2653 must send their own. Thus a call_trans2xxx routine only
2654 returns a value other than -1 when it wants to send
2660 END_PROFILE(SMBtrans2);
2661 return outsize; /* If a correct response was needed the
2662 call_trans2xxx calls have already sent
2663 it. If outsize != -1 then it is returning */