2 Unix SMB/Netbios implementation.
4 SMB transaction2 handling
5 Copyright (C) Jeremy Allison 1994-1998
7 Extensively modified by Andrew Tridgell, 1995
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26 extern int DEBUGLEVEL;
28 extern BOOL case_sensitive;
29 extern int smb_read_error;
30 extern fstring local_machine;
31 extern int global_oplock_break;
32 extern uint32 global_client_caps;
33 extern pstring global_myname;
35 /****************************************************************************
36 Send the required number of replies back.
37 We assume all fields other than the data fields are
38 set correctly for the type of call.
39 HACK ! Always assumes smb_setup field is zero.
40 ****************************************************************************/
41 static int send_trans2_replies(char *outbuf, int bufsize, char *params,
42 int paramsize, char *pdata, int datasize)
44 /* As we are using a protocol > LANMAN1 then the max_send
45 variable must have been set in the sessetupX call.
46 This takes precedence over the max_xmit field in the
47 global struct. These different max_xmit variables should
48 be merged as this is now too confusing */
51 int data_to_send = datasize;
52 int params_to_send = paramsize;
56 int params_sent_thistime, data_sent_thistime, total_sent_thistime;
57 int alignment_offset = 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.\n");
73 /* When sending params and data ensure that both are nicely aligned */
74 /* Only do this alignment when there is also data to send - else
75 can cause NT redirector problems. */
76 if (((params_to_send % 4) != 0) && (data_to_send != 0))
77 data_alignment_offset = 4 - (params_to_send % 4);
79 /* Space is bufsize minus Netbios over TCP header minus SMB header */
80 /* The alignment_offset is to align the param bytes on an even byte
81 boundary. NT 4.0 Beta needs this to work correctly. */
82 useable_space = bufsize - ((smb_buf(outbuf)+
83 alignment_offset+data_alignment_offset) -
86 /* useable_space can never be more than max_send minus the
88 useable_space = MIN(useable_space,
89 max_send - (alignment_offset+data_alignment_offset));
92 while (params_to_send || data_to_send)
94 /* Calculate whether we will totally or partially fill this packet */
95 total_sent_thistime = params_to_send + data_to_send +
96 alignment_offset + data_alignment_offset;
97 /* We can never send more than useable_space */
99 * Note that 'useable_space' does not include the alignment offsets,
100 * but we must include the alignment offsets in the calculation of
101 * the length of the data we send over the wire, as the alignment offsets
102 * are sent here. Fix from Marc_Jacobsen@hp.com.
104 total_sent_thistime = MIN(total_sent_thistime, useable_space+
105 alignment_offset + data_alignment_offset);
107 set_message(outbuf, 10, total_sent_thistime, True);
109 /* Set total params and data to be sent */
110 SSVAL(outbuf,smb_tprcnt,paramsize);
111 SSVAL(outbuf,smb_tdrcnt,datasize);
113 /* Calculate how many parameters and data we can fit into
114 this packet. Parameters get precedence */
116 params_sent_thistime = MIN(params_to_send,useable_space);
117 data_sent_thistime = useable_space - params_sent_thistime;
118 data_sent_thistime = MIN(data_sent_thistime,data_to_send);
120 SSVAL(outbuf,smb_prcnt, params_sent_thistime);
122 /* smb_proff is the offset from the start of the SMB header to the
123 parameter bytes, however the first 4 bytes of outbuf are
124 the Netbios over TCP header. Thus use smb_base() to subtract
125 them from the calculation */
127 SSVAL(outbuf,smb_proff,((smb_buf(outbuf)+alignment_offset) - smb_base(outbuf)));
129 if(params_sent_thistime == 0)
130 SSVAL(outbuf,smb_prdisp,0);
132 /* Absolute displacement of param bytes sent in this packet */
133 SSVAL(outbuf,smb_prdisp,pp - params);
135 SSVAL(outbuf,smb_drcnt, data_sent_thistime);
136 if(data_sent_thistime == 0)
138 SSVAL(outbuf,smb_droff,0);
139 SSVAL(outbuf,smb_drdisp, 0);
143 /* The offset of the data bytes is the offset of the
144 parameter bytes plus the number of parameters being sent this time */
145 SSVAL(outbuf,smb_droff,((smb_buf(outbuf)+alignment_offset) -
146 smb_base(outbuf)) + params_sent_thistime + data_alignment_offset);
147 SSVAL(outbuf,smb_drdisp, pd - pdata);
150 /* Copy the param bytes into the packet */
151 if(params_sent_thistime)
152 memcpy((smb_buf(outbuf)+alignment_offset),pp,params_sent_thistime);
153 /* Copy in the data bytes */
154 if(data_sent_thistime)
155 memcpy(smb_buf(outbuf)+alignment_offset+params_sent_thistime+
156 data_alignment_offset,pd,data_sent_thistime);
158 DEBUG(9,("t2_rep: params_sent_thistime = %d, data_sent_thistime = %d, useable_space = %d\n",
159 params_sent_thistime, data_sent_thistime, useable_space));
160 DEBUG(9,("t2_rep: params_to_send = %d, data_to_send = %d, paramsize = %d, datasize = %d\n",
161 params_to_send, data_to_send, paramsize, datasize));
163 /* Send the packet */
164 if (!send_smb(smbd_server_fd(),outbuf))
165 exit_server("send_trans2_replies: send_smb failed.\n");
167 pp += params_sent_thistime;
168 pd += data_sent_thistime;
170 params_to_send -= params_sent_thistime;
171 data_to_send -= data_sent_thistime;
174 if(params_to_send < 0 || data_to_send < 0)
176 DEBUG(0,("send_trans2_replies failed sanity check pts = %d, dts = %d\n!!!",
177 params_to_send, data_to_send));
186 /****************************************************************************
187 reply to a TRANSACT2_OPEN
188 ****************************************************************************/
189 static int call_trans2open(connection_struct *conn, char *inbuf, char *outbuf,
191 char **pparams, char **ppdata)
193 char *params = *pparams;
194 int16 open_mode = SVAL(params, 2);
195 int16 open_attr = SVAL(params,6);
196 BOOL oplock_request = (((SVAL(params,0)|(1<<1))>>1) | ((SVAL(params,0)|(1<<2))>>1));
198 BOOL return_additional_info = BITSETW(params,0);
199 int16 open_sattr = SVAL(params, 4);
200 time_t open_time = make_unix_date3(params+8);
202 int16 open_ofun = SVAL(params,12);
203 int32 open_size = IVAL(params,14);
204 char *pname = ¶ms[28];
208 int fmode=0,mtime=0,rmode;
210 SMB_STRUCT_STAT sbuf;
212 BOOL bad_path = False;
215 srvstr_pull(inbuf, fname, pname, sizeof(fname), -1, STR_TERMINATE);
217 DEBUG(3,("trans2open %s mode=%d attr=%d ofun=%d size=%d\n",
218 fname,open_mode, open_attr, open_ofun, open_size));
221 return(ERROR_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 **********************************************************/
298 static BOOL exact_match(char *str,char *mask, BOOL case_sig)
300 if (mask[0] == '.' && mask[1] == 0) return False;
301 if (case_sig) return strcmp(str,mask)==0;
302 return strcasecmp(str,mask) == 0;
305 /****************************************************************************
306 get a level dependent lanman2 dir entry.
307 ****************************************************************************/
308 static BOOL get_lanman2_dir_entry(connection_struct *conn,
309 void *inbuf, void *outbuf,
310 char *path_mask,int dirtype,int info_level,
311 int requires_resume_key,
312 BOOL dont_descend,char **ppdata,
313 char *base_data, int space_remaining,
314 BOOL *out_of_space, BOOL *got_exact_match,
319 SMB_STRUCT_STAT sbuf;
323 char *p, *q, *pdata = *ppdata;
329 time_t mdate=0, adate=0, cdate=0;
332 int nt_extmode; /* Used for NT connections instead of mode */
333 BOOL needslash = ( conn->dirpath[strlen(conn->dirpath) -1] != '/');
336 *out_of_space = False;
337 *got_exact_match = False;
342 p = strrchr_m(path_mask,'/');
351 pstrcpy(mask, path_mask);
357 /* Needed if we run out of space */
358 prev_dirpos = TellDir(conn->dirptr);
359 dname = ReadDirName(conn->dirptr);
362 * Due to bugs in NT client redirectors we are not using
363 * resume keys any more - set them to zero.
364 * Check out the related comments in findfirst/findnext.
370 DEBUG(8,("get_lanman2_dir_entry:readdir on dirptr 0x%lx now at offset %d\n",
371 (long)conn->dirptr,TellDir(conn->dirptr)));
376 pstrcpy(fname,dname);
378 if(!(got_match = *got_exact_match = exact_match(fname, mask, case_sensitive))) {
379 got_match = mask_match(fname, mask, case_sensitive);
382 if(!got_match && !is_8_3(fname, False)) {
385 * It turns out that NT matches wildcards against
386 * both long *and* short names. This may explain some
387 * of the wildcard wierdness from old DOS clients
388 * that some people have been seeing.... JRA.
392 pstrcpy( newname, fname);
393 name_map_mangle( newname, True, False, SNUM(conn));
394 if(!(got_match = *got_exact_match = exact_match(newname, mask, case_sensitive)))
395 got_match = mask_match(newname, mask, case_sensitive);
400 BOOL isdots = (strequal(fname,"..") || strequal(fname,"."));
401 if (dont_descend && !isdots)
404 pstrcpy(pathreal,conn->dirpath);
406 pstrcat(pathreal,"/");
407 pstrcat(pathreal,dname);
408 if (vfs_stat(conn,pathreal,&sbuf) != 0)
410 /* Needed to show the msdfs symlinks as directories */
411 if(!lp_host_msdfs() || !lp_msdfs_root(SNUM(conn))
412 || !is_msdfs_link(conn, pathreal))
414 DEBUG(5,("get_lanman2_dir_entry:Couldn't stat [%s] (%s)\n",
415 pathreal,strerror(errno)));
420 DEBUG(5,("get_lanman2_dir_entry: Masquerading msdfs link %s as a directory\n", pathreal));
421 sbuf.st_mode = (sbuf.st_mode & 0xFFF) | S_IFDIR;
425 mode = dos_mode(conn,pathreal,&sbuf);
427 if (!dir_check_ftype(conn,mode,&sbuf,dirtype)) {
428 DEBUG(5,("[%s] attribs didn't match %x\n",fname,dirtype));
433 mdate = sbuf.st_mtime;
434 adate = sbuf.st_atime;
435 cdate = get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(conn)));
437 if (lp_dos_filetime_resolution(SNUM(conn))) {
446 DEBUG(5,("get_lanman2_dir_entry found %s fname=%s\n",pathreal,fname));
452 name_map_mangle(fname,False,True,SNUM(conn));
457 nt_extmode = mode ? mode : FILE_ATTRIBUTE_NORMAL;
462 if(requires_resume_key) {
466 put_dos_date2(p,l1_fdateCreation,cdate);
467 put_dos_date2(p,l1_fdateLastAccess,adate);
468 put_dos_date2(p,l1_fdateLastWrite,mdate);
469 SIVAL(p,l1_cbFile,(uint32)size);
470 SIVAL(p,l1_cbFileAlloc,SMB_ROUNDUP(size,1024));
471 SSVAL(p,l1_attrFile,mode);
474 p += align_string(outbuf, p, 0);
475 len = srvstr_push(outbuf, p, fname, -1, STR_TERMINATE);
476 SCVAL(nameptr, -1, len);
482 if(requires_resume_key) {
486 put_dos_date2(p,l2_fdateCreation,cdate);
487 put_dos_date2(p,l2_fdateLastAccess,adate);
488 put_dos_date2(p,l2_fdateLastWrite,mdate);
489 SIVAL(p,l2_cbFile,(uint32)size);
490 SIVAL(p,l2_cbFileAlloc,SMB_ROUNDUP(size,1024));
491 SSVAL(p,l2_attrFile,mode);
492 SIVAL(p,l2_cbList,0); /* No extended attributes */
495 len = srvstr_push(outbuf, p, fname, -1,
499 *p++ = 0; /* craig from unisys pointed out we need this */
502 case SMB_FIND_FILE_BOTH_DIRECTORY_INFO:
503 was_8_3 = is_8_3(fname, True);
505 SIVAL(p,0,reskey); p += 4;
506 put_long_date(p,cdate); p += 8;
507 put_long_date(p,adate); p += 8;
508 put_long_date(p,mdate); p += 8;
509 put_long_date(p,mdate); p += 8;
513 SIVAL(p,0,nt_extmode); p += 4;
515 SIVAL(p,0,0); p += 4;
517 pstring mangled_name;
518 pstrcpy(mangled_name, fname);
519 name_map_mangle(mangled_name,True,True,SNUM(conn));
520 mangled_name[12] = 0;
521 len = srvstr_push(outbuf, p+2, mangled_name, 24, STR_UPPER);
528 len = srvstr_push(outbuf, p, fname, -1, STR_TERMINATE);
531 len = PTR_DIFF(p, pdata);
532 len = (len + 3) & ~3;
537 case SMB_FIND_FILE_DIRECTORY_INFO:
539 SIVAL(p,0,reskey); p += 4;
540 put_long_date(p,cdate); p += 8;
541 put_long_date(p,adate); p += 8;
542 put_long_date(p,mdate); p += 8;
543 put_long_date(p,mdate); p += 8;
547 SIVAL(p,0,nt_extmode); p += 4;
549 len = srvstr_push(outbuf, p, fname, -1, STR_TERMINATE);
552 len = PTR_DIFF(p, pdata);
553 len = (len + 3) & ~3;
559 case SMB_FIND_FILE_FULL_DIRECTORY_INFO:
561 SIVAL(p,0,reskey); p += 4;
562 put_long_date(p,cdate); p += 8;
563 put_long_date(p,adate); p += 8;
564 put_long_date(p,mdate); p += 8;
565 put_long_date(p,mdate); p += 8;
569 SIVAL(p,0,nt_extmode); p += 4;
571 SIVAL(p,0,0); p += 4;
573 len = srvstr_push(outbuf, p, fname, -1, STR_TERMINATE);
577 len = PTR_DIFF(p, pdata);
578 len = (len + 3) & ~3;
583 case SMB_FIND_FILE_NAMES_INFO:
585 SIVAL(p,0,reskey); p += 4;
587 len = srvstr_push(outbuf, p, fname, -1, STR_TERMINATE);
590 len = PTR_DIFF(p, pdata);
591 len = (len + 3) & ~3;
601 if (PTR_DIFF(p,pdata) > space_remaining) {
602 /* Move the dirptr back to prev_dirpos */
603 SeekDir(conn->dirptr, prev_dirpos);
604 *out_of_space = True;
605 DEBUG(9,("get_lanman2_dir_entry: out of space\n"));
606 return False; /* Not finished - just out of space */
609 /* Setup the last_filename pointer, as an offset from base_data */
610 *last_name_off = PTR_DIFF(nameptr,base_data);
611 /* Advance the data pointer to the next slot */
618 /****************************************************************************
619 Reply to a TRANS2_FINDFIRST.
620 ****************************************************************************/
622 static int call_trans2findfirst(connection_struct *conn,
623 char *inbuf, char *outbuf, int bufsize,
624 char **pparams, char **ppdata)
626 /* We must be careful here that we don't return more than the
627 allowed number of data bytes. If this means returning fewer than
628 maxentries then so be it. We assume that the redirector has
629 enough room for the fixed number of parameter bytes it has
631 uint32 max_data_bytes = SVAL(inbuf, smb_mdrcnt);
632 char *params = *pparams;
633 char *pdata = *ppdata;
634 int dirtype = SVAL(params,0);
635 int maxentries = SVAL(params,2);
636 BOOL close_after_first = BITSETW(params+4,0);
637 BOOL close_if_end = BITSETW(params+4,1);
638 BOOL requires_resume_key = BITSETW(params+4,2);
639 int info_level = SVAL(params,6);
647 BOOL finished = False;
648 BOOL dont_descend = False;
649 BOOL out_of_space = False;
651 BOOL bad_path = False;
652 SMB_STRUCT_STAT sbuf;
654 *directory = *mask = 0;
656 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",
657 dirtype, maxentries, close_after_first, close_if_end, requires_resume_key,
658 info_level, max_data_bytes));
666 case SMB_FIND_FILE_DIRECTORY_INFO:
667 case SMB_FIND_FILE_FULL_DIRECTORY_INFO:
668 case SMB_FIND_FILE_NAMES_INFO:
669 case SMB_FIND_FILE_BOTH_DIRECTORY_INFO:
672 return(ERROR_DOS(ERRDOS,ERRunknownlevel));
675 srvstr_pull(inbuf, directory, params+12, sizeof(directory), -1, STR_TERMINATE);
677 RESOLVE_FINDFIRST_DFSPATH(directory, conn, inbuf, outbuf);
679 unix_convert(directory,conn,0,&bad_path,&sbuf);
680 if(!check_name(directory,conn)) {
681 if((errno == ENOENT) && bad_path)
683 unix_ERR_class = ERRDOS;
684 unix_ERR_code = ERRbadpath;
688 /* Ugly - NT specific hack - maybe not needed ? (JRA) */
689 if((errno == ENOTDIR) && (Protocol >= PROTOCOL_NT1) &&
690 (get_remote_arch() == RA_WINNT))
692 unix_ERR_class = ERRDOS;
693 unix_ERR_code = ERRbaddirectory;
697 return(UNIXERROR(ERRDOS,ERRbadpath));
700 p = strrchr_m(directory,'/');
702 pstrcpy(mask,directory);
703 pstrcpy(directory,"./");
709 DEBUG(5,("dir=%s, mask = %s\n",directory, mask));
711 pdata = Realloc(*ppdata, max_data_bytes + 1024);
712 if( pdata == NULL ) {
713 return(ERROR_DOS(ERRDOS,ERRnomem));
716 memset((char *)pdata,'\0',max_data_bytes + 1024);
718 /* Realloc the params space */
719 params = Realloc(*pparams, 10);
720 if (params == NULL) {
721 return ERROR_DOS(ERRDOS,ERRnomem);
725 dptr_num = dptr_create(conn,directory, False, True ,SVAL(inbuf,smb_pid));
727 return(UNIXERROR(ERRDOS,ERRbadfile));
729 /* Save the wildcard match and attribs we are using on this directory -
730 needed as lanman2 assumes these are being saved between calls */
732 if(!(wcard = strdup(mask))) {
733 dptr_close(&dptr_num);
734 return ERROR_DOS(ERRDOS,ERRnomem);
737 dptr_set_wcard(dptr_num, wcard);
738 dptr_set_attr(dptr_num, dirtype);
740 DEBUG(4,("dptr_num is %d, wcard = %s, attr = %d\n",dptr_num, wcard, dirtype));
742 /* We don't need to check for VOL here as this is returned by
743 a different TRANS2 call. */
745 DEBUG(8,("dirpath=<%s> dontdescend=<%s>\n",
746 conn->dirpath,lp_dontdescend(SNUM(conn))));
747 if (in_list(conn->dirpath,lp_dontdescend(SNUM(conn)),case_sensitive))
751 space_remaining = max_data_bytes;
752 out_of_space = False;
754 for (i=0;(i<maxentries) && !finished && !out_of_space;i++)
756 BOOL got_exact_match = False;
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)
767 finished = !get_lanman2_dir_entry(conn,
769 mask,dirtype,info_level,
770 requires_resume_key,dont_descend,
771 &p,pdata,space_remaining, &out_of_space, &got_exact_match,
775 if (finished && out_of_space)
778 if (!finished && !out_of_space)
782 * As an optimisation if we know we aren't looking
783 * for a wildcard name (ie. the name matches the wildcard exactly)
784 * then we can finish on any (first) match.
785 * This speeds up large directory searches. JRA.
791 space_remaining = max_data_bytes - PTR_DIFF(p,pdata);
794 /* Check if we can close the dirptr */
795 if(close_after_first || (finished && close_if_end))
797 DEBUG(5,("call_trans2findfirst - (2) closing dptr_num %d\n", dptr_num));
798 dptr_close(&dptr_num);
802 * If there are no matching entries we must return ERRDOS/ERRbadfile -
803 * from observation of NT.
806 if(numentries == 0) {
807 dptr_close(&dptr_num);
808 return ERROR_DOS(ERRDOS,ERRbadfile);
811 /* At this point pdata points to numentries directory entries. */
813 /* Set up the return parameter block */
814 SSVAL(params,0,dptr_num);
815 SSVAL(params,2,numentries);
816 SSVAL(params,4,finished);
817 SSVAL(params,6,0); /* Never an EA error */
818 SSVAL(params,8,last_name_off);
820 send_trans2_replies( outbuf, bufsize, params, 10, pdata, PTR_DIFF(p,pdata));
822 if ((! *directory) && dptr_path(dptr_num))
823 slprintf(directory,sizeof(directory)-1, "(%s)",dptr_path(dptr_num));
825 DEBUG( 4, ( "%s mask=%s directory=%s dirtype=%d numentries=%d\n",
826 smb_fn_name(CVAL(inbuf,smb_com)),
827 mask, directory, dirtype, numentries ) );
830 * Force a name mangle here to ensure that the
831 * mask as an 8.3 name is top of the mangled cache.
832 * The reasons for this are subtle. Don't remove
833 * this code unless you know what you are doing
834 * (see PR#13758). JRA.
837 if(!is_8_3( mask, False))
838 name_map_mangle(mask, True, True, SNUM(conn));
844 /****************************************************************************
845 reply to a TRANS2_FINDNEXT
846 ****************************************************************************/
847 static int call_trans2findnext(connection_struct *conn,
848 char *inbuf, char *outbuf,
849 int length, int bufsize,
850 char **pparams, char **ppdata)
852 /* We must be careful here that we don't return more than the
853 allowed number of data bytes. If this means returning fewer than
854 maxentries then so be it. We assume that the redirector has
855 enough room for the fixed number of parameter bytes it has
857 int max_data_bytes = SVAL(inbuf, smb_mdrcnt);
858 char *params = *pparams;
859 char *pdata = *ppdata;
860 int dptr_num = SVAL(params,0);
861 int maxentries = SVAL(params,2);
862 uint16 info_level = SVAL(params,4);
863 uint32 resume_key = IVAL(params,6);
864 BOOL close_after_request = BITSETW(params+10,0);
865 BOOL close_if_end = BITSETW(params+10,1);
866 BOOL requires_resume_key = BITSETW(params+10,2);
867 BOOL continue_bit = BITSETW(params+10,3);
874 int i, last_name_off=0;
875 BOOL finished = False;
876 BOOL dont_descend = False;
877 BOOL out_of_space = False;
880 *mask = *directory = *resume_name = 0;
882 srvstr_pull(inbuf, resume_name, params+12, sizeof(resume_name), -1, STR_TERMINATE);
884 DEBUG(3,("call_trans2findnext: dirhandle = %d, max_data_bytes = %d, maxentries = %d, \
885 close_after_request=%d, close_if_end = %d requires_resume_key = %d \
886 resume_key = %d resume name = %s continue=%d level = %d\n",
887 dptr_num, max_data_bytes, maxentries, close_after_request, close_if_end,
888 requires_resume_key, resume_key, resume_name, continue_bit, info_level));
896 case SMB_FIND_FILE_DIRECTORY_INFO:
897 case SMB_FIND_FILE_FULL_DIRECTORY_INFO:
898 case SMB_FIND_FILE_NAMES_INFO:
899 case SMB_FIND_FILE_BOTH_DIRECTORY_INFO:
902 return ERROR_DOS(ERRDOS,ERRunknownlevel);
905 pdata = Realloc( *ppdata, max_data_bytes + 1024);
907 return ERROR_DOS(ERRDOS,ERRnomem);
910 memset((char *)pdata,'\0',max_data_bytes + 1024);
912 /* Realloc the params space */
913 params = Realloc(*pparams, 6*SIZEOFWORD);
914 if( params == NULL ) {
915 return ERROR_DOS(ERRDOS,ERRnomem);
919 /* Check that the dptr is valid */
920 if(!(conn->dirptr = dptr_fetch_lanman2(dptr_num)))
921 return ERROR_DOS(ERRDOS,ERRnofiles);
923 string_set(&conn->dirpath,dptr_path(dptr_num));
925 /* Get the wildcard mask from the dptr */
926 if((p = dptr_wcard(dptr_num))== NULL) {
927 DEBUG(2,("dptr_num %d has no wildcard\n", dptr_num));
928 return ERROR_DOS(ERRDOS,ERRnofiles);
931 pstrcpy(directory,conn->dirpath);
933 /* Get the attr mask from the dptr */
934 dirtype = dptr_attr(dptr_num);
936 DEBUG(3,("dptr_num is %d, mask = %s, attr = %x, dirptr=(0x%lX,%d)\n",
937 dptr_num, mask, dirtype,
939 TellDir(conn->dirptr)));
941 /* We don't need to check for VOL here as this is returned by
942 a different TRANS2 call. */
944 DEBUG(8,("dirpath=<%s> dontdescend=<%s>\n",conn->dirpath,lp_dontdescend(SNUM(conn))));
945 if (in_list(conn->dirpath,lp_dontdescend(SNUM(conn)),case_sensitive))
949 space_remaining = max_data_bytes;
950 out_of_space = False;
953 * Seek to the correct position. We no longer use the resume key but
954 * depend on the last file name instead.
956 if(requires_resume_key && *resume_name && !continue_bit)
959 * Fix for NT redirector problem triggered by resume key indexes
960 * changing between directory scans. We now return a resume key of 0
961 * and instead look for the filename to continue from (also given
962 * to us by NT/95/smbfs/smbclient). If no other scans have been done between the
963 * findfirst/findnext (as is usual) then the directory pointer
964 * should already be at the correct place. Check this by scanning
965 * backwards looking for an exact (ie. case sensitive) filename match.
966 * If we get to the beginning of the directory and haven't found it then scan
967 * forwards again looking for a match. JRA.
970 int current_pos, start_pos;
972 void *dirptr = conn->dirptr;
973 start_pos = TellDir(dirptr);
974 for(current_pos = start_pos; current_pos >= 0; current_pos--)
976 DEBUG(7,("call_trans2findnext: seeking to pos %d\n", current_pos));
978 SeekDir(dirptr, current_pos);
979 dname = ReadDirName(dirptr);
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, True, 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 ));
1000 * Scan forward from start if not found going backwards.
1005 DEBUG(7,("call_trans2findnext: notfound: seeking to pos %d\n", start_pos));
1006 SeekDir(dirptr, start_pos);
1007 for(current_pos = start_pos; (dname = ReadDirName(dirptr)) != NULL; SeekDir(dirptr,++current_pos))
1010 * Remember, name_map_mangle is called by
1011 * get_lanman2_dir_entry(), so the resume name
1012 * could be mangled. Ensure we do the same
1017 name_map_mangle( dname, False, True, SNUM(conn));
1019 if(dname && strcsequal( resume_name, dname))
1021 SeekDir(dirptr, current_pos+1);
1022 DEBUG(7,("call_trans2findnext: got match at pos %d\n", current_pos+1 ));
1026 } /* end if current_pos */
1027 } /* end if requires_resume_key && !continue_bit */
1029 for (i=0;(i<(int)maxentries) && !finished && !out_of_space ;i++)
1031 BOOL got_exact_match = False;
1033 /* this is a heuristic to avoid seeking the dirptr except when
1034 absolutely necessary. It allows for a filename of about 40 chars */
1035 if (space_remaining < DIRLEN_GUESS && numentries > 0)
1037 out_of_space = True;
1042 finished = !get_lanman2_dir_entry(conn,
1044 mask,dirtype,info_level,
1045 requires_resume_key,dont_descend,
1046 &p,pdata,space_remaining, &out_of_space, &got_exact_match,
1050 if (finished && out_of_space)
1053 if (!finished && !out_of_space)
1057 * As an optimisation if we know we aren't looking
1058 * for a wildcard name (ie. the name matches the wildcard exactly)
1059 * then we can finish on any (first) match.
1060 * This speeds up large directory searches. JRA.
1066 space_remaining = max_data_bytes - PTR_DIFF(p,pdata);
1069 /* Check if we can close the dirptr */
1070 if(close_after_request || (finished && close_if_end))
1072 DEBUG(5,("call_trans2findnext: closing dptr_num = %d\n", dptr_num));
1073 dptr_close(&dptr_num); /* This frees up the saved mask */
1077 /* Set up the return parameter block */
1078 SSVAL(params,0,numentries);
1079 SSVAL(params,2,finished);
1080 SSVAL(params,4,0); /* Never an EA error */
1081 SSVAL(params,6,last_name_off);
1083 send_trans2_replies( outbuf, bufsize, params, 8, pdata, PTR_DIFF(p,pdata));
1085 if ((! *directory) && dptr_path(dptr_num))
1086 slprintf(directory,sizeof(directory)-1, "(%s)",dptr_path(dptr_num));
1088 DEBUG( 3, ( "%s mask=%s directory=%s dirtype=%d numentries=%d\n",
1089 smb_fn_name(CVAL(inbuf,smb_com)),
1090 mask, directory, dirtype, numentries ) );
1095 /****************************************************************************
1096 reply to a TRANS2_QFSINFO (query filesystem info)
1097 ****************************************************************************/
1099 static int call_trans2qfsinfo(connection_struct *conn,
1100 char *inbuf, char *outbuf,
1101 int length, int bufsize,
1102 char **pparams, char **ppdata)
1104 int max_data_bytes = SVAL(inbuf, smb_mdrcnt);
1105 char *pdata = *ppdata;
1106 char *params = *pparams;
1107 uint16 info_level = SVAL(params,0);
1110 char *vname = volume_label(SNUM(conn));
1111 int snum = SNUM(conn);
1112 char *fstype = lp_fstype(SNUM(conn));
1114 DEBUG(3,("call_trans2qfsinfo: level = %d\n", info_level));
1116 if(vfs_stat(conn,".",&st)!=0) {
1117 DEBUG(2,("call_trans2qfsinfo: stat of . failed (%s)\n", strerror(errno)));
1118 return ERROR_DOS(ERRSRV,ERRinvdevice);
1121 pdata = Realloc(*ppdata, max_data_bytes + 1024);
1122 if ( pdata == NULL ) {
1123 return ERROR_DOS(ERRDOS,ERRnomem);
1126 memset((char *)pdata,'\0',max_data_bytes + 1024);
1132 SMB_BIG_UINT dfree,dsize,bsize;
1134 conn->vfs_ops.disk_free(conn,".",False,&bsize,&dfree,&dsize);
1135 SIVAL(pdata,l1_idFileSystem,st.st_dev);
1136 SIVAL(pdata,l1_cSectorUnit,bsize/512);
1137 SIVAL(pdata,l1_cUnit,dsize);
1138 SIVAL(pdata,l1_cUnitAvail,dfree);
1139 SSVAL(pdata,l1_cbSector,512);
1140 DEBUG(5,("call_trans2qfsinfo : bsize=%u, id=%x, cSectorUnit=%u, cUnit=%u, cUnitAvail=%u, cbSector=%d\n",
1141 (unsigned int)bsize, (unsigned int)st.st_dev, ((unsigned int)bsize)/512, (unsigned int)dsize,
1142 (unsigned int)dfree, 512));
1146 /* Return volume name */
1148 * Add volume serial number - hash of a combination of
1149 * the called hostname and the service name.
1151 SIVAL(pdata,0,str_checksum(lp_servicename(snum)) ^ (str_checksum(local_machine)<<16) );
1152 len = srvstr_push(outbuf, pdata+l2_vol_szVolLabel, vname, -1,
1154 SCVAL(pdata,l2_vol_cch,len);
1155 data_len = l2_vol_szVolLabel + len;
1156 DEBUG(5,("call_trans2qfsinfo : time = %x, namelen = %d, name = %s\n",
1157 (unsigned)st.st_ctime, len, vname));
1160 case SMB_QUERY_FS_ATTRIBUTE_INFO:
1161 SIVAL(pdata,0,FILE_CASE_PRESERVED_NAMES|FILE_CASE_SENSITIVE_SEARCH|
1162 FILE_DEVICE_IS_MOUNTED|
1163 (lp_nt_acl_support() ? FILE_PERSISTENT_ACLS : 0)); /* FS ATTRIBUTES */
1164 SIVAL(pdata,4,255); /* Max filename component length */
1165 len = srvstr_push(outbuf, pdata+12, fstype, -1, STR_TERMINATE);
1167 data_len = 12 + len;
1170 case SMB_QUERY_FS_LABEL_INFO:
1171 len = srvstr_push(outbuf, pdata+4, vname, -1, STR_TERMINATE);
1175 case SMB_QUERY_FS_VOLUME_INFO:
1177 * Add volume serial number - hash of a combination of
1178 * the called hostname and the service name.
1180 SIVAL(pdata,8,str_checksum(lp_servicename(snum)) ^
1181 (str_checksum(local_machine)<<16));
1183 len = srvstr_push(outbuf, pdata+18, vname, -1, STR_TERMINATE);
1184 SIVAL(pdata,12,len);
1186 DEBUG(5,("call_trans2qfsinfo : SMB_QUERY_FS_VOLUME_INFO namelen = %d, vol=%s serv=%s\n",
1187 (int)strlen(vname),vname, lp_servicename(snum)));
1189 case SMB_QUERY_FS_SIZE_INFO:
1191 SMB_BIG_UINT dfree,dsize,bsize;
1193 conn->vfs_ops.disk_free(conn,".",False,&bsize,&dfree,&dsize);
1194 SBIG_UINT(pdata,0,dsize);
1195 SBIG_UINT(pdata,8,dfree);
1196 SIVAL(pdata,16,bsize/512);
1197 SIVAL(pdata,20,512);
1200 case SMB_QUERY_FS_DEVICE_INFO:
1202 SIVAL(pdata,0,0); /* dev type */
1203 SIVAL(pdata,4,0); /* characteristics */
1205 case SMB_MAC_QUERY_FS_INFO:
1207 * Thursby MAC extension... ONLY on NTFS filesystems
1208 * once we do streams then we don't need this
1210 if (strequal(lp_fstype(SNUM(conn)),"NTFS")) {
1212 SIVAL(pdata,84,0x100); /* Don't support mac... */
1217 return ERROR_DOS(ERRDOS,ERRunknownlevel);
1221 send_trans2_replies( outbuf, bufsize, params, 0, pdata, data_len);
1223 DEBUG( 4, ( "%s info_level = %d\n",
1224 smb_fn_name(CVAL(inbuf,smb_com)), info_level) );
1229 /****************************************************************************
1230 reply to a TRANS2_SETFSINFO (set filesystem info)
1231 ****************************************************************************/
1232 static int call_trans2setfsinfo(connection_struct *conn,
1233 char *inbuf, char *outbuf, int length,
1235 char **pparams, char **ppdata)
1237 /* Just say yes we did it - there is nothing that
1238 can be set here so it doesn't matter. */
1240 DEBUG(3,("call_trans2setfsinfo\n"));
1242 if (!CAN_WRITE(conn))
1243 return ERROR_DOS(ERRSRV,ERRaccess);
1245 outsize = set_message(outbuf,10,0,True);
1250 /****************************************************************************
1251 Reply to a TRANS2_QFILEPATHINFO or TRANSACT2_QFILEINFO (query file info by
1252 file name or file id).
1253 ****************************************************************************/
1255 static int call_trans2qfilepathinfo(connection_struct *conn,
1256 char *inbuf, char *outbuf, int length,
1258 char **pparams,char **ppdata,
1261 int max_data_bytes = SVAL(inbuf, smb_mdrcnt);
1262 char *params = *pparams;
1263 char *pdata = *ppdata;
1264 uint16 tran_call = SVAL(inbuf, smb_setup0);
1268 unsigned int data_size;
1269 SMB_STRUCT_STAT sbuf;
1274 BOOL bad_path = False;
1275 BOOL delete_pending = False;
1279 if (tran_call == TRANSACT2_QFILEINFO) {
1280 files_struct *fsp = file_fsp(params,0);
1281 info_level = SVAL(params,2);
1283 DEBUG(3,("call_trans2qfilepathinfo: TRANSACT2_QFILEINFO: level = %d\n",
1286 if(fsp && (fsp->is_directory || fsp->stat_open)) {
1288 * This is actually a QFILEINFO on a directory
1289 * handle (returned from an NT SMB). NT5.0 seems
1290 * to do this call. JRA.
1292 pstrcpy(fname, fsp->fsp_name);
1293 unix_convert(fname,conn,0,&bad_path,&sbuf);
1294 if (!check_name(fname,conn) ||
1295 (!VALID_STAT(sbuf) && vfs_stat(conn,fname,&sbuf))) {
1296 DEBUG(3,("fileinfo of %s failed (%s)\n",fname,strerror(errno)));
1297 if((errno == ENOENT) && bad_path) {
1298 unix_ERR_class = ERRDOS;
1299 unix_ERR_code = ERRbadpath;
1301 return(UNIXERROR(ERRDOS,ERRbadpath));
1304 delete_pending = fsp->directory_delete_on_close;
1307 * Original code - this is an open file.
1309 CHECK_FSP(fsp,conn);
1311 pstrcpy(fname, fsp->fsp_name);
1312 if (vfs_fstat(fsp,fsp->fd,&sbuf) != 0) {
1313 DEBUG(3,("fstat of fnum %d failed (%s)\n",
1314 fsp->fnum, strerror(errno)));
1315 return(UNIXERROR(ERRDOS,ERRbadfid));
1317 if((pos = fsp->conn->vfs_ops.lseek(fsp,fsp->fd,0,SEEK_CUR)) == -1)
1318 return(UNIXERROR(ERRDOS,ERRnoaccess));
1320 delete_pending = fsp->delete_on_close;
1324 info_level = SVAL(params,0);
1326 DEBUG(3,("call_trans2qfilepathinfo: TRANSACT2_QPATHINFO: level = %d\n",
1329 srvstr_pull(inbuf, fname, ¶ms[6], sizeof(fname), -1, STR_TERMINATE);
1331 RESOLVE_DFSPATH(fname, conn, inbuf, outbuf);
1333 unix_convert(fname,conn,0,&bad_path,&sbuf);
1334 if (!check_name(fname,conn) ||
1335 (!VALID_STAT(sbuf) && vfs_stat(conn,fname,&sbuf))) {
1336 DEBUG(3,("fileinfo of %s failed (%s)\n",fname,strerror(errno)));
1337 if((errno == ENOENT) && bad_path) {
1338 unix_ERR_class = ERRDOS;
1339 unix_ERR_code = ERRbadpath;
1341 return(UNIXERROR(ERRDOS,ERRbadpath));
1346 DEBUG(3,("call_trans2qfilepathinfo %s level=%d call=%d total_data=%d\n",
1347 fname,info_level,tran_call,total_data));
1349 p = strrchr_m(fname,'/');
1356 mode = dos_mode(conn,fname,&sbuf);
1357 size = sbuf.st_size;
1358 if (mode & aDIR) size = 0;
1360 params = Realloc(*pparams,2);
1361 if (params == NULL) {
1362 return ERROR_DOS(ERRDOS,ERRnomem);
1365 memset((char *)params,'\0',2);
1366 data_size = max_data_bytes + 1024;
1367 pdata = Realloc(*ppdata, data_size);
1368 if ( pdata == NULL ) {
1369 return ERROR_DOS(ERRDOS,ERRnomem);
1373 if (total_data > 0 && IVAL(pdata,0) == total_data) {
1374 /* uggh, EAs for OS2 */
1375 DEBUG(4,("Rejecting EA request with total_data=%d\n",total_data));
1376 return ERROR_DOS(ERRDOS,ERReasnotsupported);
1379 memset((char *)pdata,'\0',data_size);
1381 c_time = get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(conn)));
1383 if (lp_dos_filetime_resolution(SNUM(conn))) {
1385 sbuf.st_atime &= ~1;
1386 sbuf.st_mtime &= ~1;
1387 sbuf.st_mtime &= ~1;
1392 case SMB_INFO_STANDARD:
1393 case SMB_INFO_QUERY_EA_SIZE:
1394 data_size = (info_level==1?22:26);
1395 put_dos_date2(pdata,l1_fdateCreation,c_time);
1396 put_dos_date2(pdata,l1_fdateLastAccess,sbuf.st_atime);
1397 put_dos_date2(pdata,l1_fdateLastWrite,sbuf.st_mtime); /* write time */
1398 SIVAL(pdata,l1_cbFile,(uint32)size);
1399 SIVAL(pdata,l1_cbFileAlloc,SMB_ROUNDUP(size,1024));
1400 SSVAL(pdata,l1_attrFile,mode);
1401 SIVAL(pdata,l1_attrFile+2,4); /* this is what OS2 does */
1404 case SMB_INFO_QUERY_EAS_FROM_LIST:
1406 put_dos_date2(pdata,0,c_time);
1407 put_dos_date2(pdata,4,sbuf.st_atime);
1408 put_dos_date2(pdata,8,sbuf.st_mtime);
1409 SIVAL(pdata,12,(uint32)size);
1410 SIVAL(pdata,16,SMB_ROUNDUP(size,1024));
1411 SIVAL(pdata,20,mode);
1414 case SMB_INFO_QUERY_ALL_EAS:
1416 SIVAL(pdata,0,data_size);
1420 return ERROR_DOS(ERRDOS,ERRbadfunc); /* os/2 needs this */
1422 case SMB_QUERY_FILE_BASIC_INFO:
1425 if (info_level == SMB_QUERY_FILE_BASIC_INFO)
1426 data_size = 36; /* w95 returns 40 bytes not 36 - why ?. */
1431 put_long_date(pdata,c_time);
1432 put_long_date(pdata+8,sbuf.st_atime);
1433 put_long_date(pdata+16,sbuf.st_mtime); /* write time */
1434 put_long_date(pdata+24,sbuf.st_mtime); /* change time */
1435 SIVAL(pdata,32,mode);
1437 DEBUG(5,("SMB_QFBI - "));
1439 time_t create_time = c_time;
1440 DEBUG(5,("create: %s ", ctime(&create_time)));
1442 DEBUG(5,("access: %s ", ctime(&sbuf.st_atime)));
1443 DEBUG(5,("write: %s ", ctime(&sbuf.st_mtime)));
1444 DEBUG(5,("change: %s ", ctime(&sbuf.st_mtime)));
1445 DEBUG(5,("mode: %x\n", mode));
1449 case SMB_QUERY_FILE_STANDARD_INFO:
1451 SOFF_T(pdata,0,size);
1452 SOFF_T(pdata,8,size);
1453 SIVAL(pdata,16,sbuf.st_nlink);
1455 CVAL(pdata,21) = (mode&aDIR)?1:0;
1458 case SMB_QUERY_FILE_EA_INFO:
1462 /* Get the 8.3 name - used if NT SMB was negotiated. */
1463 case SMB_QUERY_FILE_ALT_NAME_INFO:
1467 pstrcpy(short_name,base_name);
1468 /* Mangle if not already 8.3 */
1469 if(!is_8_3(short_name, True))
1471 if(!name_map_mangle(short_name,True,True,SNUM(conn)))
1474 len = srvstr_push(outbuf, pdata+4, short_name, -1,
1475 STR_TERMINATE|STR_UPPER);
1476 data_size = 4 + len;
1481 case SMB_QUERY_FILE_NAME_INFO:
1483 * The first part of this code is essential
1484 * to get security descriptors to work on mapped
1485 * drives. Don't ask how I discovered this unless
1486 * you like hearing about me suffering.... :-). JRA.
1488 if(strequal(".", fname)) {
1489 len = srvstr_push(outbuf, pdata+4, "\\", -1, STR_TERMINATE);
1491 len = srvstr_push(outbuf, pdata+4, fname, -1, STR_TERMINATE);
1493 data_size = 4 + len;
1497 case SMB_QUERY_FILE_ALLOCATION_INFO:
1498 case SMB_QUERY_FILE_END_OF_FILEINFO:
1500 SOFF_T(pdata,0,size);
1503 case SMB_QUERY_FILE_ALL_INFO:
1504 put_long_date(pdata,c_time);
1505 put_long_date(pdata+8,sbuf.st_atime);
1506 put_long_date(pdata+16,sbuf.st_mtime); /* write time */
1507 put_long_date(pdata+24,sbuf.st_mtime); /* change time */
1508 SIVAL(pdata,32,mode);
1510 SOFF_T(pdata,0,size);
1511 SOFF_T(pdata,8,size);
1512 SIVAL(pdata,16,sbuf.st_nlink);
1513 CVAL(pdata,20) = delete_pending;
1514 CVAL(pdata,21) = (mode&aDIR)?1:0;
1516 SINO_T(pdata,0,(SMB_INO_T)sbuf.st_ino);
1517 pdata += 8; /* index number */
1518 pdata += 4; /* EA info */
1520 SIVAL(pdata,0,0xA9);
1522 SIVAL(pdata,0,0xd01BF);
1524 SOFF_T(pdata,0,pos); /* current offset */
1526 SIVAL(pdata,0,mode); /* is this the right sort of mode info? */
1528 pdata += 4; /* alignment */
1529 len = srvstr_push(outbuf, pdata+4, fname, -1, STR_TERMINATE);
1532 data_size = PTR_DIFF(pdata,(*ppdata));
1536 * Windows 2000 completely undocumented new SMB info levels.
1537 * Thanks Microsoft.... sure you're working on making this
1538 * protocol a standard.... sure you are... :-).
1539 * Lying rat-bastards. JRA.
1543 SIVAL(pdata,0,mode);
1544 SIVAL(pdata,4,0); /* ??? */
1545 SOFF_T(pdata,8,size);
1546 SIVAL(pdata,16,1); /* ??? */
1547 SIVAL(pdata,20,0); /* ??? */
1552 SIVAL(pdata,0,0x907); /* ??? */
1553 SIVAL(pdata,4,0x690000); /* ??? */
1558 SIVAL(pdata,0,0); /* ??? */
1563 SIVAL(pdata,0,0x12019F); /* ??? */
1568 /* Pathname with leading '\'. */
1573 pstrcpy(new_fname, "\\");
1574 pstrcat(new_fname, fname);
1575 byte_len = dos_PutUniCode(pdata+4,new_fname,max_data_bytes,False);
1576 SIVAL(pdata,0,byte_len);
1577 data_size = 4 + byte_len;
1582 SIVAL(pdata,0,0); /* ??? */
1583 SIVAL(pdata,4,0); /* ??? */
1588 SIVAL(pdata,0,0); /* ??? */
1593 SIVAL(pdata,0,0); /* ??? */
1598 /* Not yet finished... JRA */
1604 put_long_date(pdata,c_time);
1605 put_long_date(pdata+8,sbuf.st_atime);
1606 put_long_date(pdata+16,sbuf.st_mtime); /* write time */
1607 put_long_date(pdata+24,sbuf.st_mtime); /* change time */
1608 SIVAL(pdata,32,mode);
1609 SIVAL(pdata,36,0); /* ??? */
1610 SIVAL(pdata,40,0x20); /* ??? */
1611 SIVAL(pdata,44,0); /* ??? */
1612 SOFF_T(pdata,48,size);
1613 SIVAL(pdata,56,0x1); /* ??? */
1614 SIVAL(pdata,60,0); /* ??? */
1615 SIVAL(pdata,64,0); /* ??? */
1616 SIVAL(pdata,68,length); /* Following string length in bytes. */
1617 dos_PutUniCode(pdata+72,,False);
1623 /* Last component of pathname. */
1625 size_t byte_len = dos_PutUniCode(pdata+4,fname,max_data_bytes,False);
1626 SIVAL(pdata,0,byte_len);
1627 data_size = 4 + byte_len;
1631 case SMB_FILE_STREAM_INFORMATION:
1635 size_t byte_len = dos_PutUniCode(pdata+24,"::$DATA", 0xE, False);
1636 SIVAL(pdata,0,0); /* ??? */
1637 SIVAL(pdata,4,byte_len); /* Byte length of unicode string ::$DATA */
1638 SOFF_T(pdata,8,size);
1639 SIVAL(pdata,16,0x20); /* ??? */
1640 SIVAL(pdata,20,0); /* ??? */
1641 data_size = 24 + byte_len;
1646 SOFF_T(pdata,0,size);
1647 SIVAL(pdata,8,0); /* ??? */
1648 SIVAL(pdata,12,0); /* ??? */
1653 put_long_date(pdata,c_time);
1654 put_long_date(pdata+8,sbuf.st_atime);
1655 put_long_date(pdata+16,sbuf.st_mtime); /* write time */
1656 put_long_date(pdata+24,sbuf.st_mtime); /* change time */
1657 SIVAL(pdata,32,0x20); /* ??? */
1658 SIVAL(pdata,36,0); /* ??? */
1659 SOFF_T(pdata,40,size);
1660 SIVAL(pdata,48,mode);
1661 SIVAL(pdata,52,0); /* ??? */
1666 SIVAL(pdata,0,mode);
1672 * End new completely undocumented info levels... JRA.
1676 /* NT4 server just returns "invalid query" to this - if we try to answer
1677 it then NTws gets a BSOD! (tridge) */
1678 case SMB_QUERY_FILE_STREAM_INFO:
1680 SIVAL(pdata,4,size);
1681 SIVAL(pdata,12,size);
1682 len = srvstr_push(outbuf, pdata+24, fname, -1, STR_TERMINATE);
1683 SIVAL(pdata,20,len);
1684 data_size = 24 + len;
1689 return ERROR_DOS(ERRDOS,ERRunknownlevel);
1692 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, data_size);
1697 /****************************************************************************
1698 reply to a TRANS2_SETFILEINFO (set file info by fileid)
1699 ****************************************************************************/
1700 static int call_trans2setfilepathinfo(connection_struct *conn,
1701 char *inbuf, char *outbuf, int length,
1702 int bufsize, char **pparams,
1703 char **ppdata, int total_data)
1705 char *params = *pparams;
1706 char *pdata = *ppdata;
1707 uint16 tran_call = SVAL(inbuf, smb_setup0);
1712 SMB_STRUCT_STAT sbuf;
1715 BOOL bad_path = False;
1716 files_struct *fsp = NULL;
1718 if (tran_call == TRANSACT2_SETFILEINFO) {
1719 fsp = file_fsp(params,0);
1720 info_level = SVAL(params,2);
1722 if(fsp && (fsp->is_directory || fsp->stat_open)) {
1724 * This is actually a SETFILEINFO on a directory
1725 * handle (returned from an NT SMB). NT5.0 seems
1726 * to do this call. JRA.
1728 pstrcpy(fname, fsp->fsp_name);
1729 unix_convert(fname,conn,0,&bad_path,&sbuf);
1730 if (!check_name(fname,conn) || (!VALID_STAT(sbuf))) {
1731 DEBUG(3,("fileinfo of %s failed (%s)\n",fname,strerror(errno)));
1732 if((errno == ENOENT) && bad_path)
1734 unix_ERR_class = ERRDOS;
1735 unix_ERR_code = ERRbadpath;
1737 return(UNIXERROR(ERRDOS,ERRbadpath));
1739 } else if (fsp && fsp->print_file) {
1741 * Doing a DELETE_ON_CLOSE should cancel a print job.
1743 if ((info_level == SMB_SET_FILE_DISPOSITION_INFO) && CVAL(pdata,0)) {
1744 fsp->share_mode = FILE_DELETE_ON_CLOSE;
1746 DEBUG(3,("call_trans2setfilepathinfo: Cancelling print job (%s)\n",
1750 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
1755 * Original code - this is an open file.
1757 CHECK_FSP(fsp,conn);
1759 pstrcpy(fname, fsp->fsp_name);
1762 if (vfs_fstat(fsp,fd,&sbuf) != 0) {
1763 DEBUG(3,("fstat of fnum %d failed (%s)\n",fsp->fnum, strerror(errno)));
1764 return(UNIXERROR(ERRDOS,ERRbadfid));
1769 info_level = SVAL(params,0);
1770 srvstr_pull(inbuf, fname, ¶ms[6], sizeof(fname), -1, STR_TERMINATE);
1771 unix_convert(fname,conn,0,&bad_path,&sbuf);
1772 if(!check_name(fname, conn))
1774 if((errno == ENOENT) && bad_path)
1776 unix_ERR_class = ERRDOS;
1777 unix_ERR_code = ERRbadpath;
1779 return(UNIXERROR(ERRDOS,ERRbadpath));
1782 if(!VALID_STAT(sbuf)) {
1783 DEBUG(3,("stat of %s failed (%s)\n", fname, strerror(errno)));
1784 if((errno == ENOENT) && bad_path)
1786 unix_ERR_class = ERRDOS;
1787 unix_ERR_code = ERRbadpath;
1789 return(UNIXERROR(ERRDOS,ERRbadpath));
1793 if (!CAN_WRITE(conn))
1794 return ERROR_DOS(ERRSRV,ERRaccess);
1796 DEBUG(3,("call_trans2setfilepathinfo(%d) %s info_level=%d totdata=%d\n",
1797 tran_call,fname,info_level,total_data));
1799 /* Realloc the parameter and data sizes */
1800 params = Realloc(*pparams,2);
1801 if(params == NULL) {
1802 return ERROR_DOS(ERRDOS,ERRnomem);
1808 size = sbuf.st_size;
1809 tvs.modtime = sbuf.st_mtime;
1810 tvs.actime = sbuf.st_atime;
1811 mode = dos_mode(conn,fname,&sbuf);
1813 if (total_data > 4 && IVAL(pdata,0) == total_data) {
1814 /* uggh, EAs for OS2 */
1815 DEBUG(4,("Rejecting EA request with total_data=%d\n",total_data));
1816 return ERROR_DOS(ERRDOS,ERReasnotsupported);
1821 case SMB_INFO_STANDARD:
1822 case SMB_INFO_QUERY_EA_SIZE:
1825 tvs.actime = make_unix_date2(pdata+l1_fdateLastAccess);
1828 tvs.modtime = make_unix_date2(pdata+l1_fdateLastWrite);
1830 mode = SVAL(pdata,l1_attrFile);
1831 size = IVAL(pdata,l1_cbFile);
1835 /* XXXX um, i don't think this is right.
1836 it's also not in the cifs6.txt spec.
1838 case SMB_INFO_QUERY_EAS_FROM_LIST:
1839 tvs.actime = make_unix_date2(pdata+8);
1840 tvs.modtime = make_unix_date2(pdata+12);
1841 size = IVAL(pdata,16);
1842 mode = IVAL(pdata,24);
1845 /* XXXX nor this. not in cifs6.txt, either. */
1846 case SMB_INFO_QUERY_ALL_EAS:
1847 tvs.actime = make_unix_date2(pdata+8);
1848 tvs.modtime = make_unix_date2(pdata+12);
1849 size = IVAL(pdata,16);
1850 mode = IVAL(pdata,24);
1853 case SMB_SET_FILE_BASIC_INFO:
1856 /* Patch to do this correctly from Paul Eggert <eggert@twinsun.com>. */
1858 time_t changed_time;
1860 /* Ignore create time at offset pdata. */
1863 tvs.actime = interpret_long_date(pdata+8);
1865 write_time = interpret_long_date(pdata+16);
1866 changed_time = interpret_long_date(pdata+24);
1868 tvs.modtime = MIN(write_time, changed_time);
1870 /* Prefer a defined time to an undefined one. */
1871 if (tvs.modtime == (time_t)0 || tvs.modtime == (time_t)-1)
1872 tvs.modtime = (write_time == (time_t)0 || write_time == (time_t)-1
1877 mode = IVAL(pdata,32);
1883 case SMB_SET_FILE_ALLOCATION_INFO:
1886 size = IVAL(pdata,0);
1887 #ifdef LARGE_SMB_OFF_T
1888 size |= (((SMB_OFF_T)IVAL(pdata,4)) << 32);
1889 #else /* LARGE_SMB_OFF_T */
1890 if (IVAL(pdata,4) != 0) /* more than 32 bits? */
1891 return ERROR_DOS(ERRDOS,ERRunknownlevel);
1892 #endif /* LARGE_SMB_OFF_T */
1893 DEBUG(10,("call_trans2setfilepathinfo: Set file allocation info for file %s to %.0f\n",
1894 fname, (double)size ));
1896 if(size != sbuf.st_size) {
1898 DEBUG(10,("call_trans2setfilepathinfo: file %s : setting new size to %.0f\n",
1899 fname, (double)size ));
1902 files_struct *new_fsp = NULL;
1903 int access_mode = 0;
1906 if(global_oplock_break) {
1907 /* Queue this file modify as we are the process of an oplock break. */
1909 DEBUG(2,("call_trans2setfilepathinfo: queueing message due to being "));
1910 DEBUGADD(2,( "in oplock break state.\n"));
1912 push_oplock_pending_smb_message(inbuf, length);
1916 new_fsp = open_file_shared(conn, fname, &sbuf,
1917 SET_OPEN_MODE(DOS_OPEN_RDWR),
1918 (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN),
1919 0, 0, &access_mode, &action);
1921 if (new_fsp == NULL)
1922 return(UNIXERROR(ERRDOS,ERRbadpath));
1923 ret = vfs_allocate_file_space(new_fsp, size);
1924 close_file(new_fsp,True);
1926 ret = vfs_allocate_file_space(fsp, size);
1928 if (ret == -1) return ERROR_NT(NT_STATUS_DISK_FULL);
1930 sbuf.st_size = size;
1936 case SMB_SET_FILE_END_OF_FILE_INFO:
1938 size = IVAL(pdata,0);
1939 #ifdef LARGE_SMB_OFF_T
1940 size |= (((SMB_OFF_T)IVAL(pdata,4)) << 32);
1941 #else /* LARGE_SMB_OFF_T */
1942 if (IVAL(pdata,4) != 0) /* more than 32 bits? */
1943 return ERROR_DOS(ERRDOS,ERRunknownlevel);
1944 #endif /* LARGE_SMB_OFF_T */
1945 DEBUG(10,("call_trans2setfilepathinfo: Set end of file info for file %s to %.0f\n", fname, (double)size ));
1949 case SMB_FILE_DISPOSITION_INFORMATION:
1950 case SMB_SET_FILE_DISPOSITION_INFO: /* Set delete on close for open file. */
1952 BOOL delete_on_close = (CVAL(pdata,0) ? True : False);
1954 if (tran_call != TRANSACT2_SETFILEINFO)
1955 return ERROR_DOS(ERRDOS,ERRunknownlevel);
1958 return(UNIXERROR(ERRDOS,ERRbadfid));
1961 * Only allow delete on close for files/directories opened with delete intent.
1964 if (delete_on_close && !GET_DELETE_ACCESS_REQUESTED(fsp->share_mode)) {
1965 DEBUG(10,("call_trans2setfilepathinfo: file %s delete on close flag set but delete access denied.\n",
1967 return ERROR_DOS(ERRDOS,ERRnoaccess);
1970 if(fsp->is_directory) {
1971 fsp->directory_delete_on_close = delete_on_close;
1972 DEBUG(10, ("call_trans2setfilepathinfo: %s delete on close flag for fnum = %d, directory %s\n",
1973 delete_on_close ? "Added" : "Removed", fsp->fnum, fsp->fsp_name ));
1974 } else if(fsp->stat_open) {
1976 DEBUG(10, ("call_trans2setfilepathinfo: %s delete on close flag for fnum = %d, stat open %s\n",
1977 delete_on_close ? "Added" : "Removed", fsp->fnum, fsp->fsp_name ));
1981 files_struct *iterate_fsp;
1984 * Modify the share mode entry for all files open
1985 * on this device and inode to tell other smbds we have
1986 * changed the delete on close flag. This will be noticed
1987 * in the close code, the last closer will delete the file
1991 DEBUG(10,("call_trans2setfilepathinfo: %s delete on close flag for fnum = %d, file %s\n",
1992 delete_on_close ? "Adding" : "Removing", fsp->fnum, fsp->fsp_name ));
1994 if (lock_share_entry_fsp(fsp) == False)
1995 return ERROR_DOS(ERRDOS,ERRnoaccess);
1997 if (!modify_delete_flag(fsp->dev, fsp->inode, delete_on_close)) {
1998 DEBUG(0,("call_trans2setfilepathinfo: failed to change delete on close flag for file %s\n",
2000 unlock_share_entry_fsp(fsp);
2001 return ERROR_DOS(ERRDOS,ERRnoaccess);
2008 unlock_share_entry_fsp(fsp);
2011 * Go through all files we have open on the same device and
2012 * inode (hanging off the same hash bucket) and set the DELETE_ON_CLOSE_FLAG.
2013 * Other smbd's that have this file open will look in the share_mode on close.
2014 * take care of this (rare) case in close_file(). See the comment there.
2015 * NB. JRA. We don't really need to do this anymore - all should be taken
2016 * care of in the share_mode changes in the tdb.
2019 for(iterate_fsp = file_find_di_first(fsp->dev, fsp->inode);
2020 iterate_fsp; iterate_fsp = file_find_di_next(iterate_fsp))
2021 fsp->delete_on_close = delete_on_close;
2024 * Set the delete on close flag in the fsp.
2026 fsp->delete_on_close = delete_on_close;
2028 DEBUG(10, ("call_trans2setfilepathinfo: %s delete on close flag for fnum = %d, file %s\n",
2029 delete_on_close ? "Added" : "Removed", fsp->fnum, fsp->fsp_name ));
2038 return ERROR_DOS(ERRDOS,ERRunknownlevel);
2042 /* get some defaults (no modifications) if any info is zero or -1. */
2043 if (tvs.actime == (time_t)0 || tvs.actime == (time_t)-1)
2044 tvs.actime = sbuf.st_atime;
2046 if (tvs.modtime == (time_t)0 || tvs.modtime == (time_t)-1)
2047 tvs.modtime = sbuf.st_mtime;
2049 DEBUG(6,("actime: %s " , ctime(&tvs.actime)));
2050 DEBUG(6,("modtime: %s ", ctime(&tvs.modtime)));
2051 DEBUG(6,("size: %.0f ", (double)size));
2052 DEBUG(6,("mode: %x\n" , mode));
2054 if(!((info_level == SMB_SET_FILE_END_OF_FILE_INFO) ||
2055 (info_level == SMB_SET_FILE_ALLOCATION_INFO) ||
2056 (info_level == 1019) ||
2057 (info_level == 1020))) {
2059 * Only do this test if we are not explicitly
2060 * changing the size of a file.
2063 size = sbuf.st_size;
2066 /* Try and set the times, size and mode of this file -
2067 if they are different from the current values
2069 if (sbuf.st_mtime != tvs.modtime || sbuf.st_atime != tvs.actime) {
2072 * This was a setfileinfo on an open file.
2073 * NT does this a lot. It's actually pointless
2074 * setting the time here, as it will be overwritten
2075 * on the next write, so we save the request
2076 * away and will set it on file code. JRA.
2079 if (tvs.modtime != (time_t)0 && tvs.modtime != (time_t)-1) {
2080 DEBUG(10,("call_trans2setfilepathinfo: setting pending modtime to %s\n",
2081 ctime(&tvs.modtime) ));
2082 fsp->pending_modtime = tvs.modtime;
2087 DEBUG(10,("call_trans2setfilepathinfo: setting utimes to modified values.\n"));
2089 if(file_utime(conn, fname, &tvs)!=0)
2090 return(UNIXERROR(ERRDOS,ERRnoaccess));
2094 /* check the mode isn't different, before changing it */
2095 if ((mode != 0) && (mode != dos_mode(conn, fname, &sbuf))) {
2097 DEBUG(10,("call_trans2setfilepathinfo: file %s : setting dos mode %x\n",
2100 if(file_chmod(conn, fname, mode, NULL)) {
2101 DEBUG(2,("chmod of %s failed (%s)\n", fname, strerror(errno)));
2102 return(UNIXERROR(ERRDOS,ERRnoaccess));
2106 if(size != sbuf.st_size) {
2108 DEBUG(10,("call_trans2setfilepathinfo: file %s : setting new size to %.0f\n",
2109 fname, (double)size ));
2112 files_struct *new_fsp = NULL;
2113 int access_mode = 0;
2116 if(global_oplock_break) {
2117 /* Queue this file modify as we are the process of an oplock break. */
2119 DEBUG(2,("call_trans2setfilepathinfo: queueing message due to being "));
2120 DEBUGADD(2,( "in oplock break state.\n"));
2122 push_oplock_pending_smb_message(inbuf, length);
2126 new_fsp = open_file_shared(conn, fname, &sbuf,
2127 SET_OPEN_MODE(DOS_OPEN_RDWR),
2128 (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN),
2129 0, 0, &access_mode, &action);
2131 if (new_fsp == NULL)
2132 return(UNIXERROR(ERRDOS,ERRbadpath));
2133 vfs_set_filelen(new_fsp, size);
2134 close_file(new_fsp,True);
2136 vfs_set_filelen(fsp, size);
2142 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
2147 /****************************************************************************
2148 reply to a TRANS2_MKDIR (make directory with extended attributes).
2149 ****************************************************************************/
2150 static int call_trans2mkdir(connection_struct *conn,
2151 char *inbuf, char *outbuf, int length, int bufsize,
2152 char **pparams, char **ppdata)
2154 char *params = *pparams;
2157 SMB_STRUCT_STAT sbuf;
2158 BOOL bad_path = False;
2160 if (!CAN_WRITE(conn))
2161 return ERROR_DOS(ERRSRV,ERRaccess);
2163 srvstr_pull(inbuf, directory, ¶ms[4], sizeof(directory), -1, STR_TERMINATE);
2165 DEBUG(3,("call_trans2mkdir : name = %s\n", directory));
2167 unix_convert(directory,conn,0,&bad_path,&sbuf);
2168 if (check_name(directory,conn))
2169 ret = vfs_mkdir(conn,directory,unix_mode(conn,aDIR,directory));
2173 DEBUG(5,("call_trans2mkdir error (%s)\n", strerror(errno)));
2174 if((errno == ENOENT) && bad_path)
2176 unix_ERR_class = ERRDOS;
2177 unix_ERR_code = ERRbadpath;
2179 return(UNIXERROR(ERRDOS,ERRnoaccess));
2182 /* Realloc the parameter and data sizes */
2183 params = Realloc(*pparams,2);
2184 if(params == NULL) {
2185 return ERROR_DOS(ERRDOS,ERRnomem);
2191 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
2196 /****************************************************************************
2197 reply to a TRANS2_FINDNOTIFYFIRST (start monitoring a directory for changes)
2198 We don't actually do this - we just send a null response.
2199 ****************************************************************************/
2200 static int call_trans2findnotifyfirst(connection_struct *conn,
2201 char *inbuf, char *outbuf,
2202 int length, int bufsize,
2203 char **pparams, char **ppdata)
2205 static uint16 fnf_handle = 257;
2206 char *params = *pparams;
2207 uint16 info_level = SVAL(params,4);
2209 DEBUG(3,("call_trans2findnotifyfirst - info_level %d\n", info_level));
2217 return ERROR_DOS(ERRDOS,ERRunknownlevel);
2220 /* Realloc the parameter and data sizes */
2221 params = Realloc(*pparams,6);
2222 if(params == NULL) {
2223 return ERROR_DOS(ERRDOS,ERRnomem);
2227 SSVAL(params,0,fnf_handle);
2228 SSVAL(params,2,0); /* No changes */
2229 SSVAL(params,4,0); /* No EA errors */
2236 send_trans2_replies(outbuf, bufsize, params, 6, *ppdata, 0);
2241 /****************************************************************************
2242 reply to a TRANS2_FINDNOTIFYNEXT (continue monitoring a directory for
2243 changes). Currently this does nothing.
2244 ****************************************************************************/
2245 static int call_trans2findnotifynext(connection_struct *conn,
2246 char *inbuf, char *outbuf,
2247 int length, int bufsize,
2248 char **pparams, char **ppdata)
2250 char *params = *pparams;
2252 DEBUG(3,("call_trans2findnotifynext\n"));
2254 /* Realloc the parameter and data sizes */
2255 params = Realloc(*pparams,4);
2256 if(params == NULL) {
2257 return ERROR_DOS(ERRDOS,ERRnomem);
2261 SSVAL(params,0,0); /* No changes */
2262 SSVAL(params,2,0); /* No EA errors */
2264 send_trans2_replies(outbuf, bufsize, params, 4, *ppdata, 0);
2269 /****************************************************************************
2270 reply to a TRANS2_GET_DFS_REFERRAL - Shirish Kalele <kalele@veritas.com>
2271 ****************************************************************************/
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 ****************************************************************************/
2337 int reply_findclose(connection_struct *conn,
2338 char *inbuf,char *outbuf,int length,int bufsize)
2341 int dptr_num=SVALS(inbuf,smb_vwv0);
2342 START_PROFILE(SMBfindclose);
2344 DEBUG(3,("reply_findclose, dptr_num = %d\n", dptr_num));
2346 dptr_close(&dptr_num);
2348 outsize = set_message(outbuf,0,0,True);
2350 DEBUG(3,("SMBfindclose dptr_num = %d\n", dptr_num));
2352 END_PROFILE(SMBfindclose);
2356 /****************************************************************************
2357 reply to a SMBfindnclose (stop FINDNOTIFYFIRST directory search)
2358 ****************************************************************************/
2359 int reply_findnclose(connection_struct *conn,
2360 char *inbuf,char *outbuf,int length,int bufsize)
2364 START_PROFILE(SMBfindnclose);
2366 dptr_num = SVAL(inbuf,smb_vwv0);
2368 DEBUG(3,("reply_findnclose, dptr_num = %d\n", dptr_num));
2370 /* We never give out valid handles for a
2371 findnotifyfirst - so any dptr_num is ok here.
2374 outsize = set_message(outbuf,0,0,True);
2376 DEBUG(3,("SMB_findnclose dptr_num = %d\n", dptr_num));
2378 END_PROFILE(SMBfindnclose);
2383 /****************************************************************************
2384 reply to a SMBtranss2 - just ignore it!
2385 ****************************************************************************/
2386 int reply_transs2(connection_struct *conn,
2387 char *inbuf,char *outbuf,int length,int bufsize)
2389 START_PROFILE(SMBtranss2);
2390 DEBUG(4,("Ignoring transs2 of length %d\n",length));
2391 END_PROFILE(SMBtranss2);
2395 /****************************************************************************
2396 reply to a SMBtrans2
2397 ****************************************************************************/
2398 int reply_trans2(connection_struct *conn,
2399 char *inbuf,char *outbuf,int length,int bufsize)
2402 unsigned int total_params = SVAL(inbuf, smb_tpscnt);
2403 unsigned int total_data =SVAL(inbuf, smb_tdscnt);
2405 unsigned int max_param_reply = SVAL(inbuf, smb_mprcnt);
2406 unsigned int max_data_reply = SVAL(inbuf, smb_mdrcnt);
2407 unsigned int max_setup_fields = SVAL(inbuf, smb_msrcnt);
2408 BOOL close_tid = BITSETW(inbuf+smb_flags,0);
2409 BOOL no_final_response = BITSETW(inbuf+smb_flags,1);
2410 int32 timeout = IVALS(inbuf,smb_timeout);
2412 unsigned int suwcnt = SVAL(inbuf, smb_suwcnt);
2413 unsigned int tran_call = SVAL(inbuf, smb_setup0);
2414 char *params = NULL, *data = NULL;
2415 int num_params, num_params_sofar, num_data, num_data_sofar;
2416 START_PROFILE(SMBtrans2);
2418 if(global_oplock_break && (tran_call == TRANSACT2_OPEN)) {
2419 /* Queue this open message as we are the process of an
2422 DEBUG(2,("reply_trans2: queueing message trans2open due to being "));
2423 DEBUGADD(2,( "in oplock break state.\n"));
2425 push_oplock_pending_smb_message(inbuf, length);
2426 END_PROFILE(SMBtrans2);
2430 if (IS_IPC(conn) && (tran_call != TRANSACT2_OPEN)
2431 && (tran_call != TRANSACT2_GET_DFS_REFERRAL)) {
2432 END_PROFILE(SMBtrans2);
2433 return ERROR_DOS(ERRSRV,ERRaccess);
2436 outsize = set_message(outbuf,0,0,True);
2438 /* All trans2 messages we handle have smb_sucnt == 1 - ensure this
2439 is so as a sanity check */
2442 * Need to have rc=0 for ioctl to get job id for OS/2.
2443 * Network printing will fail if function is not successful.
2444 * Similar function in reply.c will be used if protocol
2445 * is LANMAN1.0 instead of LM1.2X002.
2446 * Until DosPrintSetJobInfo with PRJINFO3 is supported,
2447 * outbuf doesn't have to be set(only job id is used).
2449 if ( (suwcnt == 4) && (tran_call == TRANSACT2_IOCTL) &&
2450 (SVAL(inbuf,(smb_setup+4)) == LMCAT_SPL) &&
2451 (SVAL(inbuf,(smb_setup+6)) == LMFUNC_GETJOBID)) {
2452 DEBUG(2,("Got Trans2 DevIOctl jobid\n"));
2454 DEBUG(2,("Invalid smb_sucnt in trans2 call(%d)\n",suwcnt));
2455 DEBUG(2,("Transaction is %d\n",tran_call));
2456 END_PROFILE(SMBtrans2);
2457 return ERROR_DOS(ERRSRV,ERRerror);
2461 /* Allocate the space for the maximum needed parameters and data */
2462 if (total_params > 0)
2463 params = (char *)malloc(total_params);
2465 data = (char *)malloc(total_data);
2467 if ((total_params && !params) || (total_data && !data)) {
2468 DEBUG(2,("Out of memory in reply_trans2\n"));
2473 END_PROFILE(SMBtrans2);
2474 return ERROR_DOS(ERRDOS,ERRnomem);
2477 /* Copy the param and data bytes sent with this request into
2478 the params buffer */
2479 num_params = num_params_sofar = SVAL(inbuf,smb_pscnt);
2480 num_data = num_data_sofar = SVAL(inbuf, smb_dscnt);
2482 if (num_params > total_params || num_data > total_data)
2483 exit_server("invalid params in reply_trans2");
2486 memcpy( params, smb_base(inbuf) + SVAL(inbuf, smb_psoff), num_params);
2488 memcpy( data, smb_base(inbuf) + SVAL(inbuf, smb_dsoff), num_data);
2490 if(num_data_sofar < total_data || num_params_sofar < total_params) {
2491 /* We need to send an interim response then receive the rest
2492 of the parameter/data bytes */
2493 outsize = set_message(outbuf,0,0,True);
2494 if (!send_smb(smbd_server_fd(),outbuf))
2495 exit_server("reply_trans2: send_smb failed.\n");
2497 while (num_data_sofar < total_data ||
2498 num_params_sofar < total_params) {
2501 ret = receive_next_smb(inbuf,bufsize,SMB_SECONDARY_WAIT);
2504 (CVAL(inbuf, smb_com) != SMBtranss2)) || !ret) {
2505 outsize = set_message(outbuf,0,0,True);
2507 DEBUG(0,("reply_trans2: Invalid secondary trans2 packet\n"));
2509 DEBUG(0,("reply_trans2: %s in getting secondary trans2 response.\n",
2510 (smb_read_error == READ_ERROR) ? "error" : "timeout" ));
2515 END_PROFILE(SMBtrans2);
2516 return ERROR_DOS(ERRSRV,ERRerror);
2519 /* Revise total_params and total_data in case
2520 they have changed downwards */
2521 total_params = SVAL(inbuf, smb_tpscnt);
2522 total_data = SVAL(inbuf, smb_tdscnt);
2523 num_params_sofar += (num_params = SVAL(inbuf,smb_spscnt));
2524 num_data_sofar += ( num_data = SVAL(inbuf, smb_sdscnt));
2525 if (num_params_sofar > total_params || num_data_sofar > total_data)
2526 exit_server("data overflow in trans2");
2528 memcpy( ¶ms[ SVAL(inbuf, smb_spsdisp)],
2529 smb_base(inbuf) + SVAL(inbuf, smb_spsoff), num_params);
2530 memcpy( &data[SVAL(inbuf, smb_sdsdisp)],
2531 smb_base(inbuf)+ SVAL(inbuf, smb_sdsoff), num_data);
2535 if (Protocol >= PROTOCOL_NT1) {
2536 SSVAL(outbuf,smb_flg2,SVAL(outbuf,smb_flg2) | 0x40); /* IS_LONG_NAME */
2539 /* Now we must call the relevant TRANS2 function */
2541 case TRANSACT2_OPEN:
2542 START_PROFILE_NESTED(Trans2_open);
2543 outsize = call_trans2open(conn,
2544 inbuf, outbuf, bufsize,
2546 END_PROFILE_NESTED(Trans2_open);
2549 case TRANSACT2_FINDFIRST:
2550 START_PROFILE_NESTED(Trans2_findfirst);
2551 outsize = call_trans2findfirst(conn, inbuf, outbuf,
2552 bufsize, ¶ms, &data);
2553 END_PROFILE_NESTED(Trans2_findfirst);
2556 case TRANSACT2_FINDNEXT:
2557 START_PROFILE_NESTED(Trans2_findnext);
2558 outsize = call_trans2findnext(conn, inbuf, outbuf,
2561 END_PROFILE_NESTED(Trans2_findnext);
2564 case TRANSACT2_QFSINFO:
2565 START_PROFILE_NESTED(Trans2_qfsinfo);
2566 outsize = call_trans2qfsinfo(conn, inbuf, outbuf,
2567 length, bufsize, ¶ms,
2569 END_PROFILE_NESTED(Trans2_qfsinfo);
2572 case TRANSACT2_SETFSINFO:
2573 START_PROFILE_NESTED(Trans2_setfsinfo);
2574 outsize = call_trans2setfsinfo(conn, inbuf, outbuf,
2577 END_PROFILE_NESTED(Trans2_setfsinfo);
2580 case TRANSACT2_QPATHINFO:
2581 case TRANSACT2_QFILEINFO:
2582 START_PROFILE_NESTED(Trans2_qpathinfo);
2583 outsize = call_trans2qfilepathinfo(conn, inbuf, outbuf,
2585 ¶ms, &data, total_data);
2586 END_PROFILE_NESTED(Trans2_qpathinfo);
2588 case TRANSACT2_SETPATHINFO:
2589 case TRANSACT2_SETFILEINFO:
2590 START_PROFILE_NESTED(Trans2_setpathinfo);
2591 outsize = call_trans2setfilepathinfo(conn, inbuf, outbuf,
2595 END_PROFILE_NESTED(Trans2_setpathinfo);
2598 case TRANSACT2_FINDNOTIFYFIRST:
2599 START_PROFILE_NESTED(Trans2_findnotifyfirst);
2600 outsize = call_trans2findnotifyfirst(conn, inbuf, outbuf,
2603 END_PROFILE_NESTED(Trans2_findnotifyfirst);
2606 case TRANSACT2_FINDNOTIFYNEXT:
2607 START_PROFILE_NESTED(Trans2_findnotifynext);
2608 outsize = call_trans2findnotifynext(conn, inbuf, outbuf,
2611 END_PROFILE_NESTED(Trans2_findnotifynext);
2613 case TRANSACT2_MKDIR:
2614 START_PROFILE_NESTED(Trans2_mkdir);
2615 outsize = call_trans2mkdir(conn, inbuf, outbuf, length,
2616 bufsize, ¶ms, &data);
2617 END_PROFILE_NESTED(Trans2_mkdir);
2620 case TRANSACT2_GET_DFS_REFERRAL:
2621 START_PROFILE_NESTED(Trans2_get_dfs_referral);
2622 outsize = call_trans2getdfsreferral(conn,inbuf,outbuf,length,
2623 bufsize, ¶ms, &data);
2624 END_PROFILE_NESTED(Trans2_get_dfs_referral);
2626 case TRANSACT2_IOCTL:
2627 START_PROFILE_NESTED(Trans2_ioctl);
2628 outsize = call_trans2ioctl(conn,inbuf,outbuf,length,
2629 bufsize,¶ms,&data);
2630 END_PROFILE_NESTED(Trans2_ioctl);
2633 /* Error in request */
2634 DEBUG(2,("Unknown request %d in trans2 call\n", tran_call));
2639 END_PROFILE(SMBtrans2);
2640 return ERROR_DOS(ERRSRV,ERRerror);
2643 /* As we do not know how many data packets will need to be
2644 returned here the various call_trans2xxxx calls
2645 must send their own. Thus a call_trans2xxx routine only
2646 returns a value other than -1 when it wants to send
2654 END_PROFILE(SMBtrans2);
2655 return outsize; /* If a correct response was needed the
2656 call_trans2xxx calls have already sent
2657 it. If outsize != -1 then it is returning */