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 int DEBUGLEVEL;
29 extern files_struct Files[];
30 extern BOOL case_sensitive;
32 extern int oplock_sock;
33 extern int smb_read_error;
34 extern fstring local_machine;
35 extern int global_oplock_break;
37 /****************************************************************************
38 Send the required number of replies back.
39 We assume all fields other than the data fields are
40 set correctly for the type of call.
41 HACK ! Always assumes smb_setup field is zero.
42 ****************************************************************************/
43 static int send_trans2_replies(char *outbuf, int bufsize, char *params,
44 int paramsize, char *pdata, int datasize)
46 /* As we are using a protocol > LANMAN1 then the max_send
47 variable must have been set in the sessetupX call.
48 This takes precedence over the max_xmit field in the
49 global struct. These different max_xmit variables should
50 be merged as this is now too confusing */
53 int data_to_send = datasize;
54 int params_to_send = paramsize;
58 int params_sent_thistime, data_sent_thistime, total_sent_thistime;
59 int alignment_offset = 3;
60 int data_alignment_offset = 0;
62 /* Initially set the wcnt area to be 10 - this is true for all
64 set_message(outbuf,10,0,True);
66 /* If there genuinely are no parameters or data to send just send
68 if(params_to_send == 0 && data_to_send == 0)
70 send_smb(Client,outbuf);
74 /* When sending params and data ensure that both are nicely aligned */
75 /* Only do this alignment when there is also data to send - else
76 can cause NT redirector problems. */
77 if (((params_to_send % 4) != 0) && (data_to_send != 0))
78 data_alignment_offset = 4 - (params_to_send % 4);
80 /* Space is bufsize minus Netbios over TCP header minus SMB header */
81 /* The alignment_offset is to align the param bytes on an even byte
82 boundary. NT 4.0 Beta needs this to work correctly. */
83 useable_space = bufsize - ((smb_buf(outbuf)+
84 alignment_offset+data_alignment_offset) -
87 /* useable_space can never be more than max_send minus the
89 useable_space = MIN(useable_space,
90 max_send - (alignment_offset+data_alignment_offset));
93 while (params_to_send || data_to_send)
95 /* Calculate whether we will totally or partially fill this packet */
96 total_sent_thistime = params_to_send + data_to_send +
97 alignment_offset + data_alignment_offset;
98 /* We can never send more than useable_space */
99 total_sent_thistime = MIN(total_sent_thistime, useable_space);
101 set_message(outbuf, 10, total_sent_thistime, True);
103 /* Set total params and data to be sent */
104 SSVAL(outbuf,smb_tprcnt,paramsize);
105 SSVAL(outbuf,smb_tdrcnt,datasize);
107 /* Calculate how many parameters and data we can fit into
108 this packet. Parameters get precedence */
110 params_sent_thistime = MIN(params_to_send,useable_space);
111 data_sent_thistime = useable_space - params_sent_thistime;
112 data_sent_thistime = MIN(data_sent_thistime,data_to_send);
114 SSVAL(outbuf,smb_prcnt, params_sent_thistime);
115 if(params_sent_thistime == 0)
117 SSVAL(outbuf,smb_proff,0);
118 SSVAL(outbuf,smb_prdisp,0);
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 */
126 SSVAL(outbuf,smb_proff,((smb_buf(outbuf)+alignment_offset) - smb_base(outbuf)));
127 /* Absolute displacement of param bytes sent in this packet */
128 SSVAL(outbuf,smb_prdisp,pp - params);
131 SSVAL(outbuf,smb_drcnt, data_sent_thistime);
132 if(data_sent_thistime == 0)
134 SSVAL(outbuf,smb_droff,0);
135 SSVAL(outbuf,smb_drdisp, 0);
139 /* The offset of the data bytes is the offset of the
140 parameter bytes plus the number of parameters being sent this time */
141 SSVAL(outbuf,smb_droff,((smb_buf(outbuf)+alignment_offset) -
142 smb_base(outbuf)) + params_sent_thistime + data_alignment_offset);
143 SSVAL(outbuf,smb_drdisp, pd - pdata);
146 /* Copy the param bytes into the packet */
147 if(params_sent_thistime)
148 memcpy((smb_buf(outbuf)+alignment_offset),pp,params_sent_thistime);
149 /* Copy in the data bytes */
150 if(data_sent_thistime)
151 memcpy(smb_buf(outbuf)+alignment_offset+params_sent_thistime+
152 data_alignment_offset,pd,data_sent_thistime);
154 DEBUG(9,("t2_rep: params_sent_thistime = %d, data_sent_thistime = %d, useable_space = %d\n",
155 params_sent_thistime, data_sent_thistime, useable_space));
156 DEBUG(9,("t2_rep: params_to_send = %d, data_to_send = %d, paramsize = %d, datasize = %d\n",
157 params_to_send, data_to_send, paramsize, datasize));
159 /* Send the packet */
160 send_smb(Client,outbuf);
162 pp += params_sent_thistime;
163 pd += data_sent_thistime;
165 params_to_send -= params_sent_thistime;
166 data_to_send -= data_sent_thistime;
169 if(params_to_send < 0 || data_to_send < 0)
171 DEBUG(0,("send_trans2_replies failed sanity check pts = %d, dts = %d\n!!!",
172 params_to_send, data_to_send));
181 /****************************************************************************
182 reply to a TRANSACT2_OPEN
183 ****************************************************************************/
184 static int call_trans2open(connection_struct *conn, char *inbuf, char *outbuf,
186 char **pparams, char **ppdata)
188 char *params = *pparams;
189 int16 open_mode = SVAL(params, 2);
190 int16 open_attr = SVAL(params,6);
191 BOOL oplock_request = (((SVAL(params,0)|(1<<1))>>1) | ((SVAL(params,0)|(1<<2))>>1));
193 BOOL return_additional_info = BITSETW(params,0);
194 int16 open_sattr = SVAL(params, 4);
195 time_t open_time = make_unix_date3(params+8);
197 int16 open_ofun = SVAL(params,12);
198 int32 open_size = IVAL(params,14);
199 char *pname = ¶ms[28];
200 int16 namelen = strlen(pname)+1;
205 int size=0,fmode=0,mtime=0,rmode;
209 BOOL bad_path = False;
212 StrnCpy(fname,pname,namelen);
214 DEBUG(3,("trans2open %s mode=%d attr=%d ofun=%d size=%d\n",
215 fname,open_mode, open_attr, open_ofun, open_size));
217 /* XXXX we need to handle passed times, sattr and flags */
219 unix_convert(fname,conn,0,&bad_path);
221 fnum = find_free_file();
223 return(ERROR(ERRSRV,ERRnofids));
227 if (!check_name(fname,conn))
229 if((errno == ENOENT) && bad_path)
231 unix_ERR_class = ERRDOS;
232 unix_ERR_code = ERRbadpath;
234 fsp->reserved = False;
235 return(UNIXERROR(ERRDOS,ERRnoaccess));
238 unixmode = unix_mode(conn,open_attr | aARCH);
240 open_file_shared(fnum,conn,fname,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 fsp->reserved = False;
251 return(UNIXERROR(ERRDOS,ERRnoaccess));
254 if (fstat(fsp->fd_ptr->fd,&sbuf) != 0) {
255 close_file(fnum,False);
256 return(ERROR(ERRDOS,ERRnoaccess));
260 fmode = dos_mode(conn,fname,&sbuf);
261 mtime = sbuf.st_mtime;
264 close_file(fnum,False);
265 return(ERROR(ERRDOS,ERRnoaccess));
268 /* Realloc the size of parameters and data we will return */
269 params = *pparams = Realloc(*pparams, 28);
271 return(ERROR(ERRDOS,ERRnomem));
274 SSVAL(params,0,fnum);
275 SSVAL(params,2,fmode);
276 put_dos_date2(params,4, mtime);
277 SIVAL(params,8, size);
278 SSVAL(params,12,rmode);
280 if (oplock_request && lp_fake_oplocks(SNUM(conn))) {
281 smb_action |= EXTENDED_OPLOCK_GRANTED;
284 SSVAL(params,18,smb_action);
285 SIVAL(params,20,inode);
287 /* Send the required number of replies */
288 send_trans2_replies(outbuf, bufsize, params, 28, *ppdata, 0);
293 /****************************************************************************
294 get a level dependent lanman2 dir entry.
295 ****************************************************************************/
296 static int get_lanman2_dir_entry(connection_struct *conn,
297 char *path_mask,int dirtype,int info_level,
298 int requires_resume_key,
299 BOOL dont_descend,char **ppdata,
300 char *base_data, int space_remaining,
311 char *p, *pdata = *ppdata;
316 uint32 mdate=0, adate=0, cdate=0;
318 BOOL isrootdir = (strequal(conn->dirpath,"./") ||
319 strequal(conn->dirpath,".") ||
320 strequal(conn->dirpath,"/"));
322 int nt_extmode; /* Used for NT connections instead of mode */
323 BOOL needslash = ( conn->dirpath[strlen(conn->dirpath) -1] != '/');
326 *out_of_space = False;
331 p = strrchr(path_mask,'/');
340 pstrcpy(mask, path_mask);
344 /* Needed if we run out of space */
345 prev_dirpos = TellDir(conn->dirptr);
346 dname = ReadDirName(conn->dirptr);
349 * Due to bugs in NT client redirectors we are not using
350 * resume keys any more - set them to zero.
351 * Check out the related comments in findfirst/findnext.
357 DEBUG(8,("get_lanman2_dir_entry:readdir on dirptr 0x%x now at offset %d\n",
358 (unsigned)conn->dirptr,TellDir(conn->dirptr)));
365 pstrcpy(fname,dname);
367 if(mask_match(fname, mask, case_sensitive, True))
369 BOOL isdots = (strequal(fname,"..") || strequal(fname,"."));
370 if (dont_descend && !isdots)
373 if (isrootdir && isdots)
376 pstrcpy(pathreal,conn->dirpath);
378 pstrcat(pathreal,"/");
379 pstrcat(pathreal,dname);
380 if (sys_stat(pathreal,&sbuf) != 0)
382 DEBUG(5,("get_lanman2_dir_entry:Couldn't stat [%s] (%s)\n",pathreal,strerror(errno)));
386 mode = dos_mode(conn,pathreal,&sbuf);
388 if (!dir_check_ftype(conn,mode,&sbuf,dirtype)) {
389 DEBUG(5,("[%s] attribs didn't match %x\n",fname,dirtype));
394 mdate = sbuf.st_mtime;
395 adate = sbuf.st_atime;
396 cdate = get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(conn)));
400 DEBUG(5,("get_lanman2_dir_entry found %s fname=%s\n",pathreal,fname));
406 name_map_mangle(fname,False,SNUM(conn));
411 nt_extmode = mode ? mode : FILE_ATTRIBUTE_NORMAL;
416 if(requires_resume_key) {
420 put_dos_date2(p,l1_fdateCreation,cdate);
421 put_dos_date2(p,l1_fdateLastAccess,adate);
422 put_dos_date2(p,l1_fdateLastWrite,mdate);
423 SIVAL(p,l1_cbFile,size);
424 SIVAL(p,l1_cbFileAlloc,ROUNDUP(size,1024));
425 SSVAL(p,l1_attrFile,mode);
426 SCVAL(p,l1_cchName,strlen(fname));
427 pstrcpy(p + l1_achName, fname);
428 nameptr = p + l1_achName;
429 p += l1_achName + strlen(fname) + 1;
434 if(requires_resume_key) {
438 put_dos_date2(p,l2_fdateCreation,cdate);
439 put_dos_date2(p,l2_fdateLastAccess,adate);
440 put_dos_date2(p,l2_fdateLastWrite,mdate);
441 SIVAL(p,l2_cbFile,size);
442 SIVAL(p,l2_cbFileAlloc,ROUNDUP(size,1024));
443 SSVAL(p,l2_attrFile,mode);
444 SIVAL(p,l2_cbList,0); /* No extended attributes */
445 SCVAL(p,l2_cchName,strlen(fname));
446 pstrcpy(p + l2_achName, fname);
447 nameptr = p + l2_achName;
448 p += l2_achName + strlen(fname) + 1;
453 put_dos_date2(p,4,cdate);
454 put_dos_date2(p,8,adate);
455 put_dos_date2(p,12,mdate);
457 SIVAL(p,20,ROUNDUP(size,1024));
460 CVAL(p,30) = strlen(fname);
461 pstrcpy(p+31, fname);
463 p += 31 + strlen(fname) + 1;
467 if(requires_resume_key) {
471 SIVAL(p,0,33+strlen(fname)+1);
472 put_dos_date2(p,4,cdate);
473 put_dos_date2(p,8,adate);
474 put_dos_date2(p,12,mdate);
476 SIVAL(p,20,ROUNDUP(size,1024));
478 CVAL(p,32) = strlen(fname);
479 pstrcpy(p + 33, fname);
481 p += 33 + strlen(fname) + 1;
484 case SMB_FIND_FILE_BOTH_DIRECTORY_INFO:
485 was_8_3 = is_8_3(fname, True);
486 len = 94+strlen(fname);
487 len = (len + 3) & ~3;
488 SIVAL(p,0,len); p += 4;
489 SIVAL(p,0,reskey); p += 4;
490 put_long_date(p,cdate); p += 8;
491 put_long_date(p,adate); p += 8;
492 put_long_date(p,mdate); p += 8;
493 put_long_date(p,mdate); p += 8;
494 SIVAL(p,0,size); p += 8;
495 SIVAL(p,0,size); p += 8;
496 SIVAL(p,0,nt_extmode); p += 4;
497 SIVAL(p,0,strlen(fname)); p += 4;
498 SIVAL(p,0,0); p += 4;
501 if (!name_map_mangle(p+2,True,SNUM(conn)))
506 SSVAL(p,0,strlen(p+2));
509 pstrcpy(p,fname); p += strlen(p);
513 case SMB_FIND_FILE_DIRECTORY_INFO:
514 len = 64+strlen(fname);
515 len = (len + 3) & ~3;
516 SIVAL(p,0,len); p += 4;
517 SIVAL(p,0,reskey); p += 4;
518 put_long_date(p,cdate); p += 8;
519 put_long_date(p,adate); p += 8;
520 put_long_date(p,mdate); p += 8;
521 put_long_date(p,mdate); p += 8;
522 SIVAL(p,0,size); p += 8;
523 SIVAL(p,0,size); p += 8;
524 SIVAL(p,0,nt_extmode); p += 4;
525 SIVAL(p,0,strlen(fname)); p += 4;
531 case SMB_FIND_FILE_FULL_DIRECTORY_INFO:
532 len = 68+strlen(fname);
533 len = (len + 3) & ~3;
534 SIVAL(p,0,len); p += 4;
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;
540 SIVAL(p,0,size); p += 8;
541 SIVAL(p,0,size); p += 8;
542 SIVAL(p,0,nt_extmode); p += 4;
543 SIVAL(p,0,strlen(fname)); p += 4;
544 SIVAL(p,0,0); p += 4;
549 case SMB_FIND_FILE_NAMES_INFO:
550 len = 12+strlen(fname);
551 len = (len + 3) & ~3;
552 SIVAL(p,0,len); p += 4;
553 SIVAL(p,0,reskey); p += 4;
554 SIVAL(p,0,strlen(fname)); p += 4;
564 if (PTR_DIFF(p,pdata) > space_remaining) {
565 /* Move the dirptr back to prev_dirpos */
566 SeekDir(conn->dirptr, prev_dirpos);
567 *out_of_space = True;
568 DEBUG(9,("get_lanman2_dir_entry: out of space\n"));
569 return False; /* Not finished - just out of space */
572 /* Setup the last_filename pointer, as an offset from base_data */
573 *last_name_off = PTR_DIFF(nameptr,base_data);
574 /* Advance the data pointer to the next slot */
579 /****************************************************************************
580 Convert the directory masks formated for the wire.
581 ****************************************************************************/
583 void mask_convert( char *mask)
586 * We know mask is a pstring.
592 if(p[1] != '"' && p[1] != '.') {
593 pstrcpy( expnd, p+1 );
596 safe_strcpy( p+1, expnd, sizeof(pstring) - (p - mask) - 2);
600 if (*p == '>') *p = '?';
601 if (*p == '"') *p = '.';
606 /****************************************************************************
607 reply to a TRANS2_FINDFIRST
608 ****************************************************************************/
609 static int call_trans2findfirst(connection_struct *conn,
610 char *inbuf, char *outbuf, int bufsize,
611 char **pparams, char **ppdata)
613 /* We must be careful here that we don't return more than the
614 allowed number of data bytes. If this means returning fewer than
615 maxentries then so be it. We assume that the redirector has
616 enough room for the fixed number of parameter bytes it has
618 uint32 max_data_bytes = SVAL(inbuf, smb_mdrcnt);
619 char *params = *pparams;
620 char *pdata = *ppdata;
621 int dirtype = SVAL(params,0);
622 int maxentries = SVAL(params,2);
623 BOOL close_after_first = BITSETW(params+4,0);
624 BOOL close_if_end = BITSETW(params+4,1);
625 BOOL requires_resume_key = BITSETW(params+4,2);
626 int info_level = SVAL(params,6);
634 BOOL finished = False;
635 BOOL dont_descend = False;
636 BOOL out_of_space = False;
638 BOOL bad_path = False;
640 *directory = *mask = 0;
642 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",
643 dirtype, maxentries, close_after_first, close_if_end, requires_resume_key,
644 info_level, max_data_bytes));
652 case SMB_FIND_FILE_DIRECTORY_INFO:
653 case SMB_FIND_FILE_FULL_DIRECTORY_INFO:
654 case SMB_FIND_FILE_NAMES_INFO:
655 case SMB_FIND_FILE_BOTH_DIRECTORY_INFO:
658 return(ERROR(ERRDOS,ERRunknownlevel));
661 pstrcpy(directory, params + 12); /* Complete directory path with
662 wildcard mask appended */
664 DEBUG(5,("path=%s\n",directory));
666 unix_convert(directory,conn,0,&bad_path);
667 if(!check_name(directory,conn)) {
668 if((errno == ENOENT) && bad_path)
670 unix_ERR_class = ERRDOS;
671 unix_ERR_code = ERRbadpath;
675 /* Ugly - NT specific hack - maybe not needed ? (JRA) */
676 if((errno == ENOTDIR) && (Protocol >= PROTOCOL_NT1) &&
677 (get_remote_arch() == RA_WINNT))
679 unix_ERR_class = ERRDOS;
680 unix_ERR_code = ERRbaddirectory;
684 return(ERROR(ERRDOS,ERRbadpath));
687 p = strrchr(directory,'/');
689 pstrcpy(mask,directory);
690 pstrcpy(directory,"./");
696 DEBUG(5,("dir=%s, mask = %s\n",directory, mask));
698 pdata = *ppdata = Realloc(*ppdata, max_data_bytes + 1024);
700 return(ERROR(ERRDOS,ERRnomem));
701 bzero(pdata,max_data_bytes);
703 /* Realloc the params space */
704 params = *pparams = Realloc(*pparams, 10);
706 return(ERROR(ERRDOS,ERRnomem));
708 dptr_num = dptr_create(conn,directory, True ,SVAL(inbuf,smb_pid));
710 return(ERROR(ERRDOS,ERRbadfile));
712 /* Convert the formatted mask. */
717 * Now we have a working mask_match in util.c, I believe
718 * we no longer need these hacks (in fact they break
722 /* a special case for 16 bit apps */
723 if (strequal(mask,"????????.???")) pstrcpy(mask,"*");
725 /* handle broken clients that send us old 8.3 format */
726 string_sub(mask,"????????","*");
727 string_sub(mask,".???",".*");
730 /* Save the wildcard match and attribs we are using on this directory -
731 needed as lanman2 assumes these are being saved between calls */
733 if(!(wcard = strdup(mask))) {
734 dptr_close(dptr_num);
735 return(ERROR(ERRDOS,ERRnomem));
738 dptr_set_wcard(dptr_num, wcard);
739 dptr_set_attr(dptr_num, dirtype);
741 DEBUG(4,("dptr_num is %d, wcard = %s, attr = %d\n",dptr_num, wcard, dirtype));
743 /* We don't need to check for VOL here as this is returned by
744 a different TRANS2 call. */
746 DEBUG(8,("dirpath=<%s> dontdescend=<%s>\n",
747 conn->dirpath,lp_dontdescend(SNUM(conn))));
748 if (in_list(conn->dirpath,lp_dontdescend(SNUM(conn)),case_sensitive))
752 space_remaining = max_data_bytes;
753 out_of_space = False;
755 for (i=0;(i<maxentries) && !finished && !out_of_space;i++)
758 /* this is a heuristic to avoid seeking the dirptr except when
759 absolutely necessary. It allows for a filename of about 40 chars */
760 if (space_remaining < DIRLEN_GUESS && numentries > 0)
768 !get_lanman2_dir_entry(conn,mask,dirtype,info_level,
769 requires_resume_key,dont_descend,
770 &p,pdata,space_remaining, &out_of_space,
774 if (finished && out_of_space)
777 if (!finished && !out_of_space)
779 space_remaining = max_data_bytes - PTR_DIFF(p,pdata);
782 /* Check if we can close the dirptr */
783 if(close_after_first || (finished && close_if_end))
785 dptr_close(dptr_num);
786 DEBUG(5,("call_trans2findfirst - (2) closing dptr_num %d\n", dptr_num));
791 * If there are no matching entries we must return ERRDOS/ERRbadfile -
792 * from observation of NT.
796 return(ERROR(ERRDOS,ERRbadfile));
798 /* At this point pdata points to numentries directory entries. */
800 /* Set up the return parameter block */
801 SSVAL(params,0,dptr_num);
802 SSVAL(params,2,numentries);
803 SSVAL(params,4,finished);
804 SSVAL(params,6,0); /* Never an EA error */
805 SSVAL(params,8,last_name_off);
807 send_trans2_replies( outbuf, bufsize, params, 10, pdata, PTR_DIFF(p,pdata));
809 if ((! *directory) && dptr_path(dptr_num))
810 slprintf(directory,sizeof(directory)-1, "(%s)",dptr_path(dptr_num));
812 DEBUG( 4, ( "%s mask=%s directory=%s dirtype=%d numentries=%d\n",
813 smb_fn_name(CVAL(inbuf,smb_com)),
814 mask, directory, dirtype, numentries ) );
820 /****************************************************************************
821 reply to a TRANS2_FINDNEXT
822 ****************************************************************************/
823 static int call_trans2findnext(connection_struct *conn,
824 char *inbuf, char *outbuf,
825 int length, int bufsize,
826 char **pparams, char **ppdata)
828 /* We must be careful here that we don't return more than the
829 allowed number of data bytes. If this means returning fewer than
830 maxentries then so be it. We assume that the redirector has
831 enough room for the fixed number of parameter bytes it has
833 int max_data_bytes = SVAL(inbuf, smb_mdrcnt);
834 char *params = *pparams;
835 char *pdata = *ppdata;
836 int16 dptr_num = SVAL(params,0);
837 int maxentries = SVAL(params,2);
838 uint16 info_level = SVAL(params,4);
839 uint32 resume_key = IVAL(params,6);
840 BOOL close_after_request = BITSETW(params+10,0);
841 BOOL close_if_end = BITSETW(params+10,1);
842 BOOL requires_resume_key = BITSETW(params+10,2);
843 BOOL continue_bit = BITSETW(params+10,3);
850 int i, last_name_off=0;
851 BOOL finished = False;
852 BOOL dont_descend = False;
853 BOOL out_of_space = False;
856 *mask = *directory = *resume_name = 0;
858 pstrcpy( resume_name, params+12);
860 DEBUG(3,("call_trans2findnext: dirhandle = %d, max_data_bytes = %d, maxentries = %d, \
861 close_after_request=%d, close_if_end = %d requires_resume_key = %d \
862 resume_key = %d resume name = %s continue=%d level = %d\n",
863 dptr_num, max_data_bytes, maxentries, close_after_request, close_if_end,
864 requires_resume_key, resume_key, resume_name, continue_bit, info_level));
872 case SMB_FIND_FILE_DIRECTORY_INFO:
873 case SMB_FIND_FILE_FULL_DIRECTORY_INFO:
874 case SMB_FIND_FILE_NAMES_INFO:
875 case SMB_FIND_FILE_BOTH_DIRECTORY_INFO:
878 return(ERROR(ERRDOS,ERRunknownlevel));
881 pdata = *ppdata = Realloc( *ppdata, max_data_bytes + 1024);
883 return(ERROR(ERRDOS,ERRnomem));
884 bzero(pdata,max_data_bytes);
886 /* Realloc the params space */
887 params = *pparams = Realloc(*pparams, 6*SIZEOFWORD);
889 return(ERROR(ERRDOS,ERRnomem));
891 /* Check that the dptr is valid */
892 if(!(conn->dirptr = dptr_fetch_lanman2(dptr_num)))
893 return(ERROR(ERRDOS,ERRnofiles));
895 string_set(&conn->dirpath,dptr_path(dptr_num));
897 /* Get the wildcard mask from the dptr */
898 if((p = dptr_wcard(dptr_num))== NULL) {
899 DEBUG(2,("dptr_num %d has no wildcard\n", dptr_num));
900 return (ERROR(ERRDOS,ERRnofiles));
903 pstrcpy(directory,conn->dirpath);
905 /* Get the attr mask from the dptr */
906 dirtype = dptr_attr(dptr_num);
908 DEBUG(3,("dptr_num is %d, mask = %s, attr = %x, dirptr=(0x%X,%d)\n",
909 dptr_num, mask, dirtype,
910 (unsigned)conn->dirptr,
911 TellDir(conn->dirptr)));
913 /* We don't need to check for VOL here as this is returned by
914 a different TRANS2 call. */
916 DEBUG(8,("dirpath=<%s> dontdescend=<%s>\n",conn->dirpath,lp_dontdescend(SNUM(conn))));
917 if (in_list(conn->dirpath,lp_dontdescend(SNUM(conn)),case_sensitive))
921 space_remaining = max_data_bytes;
922 out_of_space = False;
925 * Seek to the correct position. We no longer use the resume key but
926 * depend on the last file name instead.
928 if(requires_resume_key && *resume_name && !continue_bit)
931 * Fix for NT redirector problem triggered by resume key indexes
932 * changing between directory scans. We now return a resume key of 0
933 * and instead look for the filename to continue from (also given
934 * to us by NT/95/smbfs/smbclient). If no other scans have been done between the
935 * findfirst/findnext (as is usual) then the directory pointer
936 * should already be at the correct place. Check this by scanning
937 * backwards looking for an exact (ie. case sensitive) filename match.
938 * If we get to the beginning of the directory and haven't found it then scan
939 * forwards again looking for a match. JRA.
942 int current_pos, start_pos;
944 void *dirptr = conn->dirptr;
945 start_pos = TellDir(dirptr);
946 for(current_pos = start_pos; current_pos >= 0; current_pos--)
948 DEBUG(7,("call_trans2findnext: seeking to pos %d\n", current_pos));
950 SeekDir(dirptr, current_pos);
951 dname = ReadDirName(dirptr);
954 * Remember, name_map_mangle is called by
955 * get_lanman2_dir_entry(), so the resume name
956 * could be mangled. Ensure we do the same
961 name_map_mangle( dname, False, SNUM(conn));
963 if(dname && strcsequal( resume_name, dname))
965 SeekDir(dirptr, current_pos+1);
966 DEBUG(7,("call_trans2findnext: got match at pos %d\n", current_pos+1 ));
972 * Scan forward from start if not found going backwards.
977 DEBUG(7,("call_trans2findnext: notfound: seeking to pos %d\n", start_pos));
978 SeekDir(dirptr, start_pos);
979 for(current_pos = start_pos; (dname = ReadDirName(dirptr)) != NULL; SeekDir(dirptr,++current_pos))
982 * Remember, name_map_mangle is called by
983 * get_lanman2_dir_entry(), so the resume name
984 * could be mangled. Ensure we do the same
989 name_map_mangle( dname, False, SNUM(conn));
991 if(dname && strcsequal( resume_name, dname))
993 SeekDir(dirptr, current_pos+1);
994 DEBUG(7,("call_trans2findnext: got match at pos %d\n", current_pos+1 ));
998 } /* end if current_pos */
999 } /* end if requires_resume_key && !continue_bit */
1001 for (i=0;(i<(int)maxentries) && !finished && !out_of_space ;i++)
1003 /* this is a heuristic to avoid seeking the dirptr except when
1004 absolutely necessary. It allows for a filename of about 40 chars */
1005 if (space_remaining < DIRLEN_GUESS && numentries > 0)
1007 out_of_space = True;
1013 !get_lanman2_dir_entry(conn,mask,dirtype,info_level,
1014 requires_resume_key,dont_descend,
1015 &p,pdata,space_remaining, &out_of_space,
1019 if (finished && out_of_space)
1022 if (!finished && !out_of_space)
1024 space_remaining = max_data_bytes - PTR_DIFF(p,pdata);
1027 /* Check if we can close the dirptr */
1028 if(close_after_request || (finished && close_if_end))
1030 dptr_close(dptr_num); /* This frees up the saved mask */
1031 DEBUG(5,("call_trans2findnext: closing dptr_num = %d\n", dptr_num));
1036 /* Set up the return parameter block */
1037 SSVAL(params,0,numentries);
1038 SSVAL(params,2,finished);
1039 SSVAL(params,4,0); /* Never an EA error */
1040 SSVAL(params,6,last_name_off);
1042 send_trans2_replies( outbuf, bufsize, params, 8, pdata, PTR_DIFF(p,pdata));
1044 if ((! *directory) && dptr_path(dptr_num))
1045 slprintf(directory,sizeof(directory)-1, "(%s)",dptr_path(dptr_num));
1047 DEBUG( 3, ( "%s mask=%s directory=%s dirtype=%d numentries=%d\n",
1048 smb_fn_name(CVAL(inbuf,smb_com)),
1049 mask, directory, dirtype, numentries ) );
1054 /****************************************************************************
1055 reply to a TRANS2_QFSINFO (query filesystem info)
1056 ****************************************************************************/
1057 static int call_trans2qfsinfo(connection_struct *conn,
1058 char *inbuf, char *outbuf,
1059 int length, int bufsize,
1060 char **pparams, char **ppdata)
1062 char *pdata = *ppdata;
1063 char *params = *pparams;
1064 uint16 info_level = SVAL(params,0);
1067 char *vname = volume_label(SNUM(conn));
1068 int snum = SNUM(conn);
1070 DEBUG(3,("call_trans2qfsinfo: level = %d\n", info_level));
1072 if(sys_stat(".",&st)!=0) {
1073 DEBUG(2,("call_trans2qfsinfo: stat of . failed (%s)\n", strerror(errno)));
1074 return (ERROR(ERRSRV,ERRinvdevice));
1077 pdata = *ppdata = Realloc(*ppdata, 1024); bzero(pdata,1024);
1083 int dfree,dsize,bsize;
1085 sys_disk_free(".",&bsize,&dfree,&dsize);
1086 SIVAL(pdata,l1_idFileSystem,st.st_dev);
1087 SIVAL(pdata,l1_cSectorUnit,bsize/512);
1088 SIVAL(pdata,l1_cUnit,dsize);
1089 SIVAL(pdata,l1_cUnitAvail,dfree);
1090 SSVAL(pdata,l1_cbSector,512);
1091 DEBUG(5,("call_trans2qfsinfo : bsize=%d, id=%x, cSectorUnit=%d, cUnit=%d, cUnitAvail=%d, cbSector=%d\n",
1092 bsize, (unsigned)st.st_dev, bsize/512, dsize, dfree, 512));
1097 /* Return volume name */
1098 int volname_len = MIN(strlen(vname),11);
1099 data_len = l2_vol_szVolLabel + volname_len + 1;
1101 * Add volume serial number - hash of a combination of
1102 * the called hostname and the service name.
1104 SIVAL(pdata,0,str_checksum(lp_servicename(snum)) ^ (str_checksum(local_machine)<<16) );
1105 SCVAL(pdata,l2_vol_cch,volname_len);
1106 StrnCpy(pdata+l2_vol_szVolLabel,vname,volname_len);
1107 DEBUG(5,("call_trans2qfsinfo : time = %x, namelen = %d, name = %s\n",
1108 (unsigned)st.st_ctime, volname_len,
1109 pdata+l2_vol_szVolLabel));
1112 case SMB_QUERY_FS_ATTRIBUTE_INFO:
1113 data_len = 12 + 2*strlen(FSTYPE_STRING);
1114 SIVAL(pdata,0,FILE_CASE_PRESERVED_NAMES); /* FS ATTRIBUTES */
1115 #if 0 /* Old code. JRA. */
1116 SIVAL(pdata,0,0x4006); /* FS ATTRIBUTES == long filenames supported? */
1117 #endif /* Old code. */
1118 SIVAL(pdata,4,128); /* Max filename component length */
1119 SIVAL(pdata,8,2*strlen(FSTYPE_STRING));
1120 PutUniCode(pdata+12,FSTYPE_STRING);
1122 case SMB_QUERY_FS_LABEL_INFO:
1123 data_len = 4 + strlen(vname);
1124 SIVAL(pdata,0,strlen(vname));
1125 pstrcpy(pdata+4,vname);
1127 case SMB_QUERY_FS_VOLUME_INFO:
1128 data_len = 18 + 2*strlen(vname);
1130 * Add volume serial number - hash of a combination of
1131 * the called hostname and the service name.
1133 SIVAL(pdata,8,str_checksum(lp_servicename(snum)) ^ (str_checksum(local_machine)<<16) );
1134 SIVAL(pdata,12,2*strlen(vname));
1135 PutUniCode(pdata+18,vname);
1136 DEBUG(5,("call_trans2qfsinfo : SMB_QUERY_FS_VOLUME_INFO namelen = %d, vol = %s\n", strlen(vname),
1139 case SMB_QUERY_FS_SIZE_INFO:
1141 int dfree,dsize,bsize;
1143 sys_disk_free(".",&bsize,&dfree,&dsize);
1144 SIVAL(pdata,0,dsize);
1145 SIVAL(pdata,8,dfree);
1146 SIVAL(pdata,16,bsize/512);
1147 SIVAL(pdata,20,512);
1150 case SMB_QUERY_FS_DEVICE_INFO:
1152 SIVAL(pdata,0,0); /* dev type */
1153 SIVAL(pdata,4,0); /* characteristics */
1156 return(ERROR(ERRDOS,ERRunknownlevel));
1160 send_trans2_replies( outbuf, bufsize, params, 0, pdata, data_len);
1162 DEBUG( 4, ( "%s info_level = %d\n",
1163 smb_fn_name(CVAL(inbuf,smb_com)), info_level) );
1168 /****************************************************************************
1169 reply to a TRANS2_SETFSINFO (set filesystem info)
1170 ****************************************************************************/
1171 static int call_trans2setfsinfo(connection_struct *conn,
1172 char *inbuf, char *outbuf, int length,
1174 char **pparams, char **ppdata)
1176 /* Just say yes we did it - there is nothing that
1177 can be set here so it doesn't matter. */
1179 DEBUG(3,("call_trans2setfsinfo\n"));
1181 if (!CAN_WRITE(conn))
1182 return(ERROR(ERRSRV,ERRaccess));
1184 outsize = set_message(outbuf,10,0,True);
1189 /****************************************************************************
1190 Reply to a TRANS2_QFILEPATHINFO or TRANSACT2_QFILEINFO (query file info by
1191 file name or file id).
1192 ****************************************************************************/
1194 static int call_trans2qfilepathinfo(connection_struct *conn,
1195 char *inbuf, char *outbuf, int length,
1197 char **pparams,char **ppdata,
1200 char *params = *pparams;
1201 char *pdata = *ppdata;
1202 uint16 tran_call = SVAL(inbuf, smb_setup0);
1206 unsigned int data_size;
1212 BOOL bad_path = False;
1214 if (tran_call == TRANSACT2_QFILEINFO) {
1215 int16 fnum = SVALS(params,0);
1216 info_level = SVAL(params,2);
1218 CHECK_FNUM(fnum,conn);
1221 fname = Files[fnum].fsp_name;
1222 if (fstat(Files[fnum].fd_ptr->fd,&sbuf) != 0) {
1223 DEBUG(3,("fstat of fnum %d failed (%s)\n",fnum, strerror(errno)));
1224 return(UNIXERROR(ERRDOS,ERRbadfid));
1226 pos = lseek(Files[fnum].fd_ptr->fd,0,SEEK_CUR);
1229 info_level = SVAL(params,0);
1231 pstrcpy(fname,¶ms[6]);
1232 unix_convert(fname,conn,0,&bad_path);
1233 if (!check_name(fname,conn) || sys_stat(fname,&sbuf)) {
1234 DEBUG(3,("fileinfo of %s failed (%s)\n",fname,strerror(errno)));
1235 if((errno == ENOENT) && bad_path)
1237 unix_ERR_class = ERRDOS;
1238 unix_ERR_code = ERRbadpath;
1240 return(UNIXERROR(ERRDOS,ERRbadpath));
1246 DEBUG(3,("call_trans2qfilepathinfo %s level=%d call=%d total_data=%d\n",
1247 fname,info_level,tran_call,total_data));
1249 p = strrchr(fname,'/');
1255 mode = dos_mode(conn,fname,&sbuf);
1256 size = sbuf.st_size;
1257 if (mode & aDIR) size = 0;
1259 params = *pparams = Realloc(*pparams,2); bzero(params,2);
1261 pdata = *ppdata = Realloc(*ppdata, data_size);
1263 if (total_data > 0 && IVAL(pdata,0) == total_data) {
1264 /* uggh, EAs for OS2 */
1265 DEBUG(4,("Rejecting EA request with total_data=%d\n",total_data));
1266 return(ERROR(ERRDOS,ERROR_EAS_NOT_SUPPORTED));
1269 bzero(pdata,data_size);
1273 case SMB_INFO_STANDARD:
1274 case SMB_INFO_QUERY_EA_SIZE:
1275 data_size = (info_level==1?22:26);
1276 put_dos_date2(pdata,l1_fdateCreation,get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(conn))));
1277 put_dos_date2(pdata,l1_fdateLastAccess,sbuf.st_atime);
1278 put_dos_date2(pdata,l1_fdateLastWrite,sbuf.st_mtime); /* write time */
1279 SIVAL(pdata,l1_cbFile,size);
1280 SIVAL(pdata,l1_cbFileAlloc,ROUNDUP(size,1024));
1281 SSVAL(pdata,l1_attrFile,mode);
1282 SIVAL(pdata,l1_attrFile+2,4); /* this is what OS2 does */
1285 case SMB_INFO_QUERY_EAS_FROM_LIST:
1287 put_dos_date2(pdata,0,get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(conn))));
1288 put_dos_date2(pdata,4,sbuf.st_atime);
1289 put_dos_date2(pdata,8,sbuf.st_mtime);
1290 SIVAL(pdata,12,size);
1291 SIVAL(pdata,16,ROUNDUP(size,1024));
1292 SIVAL(pdata,20,mode);
1295 case SMB_INFO_QUERY_ALL_EAS:
1297 SIVAL(pdata,0,data_size);
1301 return(ERROR(ERRDOS,ERRbadfunc)); /* os/2 needs this */
1303 case SMB_QUERY_FILE_BASIC_INFO:
1304 data_size = 36; /* w95 returns 40 bytes not 36 - why ?. */
1305 put_long_date(pdata,get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(conn))));
1306 put_long_date(pdata+8,sbuf.st_atime);
1307 put_long_date(pdata+16,sbuf.st_mtime); /* write time */
1308 put_long_date(pdata+24,sbuf.st_mtime); /* change time */
1309 SIVAL(pdata,32,mode);
1311 DEBUG(5,("SMB_QFBI - "));
1313 time_t create_time = get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(conn)));
1314 DEBUG(5,("create: %s ", ctime(&create_time)));
1316 DEBUG(5,("access: %s ", ctime(&sbuf.st_atime)));
1317 DEBUG(5,("write: %s ", ctime(&sbuf.st_mtime)));
1318 DEBUG(5,("change: %s ", ctime(&sbuf.st_mtime)));
1319 DEBUG(5,("mode: %x\n", mode));
1323 case SMB_QUERY_FILE_STANDARD_INFO:
1325 SIVAL(pdata,0,size);
1326 SIVAL(pdata,8,size);
1327 SIVAL(pdata,16,sbuf.st_nlink);
1329 CVAL(pdata,21) = (mode&aDIR)?1:0;
1332 case SMB_QUERY_FILE_EA_INFO:
1336 /* Get the 8.3 name - used if NT SMB was negotiated. */
1337 case SMB_QUERY_FILE_ALT_NAME_INFO:
1340 pstrcpy(short_name,p);
1341 /* Mangle if not already 8.3 */
1342 if(!is_8_3(short_name, True))
1344 if(!name_map_mangle(short_name,True,SNUM(conn)))
1347 strupper(short_name);
1348 l = strlen(short_name);
1349 PutUniCode(pdata + 4, short_name);
1350 data_size = 4 + (2*l);
1355 case SMB_QUERY_FILE_NAME_INFO:
1358 pstrcpy(pdata+4,fname);
1361 case SMB_QUERY_FILE_ALLOCATION_INFO:
1362 case SMB_QUERY_FILE_END_OF_FILEINFO:
1364 SIVAL(pdata,0,size);
1367 case SMB_QUERY_FILE_ALL_INFO:
1368 put_long_date(pdata,get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(conn))));
1369 put_long_date(pdata+8,sbuf.st_atime);
1370 put_long_date(pdata+16,sbuf.st_mtime); /* write time */
1371 put_long_date(pdata+24,sbuf.st_mtime); /* change time */
1372 SIVAL(pdata,32,mode);
1374 SIVAL(pdata,0,size);
1375 SIVAL(pdata,8,size);
1376 SIVAL(pdata,16,sbuf.st_nlink);
1378 CVAL(pdata,21) = (mode&aDIR)?1:0;
1380 pdata += 8; /* index number */
1381 pdata += 4; /* EA info */
1383 SIVAL(pdata,0,0xA9);
1385 SIVAL(pdata,0,0xd01BF);
1387 SIVAL(pdata,0,pos); /* current offset */
1389 SIVAL(pdata,0,mode); /* is this the right sort of mode info? */
1391 pdata += 4; /* alignment */
1393 pstrcpy(pdata+4,fname);
1395 data_size = PTR_DIFF(pdata,(*ppdata));
1398 case SMB_QUERY_FILE_STREAM_INFO:
1401 SIVAL(pdata,4,size);
1402 SIVAL(pdata,12,size);
1404 pstrcpy(pdata+24,fname);
1407 return(ERROR(ERRDOS,ERRunknownlevel));
1410 send_trans2_replies( outbuf, bufsize, params, 2, *ppdata, data_size);
1415 /****************************************************************************
1416 reply to a TRANS2_SETFILEINFO (set file info by fileid)
1417 ****************************************************************************/
1418 static int call_trans2setfilepathinfo(connection_struct *conn,
1419 char *inbuf, char *outbuf, int length,
1420 int bufsize, char **pparams,
1421 char **ppdata, int total_data)
1423 char *params = *pparams;
1424 char *pdata = *ppdata;
1425 uint16 tran_call = SVAL(inbuf, smb_setup0);
1434 BOOL bad_path = False;
1436 if (!CAN_WRITE(conn))
1437 return(ERROR(ERRSRV,ERRaccess));
1439 if (tran_call == TRANSACT2_SETFILEINFO) {
1440 int16 fnum = SVALS(params,0);
1441 info_level = SVAL(params,2);
1443 CHECK_FNUM(fnum,conn);
1446 fname = Files[fnum].fsp_name;
1447 fd = Files[fnum].fd_ptr->fd;
1449 if(fstat(fd,&st)!=0) {
1450 DEBUG(3,("fstat of %s failed (%s)\n", fname, strerror(errno)));
1451 return(ERROR(ERRDOS,ERRbadpath));
1455 info_level = SVAL(params,0);
1457 pstrcpy(fname,¶ms[6]);
1458 unix_convert(fname,conn,0,&bad_path);
1459 if(!check_name(fname, conn))
1461 if((errno == ENOENT) && bad_path)
1463 unix_ERR_class = ERRDOS;
1464 unix_ERR_code = ERRbadpath;
1466 return(UNIXERROR(ERRDOS,ERRbadpath));
1469 if(sys_stat(fname,&st)!=0) {
1470 DEBUG(3,("stat of %s failed (%s)\n", fname, strerror(errno)));
1471 if((errno == ENOENT) && bad_path)
1473 unix_ERR_class = ERRDOS;
1474 unix_ERR_code = ERRbadpath;
1476 return(UNIXERROR(ERRDOS,ERRbadpath));
1480 DEBUG(3,("call_trans2setfilepathinfo(%d) %s info_level=%d totdata=%d\n",
1481 tran_call,fname,info_level,total_data));
1483 /* Realloc the parameter and data sizes */
1484 params = *pparams = Realloc(*pparams,2); SSVAL(params,0,0);
1486 return(ERROR(ERRDOS,ERRnomem));
1489 tvs.modtime = st.st_mtime;
1490 tvs.actime = st.st_atime;
1491 mode = dos_mode(conn,fname,&st);
1493 if (total_data > 0 && IVAL(pdata,0) == total_data) {
1494 /* uggh, EAs for OS2 */
1495 DEBUG(4,("Rejecting EA request with total_data=%d\n",total_data));
1496 return(ERROR(ERRDOS,ERROR_EAS_NOT_SUPPORTED));
1501 case SMB_INFO_STANDARD:
1502 case SMB_INFO_QUERY_EA_SIZE:
1505 tvs.actime = make_unix_date2(pdata+l1_fdateLastAccess);
1508 tvs.modtime = make_unix_date2(pdata+l1_fdateLastWrite);
1510 mode = SVAL(pdata,l1_attrFile);
1511 size = IVAL(pdata,l1_cbFile);
1515 /* XXXX um, i don't think this is right.
1516 it's also not in the cifs6.txt spec.
1518 case SMB_INFO_QUERY_EAS_FROM_LIST:
1519 tvs.actime = make_unix_date2(pdata+8);
1520 tvs.modtime = make_unix_date2(pdata+12);
1521 size = IVAL(pdata,16);
1522 mode = IVAL(pdata,24);
1525 /* XXXX nor this. not in cifs6.txt, either. */
1526 case SMB_INFO_QUERY_ALL_EAS:
1527 tvs.actime = make_unix_date2(pdata+8);
1528 tvs.modtime = make_unix_date2(pdata+12);
1529 size = IVAL(pdata,16);
1530 mode = IVAL(pdata,24);
1533 case SMB_SET_FILE_BASIC_INFO:
1535 /* Ignore create time at offset pdata. */
1538 tvs.actime = interpret_long_date(pdata+8);
1540 /* write time + changed time, combined. */
1541 tvs.modtime=MAX(interpret_long_date(pdata+16),
1542 interpret_long_date(pdata+24));
1544 #if 0 /* Needs more testing... */
1545 /* Test from Luke to prevent Win95 from
1546 setting incorrect values here.
1548 if (tvs.actime < tvs.modtime)
1549 return(ERROR(ERRDOS,ERRnoaccess));
1550 #endif /* Needs more testing... */
1553 mode = IVAL(pdata,32);
1557 case SMB_SET_FILE_END_OF_FILE_INFO:
1559 if (IVAL(pdata,4) != 0) /* more than 32 bits? */
1560 return(ERROR(ERRDOS,ERRunknownlevel));
1561 size = IVAL(pdata,0);
1565 case SMB_SET_FILE_DISPOSITION_INFO: /* not supported yet */
1566 case SMB_SET_FILE_ALLOCATION_INFO: /* not supported yet */
1569 return(ERROR(ERRDOS,ERRunknownlevel));
1573 DEBUG(6,("actime: %s " , ctime(&tvs.actime)));
1574 DEBUG(6,("modtime: %s ", ctime(&tvs.modtime)));
1575 DEBUG(6,("size: %x " , size));
1576 DEBUG(6,("mode: %x\n" , mode));
1578 /* get some defaults (no modifications) if any info is zero. */
1579 if (!tvs.actime) tvs.actime = st.st_atime;
1580 if (!tvs.modtime) tvs.modtime = st.st_mtime;
1581 if (!size) size = st.st_size;
1583 /* Try and set the times, size and mode of this file -
1584 if they are different from the current values
1586 if (st.st_mtime != tvs.modtime || st.st_atime != tvs.actime)
1588 if(file_utime(conn, fname, &tvs)!=0)
1590 return(ERROR(ERRDOS,ERRnoaccess));
1594 /* check the mode isn't different, before changing it */
1595 if (mode != dos_mode(conn, fname, &st) && dos_chmod(conn, fname, mode, NULL))
1597 DEBUG(2,("chmod of %s failed (%s)\n", fname, strerror(errno)));
1598 return(ERROR(ERRDOS,ERRnoaccess));
1601 if(size != st.st_size)
1605 fd = sys_open(fname,O_RDWR,0);
1608 return(ERROR(ERRDOS,ERRbadpath));
1610 set_filelen(fd, size);
1615 set_filelen(fd, size);
1621 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
1626 /****************************************************************************
1627 reply to a TRANS2_MKDIR (make directory with extended attributes).
1628 ****************************************************************************/
1629 static int call_trans2mkdir(connection_struct *conn,
1630 char *inbuf, char *outbuf, int length, int bufsize,
1631 char **pparams, char **ppdata)
1633 char *params = *pparams;
1636 BOOL bad_path = False;
1638 if (!CAN_WRITE(conn))
1639 return(ERROR(ERRSRV,ERRaccess));
1641 pstrcpy(directory, ¶ms[4]);
1643 DEBUG(3,("call_trans2mkdir : name = %s\n", directory));
1645 unix_convert(directory,conn,0,&bad_path);
1646 if (check_name(directory,conn))
1647 ret = sys_mkdir(directory,unix_mode(conn,aDIR));
1651 DEBUG(5,("call_trans2mkdir error (%s)\n", strerror(errno)));
1652 if((errno == ENOENT) && bad_path)
1654 unix_ERR_class = ERRDOS;
1655 unix_ERR_code = ERRbadpath;
1657 return(UNIXERROR(ERRDOS,ERRnoaccess));
1660 /* Realloc the parameter and data sizes */
1661 params = *pparams = Realloc(*pparams,2);
1663 return(ERROR(ERRDOS,ERRnomem));
1667 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
1672 /****************************************************************************
1673 reply to a TRANS2_FINDNOTIFYFIRST (start monitoring a directory for changes)
1674 We don't actually do this - we just send a null response.
1675 ****************************************************************************/
1676 static int call_trans2findnotifyfirst(connection_struct *conn,
1677 char *inbuf, char *outbuf,
1678 int length, int bufsize,
1679 char **pparams, char **ppdata)
1681 static uint16 fnf_handle = 257;
1682 char *params = *pparams;
1683 uint16 info_level = SVAL(params,4);
1685 DEBUG(3,("call_trans2findnotifyfirst - info_level %d\n", info_level));
1693 return(ERROR(ERRDOS,ERRunknownlevel));
1696 /* Realloc the parameter and data sizes */
1697 params = *pparams = Realloc(*pparams,6);
1699 return(ERROR(ERRDOS,ERRnomem));
1701 SSVAL(params,0,fnf_handle);
1702 SSVAL(params,2,0); /* No changes */
1703 SSVAL(params,4,0); /* No EA errors */
1710 send_trans2_replies(outbuf, bufsize, params, 6, *ppdata, 0);
1715 /****************************************************************************
1716 reply to a TRANS2_FINDNOTIFYNEXT (continue monitoring a directory for
1717 changes). Currently this does nothing.
1718 ****************************************************************************/
1719 static int call_trans2findnotifynext(connection_struct *conn,
1720 char *inbuf, char *outbuf,
1721 int length, int bufsize,
1722 char **pparams, char **ppdata)
1724 char *params = *pparams;
1726 DEBUG(3,("call_trans2findnotifynext\n"));
1728 /* Realloc the parameter and data sizes */
1729 params = *pparams = Realloc(*pparams,4);
1731 return(ERROR(ERRDOS,ERRnomem));
1733 SSVAL(params,0,0); /* No changes */
1734 SSVAL(params,2,0); /* No EA errors */
1736 send_trans2_replies(outbuf, bufsize, params, 4, *ppdata, 0);
1741 /****************************************************************************
1742 reply to a SMBfindclose (stop trans2 directory search)
1743 ****************************************************************************/
1744 int reply_findclose(connection_struct *conn,
1745 char *inbuf,char *outbuf,int length,int bufsize)
1748 int16 dptr_num=SVALS(inbuf,smb_vwv0);
1750 DEBUG(3,("reply_findclose, dptr_num = %d\n", dptr_num));
1752 dptr_close(dptr_num);
1754 outsize = set_message(outbuf,0,0,True);
1756 DEBUG(3,("SMBfindclose dptr_num = %d\n", dptr_num));
1761 /****************************************************************************
1762 reply to a SMBfindnclose (stop FINDNOTIFYFIRST directory search)
1763 ****************************************************************************/
1764 int reply_findnclose(connection_struct *conn,
1765 char *inbuf,char *outbuf,int length,int bufsize)
1770 dptr_num = SVAL(inbuf,smb_vwv0);
1772 DEBUG(3,("reply_findnclose, dptr_num = %d\n", dptr_num));
1774 /* We never give out valid handles for a
1775 findnotifyfirst - so any dptr_num is ok here.
1778 outsize = set_message(outbuf,0,0,True);
1780 DEBUG(3,("SMB_findnclose dptr_num = %d\n", dptr_num));
1786 /****************************************************************************
1787 reply to a SMBtranss2 - just ignore it!
1788 ****************************************************************************/
1789 int reply_transs2(connection_struct *conn,
1790 char *inbuf,char *outbuf,int length,int bufsize)
1792 DEBUG(4,("Ignoring transs2 of length %d\n",length));
1796 /****************************************************************************
1797 reply to a SMBtrans2
1798 ****************************************************************************/
1799 int reply_trans2(connection_struct *conn,
1800 char *inbuf,char *outbuf,int length,int bufsize)
1803 unsigned int total_params = SVAL(inbuf, smb_tpscnt);
1804 unsigned int total_data =SVAL(inbuf, smb_tdscnt);
1806 unsigned int max_param_reply = SVAL(inbuf, smb_mprcnt);
1807 unsigned int max_data_reply = SVAL(inbuf, smb_mdrcnt);
1808 unsigned int max_setup_fields = SVAL(inbuf, smb_msrcnt);
1809 BOOL close_tid = BITSETW(inbuf+smb_flags,0);
1810 BOOL no_final_response = BITSETW(inbuf+smb_flags,1);
1811 int32 timeout = IVALS(inbuf,smb_timeout);
1813 unsigned int suwcnt = SVAL(inbuf, smb_suwcnt);
1814 unsigned int tran_call = SVAL(inbuf, smb_setup0);
1815 char *params = NULL, *data = NULL;
1816 int num_params, num_params_sofar, num_data, num_data_sofar;
1818 if(global_oplock_break && (tran_call == TRANSACT2_OPEN)) {
1819 /* Queue this open message as we are the process of an
1822 DEBUG(2,("reply_trans2: queueing message trans2open due to being "));
1823 DEBUGADD(2,( "in oplock break state.\n"));
1825 push_oplock_pending_smb_message(inbuf, length);
1829 outsize = set_message(outbuf,0,0,True);
1831 /* All trans2 messages we handle have smb_sucnt == 1 - ensure this
1832 is so as a sanity check */
1834 DEBUG(2,("Invalid smb_sucnt in trans2 call\n"));
1835 return(ERROR(ERRSRV,ERRerror));
1838 /* Allocate the space for the maximum needed parameters and data */
1839 if (total_params > 0)
1840 params = (char *)malloc(total_params);
1842 data = (char *)malloc(total_data);
1844 if ((total_params && !params) || (total_data && !data)) {
1845 DEBUG(2,("Out of memory in reply_trans2\n"));
1846 return(ERROR(ERRDOS,ERRnomem));
1849 /* Copy the param and data bytes sent with this request into
1850 the params buffer */
1851 num_params = num_params_sofar = SVAL(inbuf,smb_pscnt);
1852 num_data = num_data_sofar = SVAL(inbuf, smb_dscnt);
1854 if (num_params > total_params || num_data > total_data)
1855 exit_server("invalid params in reply_trans2");
1858 memcpy( params, smb_base(inbuf) + SVAL(inbuf, smb_psoff), num_params);
1860 memcpy( data, smb_base(inbuf) + SVAL(inbuf, smb_dsoff), num_data);
1862 if(num_data_sofar < total_data || num_params_sofar < total_params) {
1863 /* We need to send an interim response then receive the rest
1864 of the parameter/data bytes */
1865 outsize = set_message(outbuf,0,0,True);
1866 send_smb(Client,outbuf);
1868 while (num_data_sofar < total_data ||
1869 num_params_sofar < total_params) {
1872 ret = receive_next_smb(Client,oplock_sock,inbuf,bufsize,
1873 SMB_SECONDARY_WAIT);
1876 (CVAL(inbuf, smb_com) != SMBtranss2)) || !ret) {
1877 outsize = set_message(outbuf,0,0,True);
1879 DEBUG(0,("reply_trans2: Invalid secondary trans2 packet\n"));
1881 DEBUG(0,("reply_trans2: %s in getting secondary trans2 response.\n",
1882 (smb_read_error == READ_ERROR) ? "error" : "timeout" ));
1887 return(ERROR(ERRSRV,ERRerror));
1890 /* Revise total_params and total_data in case
1891 they have changed downwards */
1892 total_params = SVAL(inbuf, smb_tpscnt);
1893 total_data = SVAL(inbuf, smb_tdscnt);
1894 num_params_sofar += (num_params = SVAL(inbuf,smb_spscnt));
1895 num_data_sofar += ( num_data = SVAL(inbuf, smb_sdscnt));
1896 if (num_params_sofar > total_params || num_data_sofar > total_data)
1897 exit_server("data overflow in trans2");
1899 memcpy( ¶ms[ SVAL(inbuf, smb_spsdisp)],
1900 smb_base(inbuf) + SVAL(inbuf, smb_spsoff), num_params);
1901 memcpy( &data[SVAL(inbuf, smb_sdsdisp)],
1902 smb_base(inbuf)+ SVAL(inbuf, smb_sdsoff), num_data);
1906 if (Protocol >= PROTOCOL_NT1) {
1907 uint16 flg2 = SVAL(outbuf,smb_flg2);
1908 SSVAL(outbuf,smb_flg2,flg2 | 0x40); /* IS_LONG_NAME */
1911 /* Now we must call the relevant TRANS2 function */
1913 case TRANSACT2_OPEN:
1914 outsize = call_trans2open(conn,
1915 inbuf, outbuf, bufsize,
1919 case TRANSACT2_FINDFIRST:
1920 outsize = call_trans2findfirst(conn, inbuf, outbuf,
1921 bufsize, ¶ms, &data);
1924 case TRANSACT2_FINDNEXT:
1925 outsize = call_trans2findnext(conn, inbuf, outbuf,
1930 case TRANSACT2_QFSINFO:
1931 outsize = call_trans2qfsinfo(conn, inbuf, outbuf,
1932 length, bufsize, ¶ms,
1936 case TRANSACT2_SETFSINFO:
1937 outsize = call_trans2setfsinfo(conn, inbuf, outbuf,
1942 case TRANSACT2_QPATHINFO:
1943 case TRANSACT2_QFILEINFO:
1944 outsize = call_trans2qfilepathinfo(conn, inbuf, outbuf,
1946 ¶ms, &data, total_data);
1948 case TRANSACT2_SETPATHINFO:
1949 case TRANSACT2_SETFILEINFO:
1950 outsize = call_trans2setfilepathinfo(conn, inbuf, outbuf,
1956 case TRANSACT2_FINDNOTIFYFIRST:
1957 outsize = call_trans2findnotifyfirst(conn, inbuf, outbuf,
1962 case TRANSACT2_FINDNOTIFYNEXT:
1963 outsize = call_trans2findnotifynext(conn, inbuf, outbuf,
1967 case TRANSACT2_MKDIR:
1968 outsize = call_trans2mkdir(conn, inbuf, outbuf, length,
1969 bufsize, ¶ms, &data);
1972 /* Error in request */
1973 DEBUG(2,("Unknown request %d in trans2 call\n", tran_call));
1978 return (ERROR(ERRSRV,ERRerror));
1981 /* As we do not know how many data packets will need to be
1982 returned here the various call_trans2xxxx calls
1983 must send their own. Thus a call_trans2xxx routine only
1984 returns a value other than -1 when it wants to send
1992 return outsize; /* If a correct response was needed the
1993 call_trans2xxx calls have already sent
1994 it. If outsize != -1 then it is returning */