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 len = srvstr_push(outbuf, pdata+12, fstype, -1, STR_TERMINATE);
1160 data_len = 12 + len;
1163 case SMB_QUERY_FS_LABEL_INFO:
1164 len = srvstr_push(outbuf, pdata+4, vname, -1, STR_TERMINATE);
1168 case SMB_QUERY_FS_VOLUME_INFO:
1170 * Add volume serial number - hash of a combination of
1171 * the called hostname and the service name.
1173 SIVAL(pdata,8,str_checksum(lp_servicename(snum)) ^
1174 (str_checksum(local_machine)<<16));
1176 len = srvstr_push(outbuf, pdata+18, vname, -1, STR_TERMINATE);
1177 SIVAL(pdata,12,len);
1179 DEBUG(5,("call_trans2qfsinfo : SMB_QUERY_FS_VOLUME_INFO namelen = %d, vol=%s serv=%s\n",
1180 (int)strlen(vname),vname, lp_servicename(snum)));
1182 case SMB_QUERY_FS_SIZE_INFO:
1184 SMB_BIG_UINT dfree,dsize,bsize;
1186 conn->vfs_ops.disk_free(conn,".",False,&bsize,&dfree,&dsize);
1187 SBIG_UINT(pdata,0,dsize);
1188 SBIG_UINT(pdata,8,dfree);
1189 SIVAL(pdata,16,bsize/512);
1190 SIVAL(pdata,20,512);
1193 case SMB_QUERY_FS_DEVICE_INFO:
1195 SIVAL(pdata,0,0); /* dev type */
1196 SIVAL(pdata,4,0); /* characteristics */
1198 case SMB_MAC_QUERY_FS_INFO:
1200 * Thursby MAC extension... ONLY on NTFS filesystems
1201 * once we do streams then we don't need this
1203 if (strequal(lp_fstype(SNUM(conn)),"NTFS")) {
1205 SIVAL(pdata,84,0x100); /* Don't support mac... */
1210 return ERROR_DOS(ERRDOS,ERRunknownlevel);
1214 send_trans2_replies( outbuf, bufsize, params, 0, pdata, data_len);
1216 DEBUG( 4, ( "%s info_level = %d\n",
1217 smb_fn_name(CVAL(inbuf,smb_com)), info_level) );
1222 /****************************************************************************
1223 Reply to a TRANS2_SETFSINFO (set filesystem info).
1224 ****************************************************************************/
1226 static int call_trans2setfsinfo(connection_struct *conn,
1227 char *inbuf, char *outbuf, int length,
1229 char **pparams, char **ppdata)
1231 /* Just say yes we did it - there is nothing that
1232 can be set here so it doesn't matter. */
1234 DEBUG(3,("call_trans2setfsinfo\n"));
1236 if (!CAN_WRITE(conn))
1237 return ERROR_DOS(ERRSRV,ERRaccess);
1239 outsize = set_message(outbuf,10,0,True);
1244 /****************************************************************************
1245 Reply to a TRANS2_QFILEPATHINFO or TRANSACT2_QFILEINFO (query file info by
1246 file name or file id).
1247 ****************************************************************************/
1249 static int call_trans2qfilepathinfo(connection_struct *conn,
1250 char *inbuf, char *outbuf, int length,
1252 char **pparams,char **ppdata,
1255 int max_data_bytes = SVAL(inbuf, smb_mdrcnt);
1256 char *params = *pparams;
1257 char *pdata = *ppdata;
1258 uint16 tran_call = SVAL(inbuf, smb_setup0);
1262 SMB_OFF_T allocation_size=0;
1263 unsigned int data_size;
1264 SMB_STRUCT_STAT sbuf;
1269 BOOL bad_path = False;
1270 BOOL delete_pending = False;
1274 if (tran_call == TRANSACT2_QFILEINFO) {
1275 files_struct *fsp = file_fsp(params,0);
1276 info_level = SVAL(params,2);
1278 DEBUG(3,("call_trans2qfilepathinfo: TRANSACT2_QFILEINFO: level = %d\n", info_level));
1280 if(fsp && (fsp->is_directory || fsp->stat_open)) {
1282 * This is actually a QFILEINFO on a directory
1283 * handle (returned from an NT SMB). NT5.0 seems
1284 * to do this call. JRA.
1286 pstrcpy(fname, fsp->fsp_name);
1287 unix_convert(fname,conn,0,&bad_path,&sbuf);
1288 if (!check_name(fname,conn) ||
1289 (!VALID_STAT(sbuf) && vfs_stat(conn,fname,&sbuf))) {
1290 DEBUG(3,("fileinfo of %s failed (%s)\n",fname,strerror(errno)));
1291 if((errno == ENOENT) && bad_path) {
1292 unix_ERR_class = ERRDOS;
1293 unix_ERR_code = ERRbadpath;
1295 return(UNIXERROR(ERRDOS,ERRbadpath));
1298 delete_pending = fsp->directory_delete_on_close;
1301 * Original code - this is an open file.
1303 CHECK_FSP(fsp,conn);
1305 pstrcpy(fname, fsp->fsp_name);
1306 if (vfs_fstat(fsp,fsp->fd,&sbuf) != 0) {
1307 DEBUG(3,("fstat of fnum %d failed (%s)\n", fsp->fnum, strerror(errno)));
1308 return(UNIXERROR(ERRDOS,ERRbadfid));
1310 if((pos = fsp->conn->vfs_ops.lseek(fsp,fsp->fd,0,SEEK_CUR)) == -1)
1311 return(UNIXERROR(ERRDOS,ERRnoaccess));
1313 delete_pending = fsp->delete_on_close;
1317 info_level = SVAL(params,0);
1319 DEBUG(3,("call_trans2qfilepathinfo: TRANSACT2_QPATHINFO: level = %d\n", info_level));
1321 srvstr_pull(inbuf, fname, ¶ms[6], sizeof(fname), -1, STR_TERMINATE);
1323 RESOLVE_DFSPATH(fname, conn, inbuf, outbuf);
1325 unix_convert(fname,conn,0,&bad_path,&sbuf);
1326 if (!check_name(fname,conn) ||
1327 (!VALID_STAT(sbuf) && vfs_stat(conn,fname,&sbuf))) {
1328 DEBUG(3,("fileinfo of %s failed (%s)\n",fname,strerror(errno)));
1329 if((errno == ENOENT) && bad_path) {
1330 unix_ERR_class = ERRDOS;
1331 unix_ERR_code = ERRbadpath;
1333 return(UNIXERROR(ERRDOS,ERRbadpath));
1338 DEBUG(3,("call_trans2qfilepathinfo %s level=%d call=%d total_data=%d\n",
1339 fname,info_level,tran_call,total_data));
1341 p = strrchr_m(fname,'/');
1347 mode = dos_mode(conn,fname,&sbuf);
1348 size = sbuf.st_size;
1349 allocation_size = SMB_ROUNDUP_ALLOCATION(sbuf.st_size);
1354 params = Realloc(*pparams,2);
1356 return ERROR_DOS(ERRDOS,ERRnomem);
1358 memset((char *)params,'\0',2);
1359 data_size = max_data_bytes + 1024;
1360 pdata = Realloc(*ppdata, data_size);
1361 if ( pdata == NULL )
1362 return ERROR_DOS(ERRDOS,ERRnomem);
1365 if (total_data > 0 && IVAL(pdata,0) == total_data) {
1366 /* uggh, EAs for OS2 */
1367 DEBUG(4,("Rejecting EA request with total_data=%d\n",total_data));
1368 return ERROR_DOS(ERRDOS,ERReasnotsupported);
1371 memset((char *)pdata,'\0',data_size);
1373 c_time = get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(conn)));
1375 if (lp_dos_filetime_resolution(SNUM(conn))) {
1377 sbuf.st_atime &= ~1;
1378 sbuf.st_mtime &= ~1;
1379 sbuf.st_mtime &= ~1;
1382 switch (info_level) {
1383 case SMB_INFO_STANDARD:
1384 case SMB_INFO_QUERY_EA_SIZE:
1385 data_size = (info_level==1?22:26);
1386 put_dos_date2(pdata,l1_fdateCreation,c_time);
1387 put_dos_date2(pdata,l1_fdateLastAccess,sbuf.st_atime);
1388 put_dos_date2(pdata,l1_fdateLastWrite,sbuf.st_mtime); /* write time */
1389 SIVAL(pdata,l1_cbFile,(uint32)size);
1390 SIVAL(pdata,l1_cbFileAlloc,(uint32)allocation_size);
1391 SSVAL(pdata,l1_attrFile,mode);
1392 SIVAL(pdata,l1_attrFile+2,4); /* this is what OS2 does */
1395 case SMB_INFO_QUERY_EAS_FROM_LIST:
1397 put_dos_date2(pdata,0,c_time);
1398 put_dos_date2(pdata,4,sbuf.st_atime);
1399 put_dos_date2(pdata,8,sbuf.st_mtime);
1400 SIVAL(pdata,12,(uint32)size);
1401 SIVAL(pdata,16,(uint32)allocation_size);
1402 SIVAL(pdata,20,mode);
1405 case SMB_INFO_QUERY_ALL_EAS:
1407 SIVAL(pdata,0,data_size);
1411 return ERROR_DOS(ERRDOS,ERRbadfunc); /* os/2 needs this */
1413 case SMB_FILE_BASIC_INFORMATION:
1414 case SMB_QUERY_FILE_BASIC_INFO:
1416 if (info_level == SMB_QUERY_FILE_BASIC_INFO)
1417 data_size = 36; /* w95 returns 40 bytes not 36 - why ?. */
1422 put_long_date(pdata,c_time);
1423 put_long_date(pdata+8,sbuf.st_atime);
1424 put_long_date(pdata+16,sbuf.st_mtime); /* write time */
1425 put_long_date(pdata+24,sbuf.st_mtime); /* change time */
1426 SIVAL(pdata,32,mode);
1428 DEBUG(5,("SMB_QFBI - "));
1430 time_t create_time = c_time;
1431 DEBUG(5,("create: %s ", ctime(&create_time)));
1433 DEBUG(5,("access: %s ", ctime(&sbuf.st_atime)));
1434 DEBUG(5,("write: %s ", ctime(&sbuf.st_mtime)));
1435 DEBUG(5,("change: %s ", ctime(&sbuf.st_mtime)));
1436 DEBUG(5,("mode: %x\n", mode));
1440 case SMB_FILE_STANDARD_INFORMATION:
1441 case SMB_QUERY_FILE_STANDARD_INFO:
1443 /* Fake up allocation size. */
1444 SOFF_T(pdata,0,allocation_size);
1445 SOFF_T(pdata,8,size);
1446 SIVAL(pdata,16,sbuf.st_nlink);
1448 CVAL(pdata,21) = (mode&aDIR)?1:0;
1451 case SMB_FILE_EA_INFORMATION:
1452 case SMB_QUERY_FILE_EA_INFO:
1456 /* Get the 8.3 name - used if NT SMB was negotiated. */
1457 case SMB_QUERY_FILE_ALT_NAME_INFO:
1461 pstrcpy(short_name,base_name);
1462 /* Mangle if not already 8.3 */
1463 if(!is_8_3(short_name, True)) {
1464 if(!name_map_mangle(short_name,True,True,SNUM(conn)))
1467 len = srvstr_push(outbuf, pdata+4, short_name, -1, STR_TERMINATE|STR_UPPER);
1468 data_size = 4 + len;
1473 case SMB_QUERY_FILE_NAME_INFO:
1475 * The first part of this code is essential
1476 * to get security descriptors to work on mapped
1477 * drives. Don't ask how I discovered this unless
1478 * you like hearing about me suffering.... :-). JRA.
1480 if(strequal(".", fname)) {
1481 len = srvstr_push(outbuf, pdata+4, "\\", -1, STR_TERMINATE);
1483 len = srvstr_push(outbuf, pdata+4, fname, -1, STR_TERMINATE);
1485 data_size = 4 + len;
1489 case SMB_FILE_END_OF_FILE_INFORMATION:
1490 case SMB_QUERY_FILE_END_OF_FILEINFO:
1492 SOFF_T(pdata,0,size);
1495 case SMB_FILE_ALLOCATION_INFORMATION:
1496 case SMB_QUERY_FILE_ALLOCATION_INFO:
1498 SOFF_T(pdata,0,allocation_size);
1501 case SMB_QUERY_FILE_ALL_INFO:
1502 put_long_date(pdata,c_time);
1503 put_long_date(pdata+8,sbuf.st_atime);
1504 put_long_date(pdata+16,sbuf.st_mtime); /* write time */
1505 put_long_date(pdata+24,sbuf.st_mtime); /* change time */
1506 SIVAL(pdata,32,mode);
1508 SOFF_T(pdata,0,allocation_size);
1509 SOFF_T(pdata,8,size);
1510 SIVAL(pdata,16,sbuf.st_nlink);
1511 CVAL(pdata,20) = delete_pending;
1512 CVAL(pdata,21) = (mode&aDIR)?1:0;
1514 SINO_T(pdata,0,(SMB_INO_T)sbuf.st_ino);
1515 pdata += 8; /* index number */
1516 pdata += 4; /* EA info */
1518 SIVAL(pdata,0,0xA9);
1520 SIVAL(pdata,0,0xd01BF);
1522 SOFF_T(pdata,0,pos); /* current offset */
1524 SIVAL(pdata,0,mode); /* is this the right sort of mode info? */
1526 pdata += 4; /* alignment */
1527 len = srvstr_push(outbuf, pdata+4, fname, -1, STR_TERMINATE);
1530 data_size = PTR_DIFF(pdata,(*ppdata));
1533 case SMB_FILE_INTERNAL_INFORMATION:
1534 /* This should be an index number - looks like dev/ino to me :-) */
1535 SIVAL(pdata,0,sbuf.st_dev);
1536 SIVAL(pdata,4,sbuf.st_ino);
1540 case SMB_FILE_ACCESS_INFORMATION:
1541 SIVAL(pdata,0,0x12019F); /* ??? */
1545 case SMB_FILE_NAME_INFORMATION:
1546 /* Pathname with leading '\'. */
1551 pstrcpy(new_fname, "\\");
1552 pstrcat(new_fname, fname);
1553 byte_len = dos_PutUniCode(pdata+4,new_fname,max_data_bytes,False);
1554 SIVAL(pdata,0,byte_len);
1555 data_size = 4 + byte_len;
1559 case SMB_FILE_DISPOSITION_INFORMATION:
1561 CVAL(pdata,0) = delete_pending;
1564 case SMB_FILE_POSITION_INFORMATION:
1566 SOFF_T(pdata,0,pos);
1569 case SMB_FILE_MODE_INFORMATION:
1570 SIVAL(pdata,0,mode);
1574 case SMB_FILE_ALIGNMENT_INFORMATION:
1575 SIVAL(pdata,0,0); /* No alignment needed. */
1580 /* Not yet finished... JRA */
1586 put_long_date(pdata,c_time);
1587 put_long_date(pdata+8,sbuf.st_atime);
1588 put_long_date(pdata+16,sbuf.st_mtime); /* write time */
1589 put_long_date(pdata+24,sbuf.st_mtime); /* change time */
1590 SIVAL(pdata,32,mode);
1591 SIVAL(pdata,36,0); /* ??? */
1592 SIVAL(pdata,40,0x20); /* ??? */
1593 SIVAL(pdata,44,0); /* ??? */
1594 SOFF_T(pdata,48,size);
1595 SIVAL(pdata,56,0x1); /* ??? */
1596 SIVAL(pdata,60,0); /* ??? */
1597 SIVAL(pdata,64,0); /* ??? */
1598 SIVAL(pdata,68,length); /* Following string length in bytes. */
1599 dos_PutUniCode(pdata+72,,False);
1604 case SMB_FILE_ALTERNATE_NAME_INFORMATION:
1605 /* Last component of pathname. */
1607 size_t byte_len = dos_PutUniCode(pdata+4,fname,max_data_bytes,False);
1608 SIVAL(pdata,0,byte_len);
1609 data_size = 4 + byte_len;
1613 case SMB_FILE_STREAM_INFORMATION:
1617 size_t byte_len = dos_PutUniCode(pdata+24,"::$DATA", 0xE, False);
1618 SIVAL(pdata,0,0); /* ??? */
1619 SIVAL(pdata,4,byte_len); /* Byte length of unicode string ::$DATA */
1620 SOFF_T(pdata,8,size);
1621 SIVAL(pdata,16,allocation_size);
1622 SIVAL(pdata,20,0); /* ??? */
1623 data_size = 24 + byte_len;
1627 case SMB_FILE_COMPRESSION_INFORMATION:
1628 SOFF_T(pdata,0,size);
1629 SIVAL(pdata,8,0); /* ??? */
1630 SIVAL(pdata,12,0); /* ??? */
1634 case SMB_FILE_NETWORK_OPEN_INFORMATION:
1635 put_long_date(pdata,c_time);
1636 put_long_date(pdata+8,sbuf.st_atime);
1637 put_long_date(pdata+16,sbuf.st_mtime); /* write time */
1638 put_long_date(pdata+24,sbuf.st_mtime); /* change time */
1639 SIVAL(pdata,32,allocation_size);
1640 SOFF_T(pdata,40,size);
1641 SIVAL(pdata,48,mode);
1642 SIVAL(pdata,52,0); /* ??? */
1646 case SMB_FILE_ATTRIBUTE_TAG_INFORMATION:
1647 SIVAL(pdata,0,mode);
1653 /* NT4 server just returns "invalid query" to this - if we try to answer
1654 it then NTws gets a BSOD! (tridge) */
1655 case SMB_QUERY_FILE_STREAM_INFO:
1657 SIVAL(pdata,4,(uint32)size);
1658 SIVAL(pdata,12,(uint32)allocation_size);
1659 len = srvstr_push(outbuf, pdata+24, fname, -1, STR_TERMINATE);
1660 SIVAL(pdata,20,len);
1661 data_size = 24 + len;
1666 return ERROR_DOS(ERRDOS,ERRunknownlevel);
1669 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, data_size);
1674 /****************************************************************************
1675 Deal with the internal needs of setting the delete on close flag. Note that
1676 as the tdb locking is recursive, it is safe to call this from within
1677 open_file_shared. JRA.
1678 ****************************************************************************/
1680 NTSTATUS set_delete_on_close_internal(files_struct *fsp, BOOL delete_on_close)
1683 * Only allow delete on close for files/directories opened with delete intent.
1686 if (delete_on_close && !GET_DELETE_ACCESS_REQUESTED(fsp->share_mode)) {
1687 DEBUG(10,("set_delete_on_close_internal: file %s delete on close flag set but delete access denied.\n",
1689 return NT_STATUS_ACCESS_DENIED;
1692 if(fsp->is_directory) {
1693 fsp->directory_delete_on_close = delete_on_close;
1694 DEBUG(10, ("set_delete_on_close_internal: %s delete on close flag for fnum = %d, directory %s\n",
1695 delete_on_close ? "Added" : "Removed", fsp->fnum, fsp->fsp_name ));
1696 } else if(fsp->stat_open) {
1698 DEBUG(10, ("set_delete_on_close_internal: %s delete on close flag for fnum = %d, stat open %s\n",
1699 delete_on_close ? "Added" : "Removed", fsp->fnum, fsp->fsp_name ));
1703 files_struct *iterate_fsp;
1706 * Modify the share mode entry for all files open
1707 * on this device and inode to tell other smbds we have
1708 * changed the delete on close flag. This will be noticed
1709 * in the close code, the last closer will delete the file
1713 DEBUG(10,("set_delete_on_close_internal: %s delete on close flag for fnum = %d, file %s\n",
1714 delete_on_close ? "Adding" : "Removing", fsp->fnum, fsp->fsp_name ));
1716 if (lock_share_entry_fsp(fsp) == False)
1717 return NT_STATUS_ACCESS_DENIED;
1719 if (!modify_delete_flag(fsp->dev, fsp->inode, delete_on_close)) {
1720 DEBUG(0,("set_delete_on_close_internal: failed to change delete on close flag for file %s\n",
1722 unlock_share_entry_fsp(fsp);
1723 return NT_STATUS_ACCESS_DENIED;
1730 unlock_share_entry_fsp(fsp);
1733 * Go through all files we have open on the same device and
1734 * inode (hanging off the same hash bucket) and set the DELETE_ON_CLOSE_FLAG.
1735 * Other smbd's that have this file open will look in the share_mode on close.
1736 * take care of this (rare) case in close_file(). See the comment there.
1737 * NB. JRA. We don't really need to do this anymore - all should be taken
1738 * care of in the share_mode changes in the tdb.
1741 for(iterate_fsp = file_find_di_first(fsp->dev, fsp->inode);
1742 iterate_fsp; iterate_fsp = file_find_di_next(iterate_fsp))
1743 fsp->delete_on_close = delete_on_close;
1746 * Set the delete on close flag in the fsp.
1748 fsp->delete_on_close = delete_on_close;
1750 DEBUG(10, ("set_delete_on_close_internal: %s delete on close flag for fnum = %d, file %s\n",
1751 delete_on_close ? "Added" : "Removed", fsp->fnum, fsp->fsp_name ));
1755 return NT_STATUS_OK;
1758 /****************************************************************************
1759 Reply to a TRANS2_SETFILEINFO (set file info by fileid).
1760 ****************************************************************************/
1762 static int call_trans2setfilepathinfo(connection_struct *conn,
1763 char *inbuf, char *outbuf, int length,
1764 int bufsize, char **pparams,
1765 char **ppdata, int total_data)
1767 char *params = *pparams;
1768 char *pdata = *ppdata;
1769 uint16 tran_call = SVAL(inbuf, smb_setup0);
1774 SMB_STRUCT_STAT sbuf;
1777 BOOL bad_path = False;
1778 files_struct *fsp = NULL;
1780 if (tran_call == TRANSACT2_SETFILEINFO) {
1781 fsp = file_fsp(params,0);
1782 info_level = SVAL(params,2);
1784 if(fsp && (fsp->is_directory || fsp->stat_open)) {
1786 * This is actually a SETFILEINFO on a directory
1787 * handle (returned from an NT SMB). NT5.0 seems
1788 * to do this call. JRA.
1790 pstrcpy(fname, fsp->fsp_name);
1791 unix_convert(fname,conn,0,&bad_path,&sbuf);
1792 if (!check_name(fname,conn) || (!VALID_STAT(sbuf))) {
1793 DEBUG(3,("fileinfo of %s failed (%s)\n",fname,strerror(errno)));
1794 if((errno == ENOENT) && bad_path) {
1795 unix_ERR_class = ERRDOS;
1796 unix_ERR_code = ERRbadpath;
1798 return(UNIXERROR(ERRDOS,ERRbadpath));
1800 } else if (fsp && fsp->print_file) {
1802 * Doing a DELETE_ON_CLOSE should cancel a print job.
1804 if ((info_level == SMB_SET_FILE_DISPOSITION_INFO) && CVAL(pdata,0)) {
1805 fsp->share_mode = FILE_DELETE_ON_CLOSE;
1807 DEBUG(3,("call_trans2setfilepathinfo: Cancelling print job (%s)\n", fsp->fsp_name ));
1810 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
1815 * Original code - this is an open file.
1817 CHECK_FSP(fsp,conn);
1819 pstrcpy(fname, fsp->fsp_name);
1822 if (vfs_fstat(fsp,fd,&sbuf) != 0) {
1823 DEBUG(3,("fstat of fnum %d failed (%s)\n",fsp->fnum, strerror(errno)));
1824 return(UNIXERROR(ERRDOS,ERRbadfid));
1829 info_level = SVAL(params,0);
1830 srvstr_pull(inbuf, fname, ¶ms[6], sizeof(fname), -1, STR_TERMINATE);
1831 unix_convert(fname,conn,0,&bad_path,&sbuf);
1832 if(!check_name(fname, conn)) {
1833 if((errno == ENOENT) && bad_path) {
1834 unix_ERR_class = ERRDOS;
1835 unix_ERR_code = ERRbadpath;
1837 return(UNIXERROR(ERRDOS,ERRbadpath));
1840 if(!VALID_STAT(sbuf)) {
1841 DEBUG(3,("stat of %s failed (%s)\n", fname, strerror(errno)));
1842 if((errno == ENOENT) && bad_path) {
1843 unix_ERR_class = ERRDOS;
1844 unix_ERR_code = ERRbadpath;
1846 return(UNIXERROR(ERRDOS,ERRbadpath));
1850 if (!CAN_WRITE(conn))
1851 return ERROR_DOS(ERRSRV,ERRaccess);
1853 DEBUG(3,("call_trans2setfilepathinfo(%d) %s info_level=%d totdata=%d\n",
1854 tran_call,fname,info_level,total_data));
1856 /* Realloc the parameter and data sizes */
1857 params = Realloc(*pparams,2);
1859 return ERROR_DOS(ERRDOS,ERRnomem);
1864 size = sbuf.st_size;
1865 tvs.modtime = sbuf.st_mtime;
1866 tvs.actime = sbuf.st_atime;
1867 mode = dos_mode(conn,fname,&sbuf);
1869 if (total_data > 4 && IVAL(pdata,0) == total_data) {
1870 /* uggh, EAs for OS2 */
1871 DEBUG(4,("Rejecting EA request with total_data=%d\n",total_data));
1872 return ERROR_DOS(ERRDOS,ERReasnotsupported);
1875 switch (info_level) {
1876 case SMB_INFO_STANDARD:
1877 case SMB_INFO_QUERY_EA_SIZE:
1880 tvs.actime = make_unix_date2(pdata+l1_fdateLastAccess);
1883 tvs.modtime = make_unix_date2(pdata+l1_fdateLastWrite);
1885 mode = SVAL(pdata,l1_attrFile);
1886 size = IVAL(pdata,l1_cbFile);
1890 /* XXXX um, i don't think this is right.
1891 it's also not in the cifs6.txt spec.
1893 case SMB_INFO_QUERY_EAS_FROM_LIST:
1894 tvs.actime = make_unix_date2(pdata+8);
1895 tvs.modtime = make_unix_date2(pdata+12);
1896 size = IVAL(pdata,16);
1897 mode = IVAL(pdata,24);
1900 /* XXXX nor this. not in cifs6.txt, either. */
1901 case SMB_INFO_QUERY_ALL_EAS:
1902 tvs.actime = make_unix_date2(pdata+8);
1903 tvs.modtime = make_unix_date2(pdata+12);
1904 size = IVAL(pdata,16);
1905 mode = IVAL(pdata,24);
1908 case SMB_SET_FILE_BASIC_INFO:
1909 case SMB_FILE_BASIC_INFORMATION:
1911 /* Patch to do this correctly from Paul Eggert <eggert@twinsun.com>. */
1913 time_t changed_time;
1915 /* Ignore create time at offset pdata. */
1918 tvs.actime = interpret_long_date(pdata+8);
1920 write_time = interpret_long_date(pdata+16);
1921 changed_time = interpret_long_date(pdata+24);
1923 tvs.modtime = MIN(write_time, changed_time);
1925 /* Prefer a defined time to an undefined one. */
1926 if (tvs.modtime == (time_t)0 || tvs.modtime == (time_t)-1)
1927 tvs.modtime = (write_time == (time_t)0 || write_time == (time_t)-1
1928 ? changed_time : write_time);
1931 mode = IVAL(pdata,32);
1935 case SMB_FILE_ALLOCATION_INFORMATION:
1936 case SMB_SET_FILE_ALLOCATION_INFO:
1939 SMB_OFF_T allocation_size = IVAL(pdata,0);
1940 #ifdef LARGE_SMB_OFF_T
1941 allocation_size |= (((SMB_OFF_T)IVAL(pdata,4)) << 32);
1942 #else /* LARGE_SMB_OFF_T */
1943 if (IVAL(pdata,4) != 0) /* more than 32 bits? */
1944 return ERROR_DOS(ERRDOS,ERRunknownlevel);
1945 #endif /* LARGE_SMB_OFF_T */
1946 DEBUG(10,("call_trans2setfilepathinfo: Set file allocation info for file %s to %.0f\n",
1947 fname, (double)allocation_size ));
1949 if(allocation_size != sbuf.st_size) {
1950 SMB_STRUCT_STAT new_sbuf;
1952 DEBUG(10,("call_trans2setfilepathinfo: file %s : setting new allocation size to %.0f\n",
1953 fname, (double)allocation_size ));
1956 files_struct *new_fsp = NULL;
1957 int access_mode = 0;
1960 if(global_oplock_break) {
1961 /* Queue this file modify as we are the process of an oplock break. */
1963 DEBUG(2,("call_trans2setfilepathinfo: queueing message due to being "));
1964 DEBUGADD(2,( "in oplock break state.\n"));
1966 push_oplock_pending_smb_message(inbuf, length);
1970 new_fsp = open_file_shared(conn, fname, &sbuf,
1971 SET_OPEN_MODE(DOS_OPEN_RDWR),
1972 (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN),
1973 0, 0, &access_mode, &action);
1975 if (new_fsp == NULL)
1976 return(UNIXERROR(ERRDOS,ERRbadpath));
1977 ret = vfs_allocate_file_space(new_fsp, allocation_size);
1978 if (vfs_fstat(new_fsp,new_fsp->fd,&new_sbuf) != 0) {
1979 DEBUG(3,("fstat of fnum %d failed (%s)\n",new_fsp->fnum, strerror(errno)));
1982 close_file(new_fsp,True);
1984 ret = vfs_allocate_file_space(fsp, size);
1985 if (vfs_fstat(fsp,fd,&new_sbuf) != 0) {
1986 DEBUG(3,("fstat of fnum %d failed (%s)\n",fsp->fnum, strerror(errno)));
1991 return ERROR_NT(NT_STATUS_DISK_FULL);
1993 /* Allocate can trucate size... */
1994 size = new_sbuf.st_size;
2000 case SMB_FILE_END_OF_FILE_INFORMATION:
2001 case SMB_SET_FILE_END_OF_FILE_INFO:
2003 size = IVAL(pdata,0);
2004 #ifdef LARGE_SMB_OFF_T
2005 size |= (((SMB_OFF_T)IVAL(pdata,4)) << 32);
2006 #else /* LARGE_SMB_OFF_T */
2007 if (IVAL(pdata,4) != 0) /* more than 32 bits? */
2008 return ERROR_DOS(ERRDOS,ERRunknownlevel);
2009 #endif /* LARGE_SMB_OFF_T */
2010 DEBUG(10,("call_trans2setfilepathinfo: Set end of file info for file %s to %.0f\n", fname, (double)size ));
2014 case SMB_FILE_DISPOSITION_INFORMATION:
2015 case SMB_SET_FILE_DISPOSITION_INFO: /* Set delete on close for open file. */
2017 BOOL delete_on_close = (CVAL(pdata,0) ? True : False);
2020 if (tran_call != TRANSACT2_SETFILEINFO)
2021 return ERROR_DOS(ERRDOS,ERRunknownlevel);
2024 return(UNIXERROR(ERRDOS,ERRbadfid));
2026 status = set_delete_on_close_internal(fsp, delete_on_close);
2028 if (NT_STATUS_V(status) != NT_STATUS_V(NT_STATUS_OK))
2029 return ERROR_NT(status);
2035 return ERROR_DOS(ERRDOS,ERRunknownlevel);
2038 /* get some defaults (no modifications) if any info is zero or -1. */
2039 if (tvs.actime == (time_t)0 || tvs.actime == (time_t)-1)
2040 tvs.actime = sbuf.st_atime;
2042 if (tvs.modtime == (time_t)0 || tvs.modtime == (time_t)-1)
2043 tvs.modtime = sbuf.st_mtime;
2045 DEBUG(6,("actime: %s " , ctime(&tvs.actime)));
2046 DEBUG(6,("modtime: %s ", ctime(&tvs.modtime)));
2047 DEBUG(6,("size: %.0f ", (double)size));
2048 DEBUG(6,("mode: %x\n" , mode));
2050 if(!((info_level == SMB_SET_FILE_END_OF_FILE_INFO) ||
2051 (info_level == SMB_SET_FILE_ALLOCATION_INFO) ||
2052 (info_level == SMB_FILE_ALLOCATION_INFORMATION) ||
2053 (info_level == SMB_FILE_END_OF_FILE_INFORMATION))) {
2056 * Only do this test if we are not explicitly
2057 * changing the size of a file.
2060 size = sbuf.st_size;
2064 * Try and set the times, size and mode of this file -
2065 * if they are different from the current values
2067 if (sbuf.st_mtime != tvs.modtime || sbuf.st_atime != tvs.actime) {
2070 * This was a setfileinfo on an open file.
2071 * NT does this a lot. It's actually pointless
2072 * setting the time here, as it will be overwritten
2073 * on the next write, so we save the request
2074 * away and will set it on file code. JRA.
2077 if (tvs.modtime != (time_t)0 && tvs.modtime != (time_t)-1) {
2078 DEBUG(10,("call_trans2setfilepathinfo: setting pending modtime to %s\n", ctime(&tvs.modtime) ));
2079 fsp->pending_modtime = tvs.modtime;
2084 DEBUG(10,("call_trans2setfilepathinfo: setting utimes to modified values.\n"));
2086 if(file_utime(conn, fname, &tvs)!=0)
2087 return(UNIXERROR(ERRDOS,ERRnoaccess));
2091 /* check the mode isn't different, before changing it */
2092 if ((mode != 0) && (mode != dos_mode(conn, fname, &sbuf))) {
2094 DEBUG(10,("call_trans2setfilepathinfo: file %s : setting dos mode %x\n", fname, mode ));
2096 if(file_chmod(conn, fname, mode, NULL)) {
2097 DEBUG(2,("chmod of %s failed (%s)\n", fname, strerror(errno)));
2098 return(UNIXERROR(ERRDOS,ERRnoaccess));
2102 if(size != sbuf.st_size) {
2104 DEBUG(10,("call_trans2setfilepathinfo: file %s : setting new size to %.0f\n",
2105 fname, (double)size ));
2108 files_struct *new_fsp = NULL;
2109 int access_mode = 0;
2112 if(global_oplock_break) {
2113 /* Queue this file modify as we are the process of an oplock break. */
2115 DEBUG(2,("call_trans2setfilepathinfo: queueing message due to being "));
2116 DEBUGADD(2,( "in oplock break state.\n"));
2118 push_oplock_pending_smb_message(inbuf, length);
2122 new_fsp = open_file_shared(conn, fname, &sbuf,
2123 SET_OPEN_MODE(DOS_OPEN_RDWR),
2124 (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN),
2125 0, 0, &access_mode, &action);
2127 if (new_fsp == NULL)
2128 return(UNIXERROR(ERRDOS,ERRbadpath));
2129 vfs_set_filelen(new_fsp, size);
2130 close_file(new_fsp,True);
2132 vfs_set_filelen(fsp, size);
2138 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
2143 /****************************************************************************
2144 Reply to a TRANS2_MKDIR (make directory with extended attributes).
2145 ****************************************************************************/
2147 static int call_trans2mkdir(connection_struct *conn,
2148 char *inbuf, char *outbuf, int length, int bufsize,
2149 char **pparams, char **ppdata)
2151 char *params = *pparams;
2154 SMB_STRUCT_STAT sbuf;
2155 BOOL bad_path = False;
2157 if (!CAN_WRITE(conn))
2158 return ERROR_DOS(ERRSRV,ERRaccess);
2160 srvstr_pull(inbuf, directory, ¶ms[4], sizeof(directory), -1, STR_TERMINATE);
2162 DEBUG(3,("call_trans2mkdir : name = %s\n", directory));
2164 unix_convert(directory,conn,0,&bad_path,&sbuf);
2165 if (check_name(directory,conn))
2166 ret = vfs_mkdir(conn,directory,unix_mode(conn,aDIR,directory));
2170 DEBUG(5,("call_trans2mkdir error (%s)\n", strerror(errno)));
2171 if((errno == ENOENT) && bad_path)
2173 unix_ERR_class = ERRDOS;
2174 unix_ERR_code = ERRbadpath;
2176 return(UNIXERROR(ERRDOS,ERRnoaccess));
2179 /* Realloc the parameter and data sizes */
2180 params = Realloc(*pparams,2);
2181 if(params == NULL) {
2182 return ERROR_DOS(ERRDOS,ERRnomem);
2188 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
2193 /****************************************************************************
2194 Reply to a TRANS2_FINDNOTIFYFIRST (start monitoring a directory for changes).
2195 We don't actually do this - we just send a null response.
2196 ****************************************************************************/
2198 static int call_trans2findnotifyfirst(connection_struct *conn,
2199 char *inbuf, char *outbuf,
2200 int length, int bufsize,
2201 char **pparams, char **ppdata)
2203 static uint16 fnf_handle = 257;
2204 char *params = *pparams;
2205 uint16 info_level = SVAL(params,4);
2207 DEBUG(3,("call_trans2findnotifyfirst - info_level %d\n", info_level));
2215 return ERROR_DOS(ERRDOS,ERRunknownlevel);
2218 /* Realloc the parameter and data sizes */
2219 params = Realloc(*pparams,6);
2220 if(params == NULL) {
2221 return ERROR_DOS(ERRDOS,ERRnomem);
2225 SSVAL(params,0,fnf_handle);
2226 SSVAL(params,2,0); /* No changes */
2227 SSVAL(params,4,0); /* No EA errors */
2234 send_trans2_replies(outbuf, bufsize, params, 6, *ppdata, 0);
2239 /****************************************************************************
2240 Reply to a TRANS2_FINDNOTIFYNEXT (continue monitoring a directory for
2241 changes). Currently this does nothing.
2242 ****************************************************************************/
2244 static int call_trans2findnotifynext(connection_struct *conn,
2245 char *inbuf, char *outbuf,
2246 int length, int bufsize,
2247 char **pparams, char **ppdata)
2249 char *params = *pparams;
2251 DEBUG(3,("call_trans2findnotifynext\n"));
2253 /* Realloc the parameter and data sizes */
2254 params = Realloc(*pparams,4);
2255 if(params == NULL) {
2256 return ERROR_DOS(ERRDOS,ERRnomem);
2260 SSVAL(params,0,0); /* No changes */
2261 SSVAL(params,2,0); /* No EA errors */
2263 send_trans2_replies(outbuf, bufsize, params, 4, *ppdata, 0);
2268 /****************************************************************************
2269 Reply to a TRANS2_GET_DFS_REFERRAL - Shirish Kalele <kalele@veritas.com>.
2270 ****************************************************************************/
2272 static int call_trans2getdfsreferral(connection_struct *conn, char* inbuf,
2273 char* outbuf, int length, int bufsize,
2274 char** pparams, char** ppdata)
2276 char *params = *pparams;
2279 int max_referral_level = SVAL(params,0);
2282 DEBUG(10,("call_trans2getdfsreferral\n"));
2284 if(!lp_host_msdfs())
2285 return ERROR_DOS(ERRDOS,ERRbadfunc);
2287 srvstr_pull(inbuf, pathname, ¶ms[2], sizeof(pathname), -1, STR_TERMINATE);
2289 if((reply_size = setup_dfs_referral(pathname,max_referral_level,ppdata)) < 0)
2290 return ERROR_DOS(ERRDOS,ERRbadfile);
2292 SSVAL(outbuf,smb_flg2,SVAL(outbuf,smb_flg2) | FLAGS2_DFS_PATHNAMES);
2293 send_trans2_replies(outbuf,bufsize,0,0,*ppdata,reply_size);
2298 #define LMCAT_SPL 0x53
2299 #define LMFUNC_GETJOBID 0x60
2301 /****************************************************************************
2302 Reply to a TRANS2_IOCTL - used for OS/2 printing.
2303 ****************************************************************************/
2305 static int call_trans2ioctl(connection_struct *conn, char* inbuf,
2306 char* outbuf, int length, int bufsize,
2307 char** pparams, char** ppdata)
2309 char *pdata = *ppdata;
2310 files_struct *fsp = file_fsp(inbuf,smb_vwv15);
2312 if ((SVAL(inbuf,(smb_setup+4)) == LMCAT_SPL) &&
2313 (SVAL(inbuf,(smb_setup+6)) == LMFUNC_GETJOBID)) {
2314 pdata = Realloc(*ppdata, 32);
2316 return ERROR_DOS(ERRDOS,ERRnomem);
2320 /* NOTE - THIS IS ASCII ONLY AT THE MOMENT - NOT SURE IF OS/2
2321 CAN ACCEPT THIS IN UNICODE. JRA. */
2323 SSVAL(pdata,0,fsp->print_jobid); /* Job number */
2324 srvstr_push( outbuf, pdata + 2, global_myname, 15, STR_ASCII|STR_TERMINATE); /* Our NetBIOS name */
2325 srvstr_push( outbuf, pdata+18, lp_servicename(SNUM(conn)), 13, STR_ASCII|STR_TERMINATE); /* Service name */
2326 send_trans2_replies(outbuf,bufsize,*pparams,0,*ppdata,32);
2329 DEBUG(2,("Unknown TRANS2_IOCTL\n"));
2330 return ERROR_DOS(ERRSRV,ERRerror);
2334 /****************************************************************************
2335 Reply to a SMBfindclose (stop trans2 directory search).
2336 ****************************************************************************/
2338 int reply_findclose(connection_struct *conn,
2339 char *inbuf,char *outbuf,int length,int bufsize)
2342 int dptr_num=SVALS(inbuf,smb_vwv0);
2343 START_PROFILE(SMBfindclose);
2345 DEBUG(3,("reply_findclose, dptr_num = %d\n", dptr_num));
2347 dptr_close(&dptr_num);
2349 outsize = set_message(outbuf,0,0,True);
2351 DEBUG(3,("SMBfindclose dptr_num = %d\n", dptr_num));
2353 END_PROFILE(SMBfindclose);
2357 /****************************************************************************
2358 Reply to a SMBfindnclose (stop FINDNOTIFYFIRST directory search).
2359 ****************************************************************************/
2361 int reply_findnclose(connection_struct *conn,
2362 char *inbuf,char *outbuf,int length,int bufsize)
2366 START_PROFILE(SMBfindnclose);
2368 dptr_num = SVAL(inbuf,smb_vwv0);
2370 DEBUG(3,("reply_findnclose, dptr_num = %d\n", dptr_num));
2372 /* We never give out valid handles for a
2373 findnotifyfirst - so any dptr_num is ok here.
2376 outsize = set_message(outbuf,0,0,True);
2378 DEBUG(3,("SMB_findnclose dptr_num = %d\n", dptr_num));
2380 END_PROFILE(SMBfindnclose);
2384 /****************************************************************************
2385 Reply to a SMBtranss2 - just ignore it!
2386 ****************************************************************************/
2388 int reply_transs2(connection_struct *conn,
2389 char *inbuf,char *outbuf,int length,int bufsize)
2391 START_PROFILE(SMBtranss2);
2392 DEBUG(4,("Ignoring transs2 of length %d\n",length));
2393 END_PROFILE(SMBtranss2);
2397 /****************************************************************************
2398 Reply to a SMBtrans2.
2399 ****************************************************************************/
2401 int reply_trans2(connection_struct *conn,
2402 char *inbuf,char *outbuf,int length,int bufsize)
2405 unsigned int total_params = SVAL(inbuf, smb_tpscnt);
2406 unsigned int total_data =SVAL(inbuf, smb_tdscnt);
2408 unsigned int max_param_reply = SVAL(inbuf, smb_mprcnt);
2409 unsigned int max_data_reply = SVAL(inbuf, smb_mdrcnt);
2410 unsigned int max_setup_fields = SVAL(inbuf, smb_msrcnt);
2411 BOOL close_tid = BITSETW(inbuf+smb_flags,0);
2412 BOOL no_final_response = BITSETW(inbuf+smb_flags,1);
2413 int32 timeout = IVALS(inbuf,smb_timeout);
2415 unsigned int suwcnt = SVAL(inbuf, smb_suwcnt);
2416 unsigned int tran_call = SVAL(inbuf, smb_setup0);
2417 char *params = NULL, *data = NULL;
2418 int num_params, num_params_sofar, num_data, num_data_sofar;
2419 START_PROFILE(SMBtrans2);
2421 if(global_oplock_break && (tran_call == TRANSACT2_OPEN)) {
2422 /* Queue this open message as we are the process of an
2425 DEBUG(2,("reply_trans2: queueing message trans2open due to being "));
2426 DEBUGADD(2,( "in oplock break state.\n"));
2428 push_oplock_pending_smb_message(inbuf, length);
2429 END_PROFILE(SMBtrans2);
2433 if (IS_IPC(conn) && (tran_call != TRANSACT2_OPEN)
2434 && (tran_call != TRANSACT2_GET_DFS_REFERRAL)) {
2435 END_PROFILE(SMBtrans2);
2436 return ERROR_DOS(ERRSRV,ERRaccess);
2439 outsize = set_message(outbuf,0,0,True);
2441 /* All trans2 messages we handle have smb_sucnt == 1 - ensure this
2442 is so as a sanity check */
2445 * Need to have rc=0 for ioctl to get job id for OS/2.
2446 * Network printing will fail if function is not successful.
2447 * Similar function in reply.c will be used if protocol
2448 * is LANMAN1.0 instead of LM1.2X002.
2449 * Until DosPrintSetJobInfo with PRJINFO3 is supported,
2450 * outbuf doesn't have to be set(only job id is used).
2452 if ( (suwcnt == 4) && (tran_call == TRANSACT2_IOCTL) &&
2453 (SVAL(inbuf,(smb_setup+4)) == LMCAT_SPL) &&
2454 (SVAL(inbuf,(smb_setup+6)) == LMFUNC_GETJOBID)) {
2455 DEBUG(2,("Got Trans2 DevIOctl jobid\n"));
2457 DEBUG(2,("Invalid smb_sucnt in trans2 call(%d)\n",suwcnt));
2458 DEBUG(2,("Transaction is %d\n",tran_call));
2459 END_PROFILE(SMBtrans2);
2460 return ERROR_DOS(ERRSRV,ERRerror);
2464 /* Allocate the space for the maximum needed parameters and data */
2465 if (total_params > 0)
2466 params = (char *)malloc(total_params);
2468 data = (char *)malloc(total_data);
2470 if ((total_params && !params) || (total_data && !data)) {
2471 DEBUG(2,("Out of memory in reply_trans2\n"));
2474 END_PROFILE(SMBtrans2);
2475 return ERROR_DOS(ERRDOS,ERRnomem);
2478 /* Copy the param and data bytes sent with this request into
2479 the params buffer */
2480 num_params = num_params_sofar = SVAL(inbuf,smb_pscnt);
2481 num_data = num_data_sofar = SVAL(inbuf, smb_dscnt);
2483 if (num_params > total_params || num_data > total_data)
2484 exit_server("invalid params in reply_trans2");
2487 memcpy( params, smb_base(inbuf) + SVAL(inbuf, smb_psoff), num_params);
2489 memcpy( data, smb_base(inbuf) + SVAL(inbuf, smb_dsoff), num_data);
2491 if(num_data_sofar < total_data || num_params_sofar < total_params) {
2492 /* We need to send an interim response then receive the rest
2493 of the parameter/data bytes */
2494 outsize = set_message(outbuf,0,0,True);
2495 if (!send_smb(smbd_server_fd(),outbuf))
2496 exit_server("reply_trans2: send_smb failed.");
2498 while (num_data_sofar < total_data ||
2499 num_params_sofar < total_params) {
2502 ret = receive_next_smb(inbuf,bufsize,SMB_SECONDARY_WAIT);
2505 (CVAL(inbuf, smb_com) != SMBtranss2)) || !ret) {
2506 outsize = set_message(outbuf,0,0,True);
2508 DEBUG(0,("reply_trans2: Invalid secondary trans2 packet\n"));
2510 DEBUG(0,("reply_trans2: %s in getting secondary trans2 response.\n",
2511 (smb_read_error == READ_ERROR) ? "error" : "timeout" ));
2514 END_PROFILE(SMBtrans2);
2515 return ERROR_DOS(ERRSRV,ERRerror);
2518 /* Revise total_params and total_data in case
2519 they have changed downwards */
2520 total_params = SVAL(inbuf, smb_tpscnt);
2521 total_data = SVAL(inbuf, smb_tdscnt);
2522 num_params_sofar += (num_params = SVAL(inbuf,smb_spscnt));
2523 num_data_sofar += ( num_data = SVAL(inbuf, smb_sdscnt));
2524 if (num_params_sofar > total_params || num_data_sofar > total_data)
2525 exit_server("data overflow in trans2");
2527 memcpy( ¶ms[ SVAL(inbuf, smb_spsdisp)],
2528 smb_base(inbuf) + SVAL(inbuf, smb_spsoff), num_params);
2529 memcpy( &data[SVAL(inbuf, smb_sdsdisp)],
2530 smb_base(inbuf)+ SVAL(inbuf, smb_sdsoff), num_data);
2534 if (Protocol >= PROTOCOL_NT1) {
2535 SSVAL(outbuf,smb_flg2,SVAL(outbuf,smb_flg2) | 0x40); /* IS_LONG_NAME */
2538 /* Now we must call the relevant TRANS2 function */
2540 case TRANSACT2_OPEN:
2541 START_PROFILE_NESTED(Trans2_open);
2542 outsize = call_trans2open(conn,
2543 inbuf, outbuf, bufsize,
2545 END_PROFILE_NESTED(Trans2_open);
2548 case TRANSACT2_FINDFIRST:
2549 START_PROFILE_NESTED(Trans2_findfirst);
2550 outsize = call_trans2findfirst(conn, inbuf, outbuf,
2551 bufsize, ¶ms, &data);
2552 END_PROFILE_NESTED(Trans2_findfirst);
2555 case TRANSACT2_FINDNEXT:
2556 START_PROFILE_NESTED(Trans2_findnext);
2557 outsize = call_trans2findnext(conn, inbuf, outbuf,
2560 END_PROFILE_NESTED(Trans2_findnext);
2563 case TRANSACT2_QFSINFO:
2564 START_PROFILE_NESTED(Trans2_qfsinfo);
2565 outsize = call_trans2qfsinfo(conn, inbuf, outbuf,
2566 length, bufsize, ¶ms,
2568 END_PROFILE_NESTED(Trans2_qfsinfo);
2571 case TRANSACT2_SETFSINFO:
2572 START_PROFILE_NESTED(Trans2_setfsinfo);
2573 outsize = call_trans2setfsinfo(conn, inbuf, outbuf,
2576 END_PROFILE_NESTED(Trans2_setfsinfo);
2579 case TRANSACT2_QPATHINFO:
2580 case TRANSACT2_QFILEINFO:
2581 START_PROFILE_NESTED(Trans2_qpathinfo);
2582 outsize = call_trans2qfilepathinfo(conn, inbuf, outbuf,
2584 ¶ms, &data, total_data);
2585 END_PROFILE_NESTED(Trans2_qpathinfo);
2587 case TRANSACT2_SETPATHINFO:
2588 case TRANSACT2_SETFILEINFO:
2589 START_PROFILE_NESTED(Trans2_setpathinfo);
2590 outsize = call_trans2setfilepathinfo(conn, inbuf, outbuf,
2594 END_PROFILE_NESTED(Trans2_setpathinfo);
2597 case TRANSACT2_FINDNOTIFYFIRST:
2598 START_PROFILE_NESTED(Trans2_findnotifyfirst);
2599 outsize = call_trans2findnotifyfirst(conn, inbuf, outbuf,
2602 END_PROFILE_NESTED(Trans2_findnotifyfirst);
2605 case TRANSACT2_FINDNOTIFYNEXT:
2606 START_PROFILE_NESTED(Trans2_findnotifynext);
2607 outsize = call_trans2findnotifynext(conn, inbuf, outbuf,
2610 END_PROFILE_NESTED(Trans2_findnotifynext);
2612 case TRANSACT2_MKDIR:
2613 START_PROFILE_NESTED(Trans2_mkdir);
2614 outsize = call_trans2mkdir(conn, inbuf, outbuf, length,
2615 bufsize, ¶ms, &data);
2616 END_PROFILE_NESTED(Trans2_mkdir);
2619 case TRANSACT2_GET_DFS_REFERRAL:
2620 START_PROFILE_NESTED(Trans2_get_dfs_referral);
2621 outsize = call_trans2getdfsreferral(conn,inbuf,outbuf,length,
2622 bufsize, ¶ms, &data);
2623 END_PROFILE_NESTED(Trans2_get_dfs_referral);
2625 case TRANSACT2_IOCTL:
2626 START_PROFILE_NESTED(Trans2_ioctl);
2627 outsize = call_trans2ioctl(conn,inbuf,outbuf,length,
2628 bufsize,¶ms,&data);
2629 END_PROFILE_NESTED(Trans2_ioctl);
2632 /* Error in request */
2633 DEBUG(2,("Unknown request %d in trans2 call\n", tran_call));
2636 END_PROFILE(SMBtrans2);
2637 return ERROR_DOS(ERRSRV,ERRerror);
2640 /* As we do not know how many data packets will need to be
2641 returned here the various call_trans2xxxx calls
2642 must send their own. Thus a call_trans2xxx routine only
2643 returns a value other than -1 when it wants to send
2649 END_PROFILE(SMBtrans2);
2650 return outsize; /* If a correct response was needed the
2651 call_trans2xxx calls have already sent
2652 it. If outsize != -1 then it is returning */