2 Unix SMB/CIFS implementation.
3 SMB transaction2 handling
4 Copyright (C) Jeremy Allison 1994-2001
6 Extensively modified by Andrew Tridgell, 1995
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26 extern BOOL case_sensitive;
27 extern int smb_read_error;
28 extern fstring local_machine;
29 extern int global_oplock_break;
30 extern uint32 global_client_caps;
31 extern pstring global_myname;
33 /* given a stat buffer return the allocated size on disk, taking into
34 account sparse files */
35 SMB_OFF_T get_allocation_size(SMB_STRUCT_STAT *sbuf)
38 ret = sbuf->st_blksize * (SMB_OFF_T)sbuf->st_blocks;
39 ret = SMB_ROUNDUP_ALLOCATION(ret);
43 #define get_file_size(sbuf) (sbuf.st_size)
46 /****************************************************************************
47 Send the required number of replies back.
48 We assume all fields other than the data fields are
49 set correctly for the type of call.
50 HACK ! Always assumes smb_setup field is zero.
51 ****************************************************************************/
53 static int send_trans2_replies(char *outbuf,
60 /* As we are using a protocol > LANMAN1 then the max_send
61 variable must have been set in the sessetupX call.
62 This takes precedence over the max_xmit field in the
63 global struct. These different max_xmit variables should
64 be merged as this is now too confusing */
67 int data_to_send = datasize;
68 int params_to_send = paramsize;
72 int params_sent_thistime, data_sent_thistime, total_sent_thistime;
73 int alignment_offset = 1; /* JRA. This used to be 3. Set to 1 to make netmon parse ok. */
74 int data_alignment_offset = 0;
76 /* Initially set the wcnt area to be 10 - this is true for all trans2 replies */
78 set_message(outbuf,10,0,True);
80 /* If there genuinely are no parameters or data to send just send the empty packet */
82 if(params_to_send == 0 && data_to_send == 0) {
83 if (!send_smb(smbd_server_fd(),outbuf))
84 exit_server("send_trans2_replies: send_smb failed.");
88 /* When sending params and data ensure that both are nicely aligned */
89 /* Only do this alignment when there is also data to send - else
90 can cause NT redirector problems. */
92 if (((params_to_send % 4) != 0) && (data_to_send != 0))
93 data_alignment_offset = 4 - (params_to_send % 4);
95 /* Space is bufsize minus Netbios over TCP header minus SMB header */
96 /* The alignment_offset is to align the param bytes on an even byte
97 boundary. NT 4.0 Beta needs this to work correctly. */
99 useable_space = bufsize - ((smb_buf(outbuf)+ alignment_offset+data_alignment_offset) - outbuf);
101 /* useable_space can never be more than max_send minus the alignment offset. */
103 useable_space = MIN(useable_space, max_send - (alignment_offset+data_alignment_offset));
105 while (params_to_send || data_to_send) {
106 /* Calculate whether we will totally or partially fill this packet */
108 total_sent_thistime = params_to_send + data_to_send + alignment_offset + data_alignment_offset;
110 /* We can never send more than useable_space */
112 * Note that 'useable_space' does not include the alignment offsets,
113 * but we must include the alignment offsets in the calculation of
114 * the length of the data we send over the wire, as the alignment offsets
115 * are sent here. Fix from Marc_Jacobsen@hp.com.
118 total_sent_thistime = MIN(total_sent_thistime, useable_space+ alignment_offset + data_alignment_offset);
120 set_message(outbuf, 10, total_sent_thistime, True);
122 /* Set total params and data to be sent */
123 SSVAL(outbuf,smb_tprcnt,paramsize);
124 SSVAL(outbuf,smb_tdrcnt,datasize);
126 /* Calculate how many parameters and data we can fit into
127 * this packet. Parameters get precedence
130 params_sent_thistime = MIN(params_to_send,useable_space);
131 data_sent_thistime = useable_space - params_sent_thistime;
132 data_sent_thistime = MIN(data_sent_thistime,data_to_send);
134 SSVAL(outbuf,smb_prcnt, params_sent_thistime);
136 /* smb_proff is the offset from the start of the SMB header to the
137 parameter bytes, however the first 4 bytes of outbuf are
138 the Netbios over TCP header. Thus use smb_base() to subtract
139 them from the calculation */
141 SSVAL(outbuf,smb_proff,((smb_buf(outbuf)+alignment_offset) - smb_base(outbuf)));
143 if(params_sent_thistime == 0)
144 SSVAL(outbuf,smb_prdisp,0);
146 /* Absolute displacement of param bytes sent in this packet */
147 SSVAL(outbuf,smb_prdisp,pp - params);
149 SSVAL(outbuf,smb_drcnt, data_sent_thistime);
150 if(data_sent_thistime == 0) {
151 SSVAL(outbuf,smb_droff,0);
152 SSVAL(outbuf,smb_drdisp, 0);
154 /* The offset of the data bytes is the offset of the
155 parameter bytes plus the number of parameters being sent this time */
156 SSVAL(outbuf,smb_droff,((smb_buf(outbuf)+alignment_offset) -
157 smb_base(outbuf)) + params_sent_thistime + data_alignment_offset);
158 SSVAL(outbuf,smb_drdisp, pd - pdata);
161 /* Copy the param bytes into the packet */
163 if(params_sent_thistime)
164 memcpy((smb_buf(outbuf)+alignment_offset),pp,params_sent_thistime);
166 /* Copy in the data bytes */
167 if(data_sent_thistime)
168 memcpy(smb_buf(outbuf)+alignment_offset+params_sent_thistime+
169 data_alignment_offset,pd,data_sent_thistime);
171 DEBUG(9,("t2_rep: params_sent_thistime = %d, data_sent_thistime = %d, useable_space = %d\n",
172 params_sent_thistime, data_sent_thistime, useable_space));
173 DEBUG(9,("t2_rep: params_to_send = %d, data_to_send = %d, paramsize = %d, datasize = %d\n",
174 params_to_send, data_to_send, paramsize, datasize));
176 /* Send the packet */
177 if (!send_smb(smbd_server_fd(),outbuf))
178 exit_server("send_trans2_replies: send_smb failed.");
180 pp += params_sent_thistime;
181 pd += data_sent_thistime;
183 params_to_send -= params_sent_thistime;
184 data_to_send -= data_sent_thistime;
187 if(params_to_send < 0 || data_to_send < 0) {
188 DEBUG(0,("send_trans2_replies failed sanity check pts = %d, dts = %d\n!!!",
189 params_to_send, data_to_send));
197 /****************************************************************************
198 Reply to a TRANSACT2_OPEN.
199 ****************************************************************************/
201 static int call_trans2open(connection_struct *conn, char *inbuf, char *outbuf, int bufsize,
202 char **pparams, int total_params, char **ppdata, int total_data)
204 char *params = *pparams;
209 BOOL return_additional_info;
219 int fmode=0,mtime=0,rmode;
221 SMB_STRUCT_STAT sbuf;
223 BOOL bad_path = False;
227 * Ensure we have enough parameters to perform the operation.
230 if (total_params < 29)
231 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
233 open_mode = SVAL(params, 2);
234 open_attr = SVAL(params,6);
235 oplock_request = (((SVAL(params,0)|(1<<1))>>1) | ((SVAL(params,0)|(1<<2))>>1));
237 return_additional_info = BITSETW(params,0);
238 open_sattr = SVAL(params, 4);
239 open_time = make_unix_date3(params+8);
241 open_ofun = SVAL(params,12);
242 open_size = IVAL(params,14);
245 srvstr_pull(inbuf, fname, pname, sizeof(fname), -1, STR_TERMINATE);
247 DEBUG(3,("trans2open %s mode=%d attr=%d ofun=%d size=%d\n",
248 fname,open_mode, open_attr, open_ofun, open_size));
251 return(ERROR_DOS(ERRSRV,ERRaccess));
253 /* XXXX we need to handle passed times, sattr and flags */
255 unix_convert(fname,conn,0,&bad_path,&sbuf);
257 if (!check_name(fname,conn)) {
258 set_bad_path_error(errno, bad_path);
259 return(UNIXERROR(ERRDOS,ERRnoaccess));
262 unixmode = unix_mode(conn,open_attr | aARCH, fname);
264 fsp = open_file_shared(conn,fname,&sbuf,open_mode,open_ofun,unixmode,
265 oplock_request, &rmode,&smb_action);
268 set_bad_path_error(errno, bad_path);
269 return(UNIXERROR(ERRDOS,ERRnoaccess));
272 size = get_file_size(sbuf);
273 fmode = dos_mode(conn,fname,&sbuf);
274 mtime = sbuf.st_mtime;
277 close_file(fsp,False);
278 return(ERROR_DOS(ERRDOS,ERRnoaccess));
281 /* Realloc the size of parameters and data we will return */
282 params = Realloc(*pparams, 28);
284 return(ERROR_DOS(ERRDOS,ERRnomem));
287 memset((char *)params,'\0',28);
288 SSVAL(params,0,fsp->fnum);
289 SSVAL(params,2,fmode);
290 put_dos_date2(params,4, mtime);
291 SIVAL(params,8, (uint32)size);
292 SSVAL(params,12,rmode);
294 if (oplock_request && lp_fake_oplocks(SNUM(conn)))
295 smb_action |= EXTENDED_OPLOCK_GRANTED;
297 SSVAL(params,18,smb_action);
300 * WARNING - this may need to be changed if SMB_INO_T <> 4 bytes.
302 SIVAL(params,20,inode);
304 /* Send the required number of replies */
305 send_trans2_replies(outbuf, bufsize, params, 28, *ppdata, 0);
310 /*********************************************************
311 Routine to check if a given string matches exactly.
312 as a special case a mask of "." does NOT match. That
313 is required for correct wildcard semantics
314 Case can be significant or not.
315 **********************************************************/
317 static BOOL exact_match(char *str,char *mask, BOOL case_sig)
319 if (mask[0] == '.' && mask[1] == 0)
322 return strcmp(str,mask)==0;
323 return strcasecmp(str,mask) == 0;
326 /****************************************************************************
327 Return the filetype for UNIX extensions.
328 ****************************************************************************/
330 static uint32 unix_filetype(mode_t mode)
333 return UNIX_TYPE_FILE;
334 else if(S_ISDIR(mode))
335 return UNIX_TYPE_DIR;
337 else if(S_ISLNK(mode))
338 return UNIX_TYPE_SYMLINK;
341 else if(S_ISCHR(mode))
342 return UNIX_TYPE_CHARDEV;
345 else if(S_ISBLK(mode))
346 return UNIX_TYPE_BLKDEV;
349 else if(S_ISFIFO(mode))
350 return UNIX_TYPE_FIFO;
353 else if(S_ISSOCK(mode))
354 return UNIX_TYPE_SOCKET;
357 DEBUG(0,("unix_filetype: unknown filetype %u", (unsigned)mode));
358 return UNIX_TYPE_UNKNOWN;
361 /****************************************************************************
362 Return the major devicenumber for UNIX extensions.
363 ****************************************************************************/
365 static uint32 unix_dev_major(SMB_DEV_T dev)
367 #if defined(HAVE_DEVICE_MAJOR_FN)
368 return (uint32)major(dev);
370 return (uint32)(dev >> 8);
374 /****************************************************************************
375 Return the minor devicenumber for UNIX extensions.
376 ****************************************************************************/
378 static uint32 unix_dev_minor(SMB_DEV_T dev)
380 #if defined(HAVE_DEVICE_MINOR_FN)
381 return (uint32)minor(dev);
383 return (uint32)(dev & 0xff);
387 /****************************************************************************
388 Map wire perms onto standard UNIX permissions. Obey share restrictions.
389 ****************************************************************************/
391 static mode_t unix_perms_from_wire( connection_struct *conn, SMB_STRUCT_STAT *pst, uint32 perms)
395 if (perms == SMB_MODE_NO_CHANGE)
398 ret |= ((perms & UNIX_X_OTH ) ? S_IXOTH : 0);
399 ret |= ((perms & UNIX_W_OTH ) ? S_IWOTH : 0);
400 ret |= ((perms & UNIX_R_OTH ) ? S_IROTH : 0);
401 ret |= ((perms & UNIX_X_GRP ) ? S_IXGRP : 0);
402 ret |= ((perms & UNIX_W_GRP ) ? S_IWGRP : 0);
403 ret |= ((perms & UNIX_R_GRP ) ? S_IRGRP : 0);
404 ret |= ((perms & UNIX_X_USR ) ? S_IXUSR : 0);
405 ret |= ((perms & UNIX_W_USR ) ? S_IWUSR : 0);
406 ret |= ((perms & UNIX_R_USR ) ? S_IRUSR : 0);
408 ret |= ((perms & UNIX_STICKY ) ? S_ISVTX : 0);
411 ret |= ((perms & UNIX_SET_GID ) ? S_ISGID : 0);
414 ret |= ((perms & UNIX_SET_UID ) ? S_ISUID : 0);
417 if (VALID_STAT(*pst) && S_ISDIR(pst->st_mode)) {
418 ret &= lp_dir_mask(SNUM(conn));
419 /* Add in force bits */
420 ret |= lp_force_dir_mode(SNUM(conn));
422 /* Apply mode mask */
423 ret &= lp_create_mask(SNUM(conn));
424 /* Add in force bits */
425 ret |= lp_force_create_mode(SNUM(conn));
431 /****************************************************************************
432 checks for SMB_TIME_NO_CHANGE and if not found
433 calls interpret_long_date
434 ****************************************************************************/
435 time_t interpret_long_unix_date(char *p)
437 DEBUG(1,("interpret_long_unix_date\n"));
438 if(IVAL(p,0) == SMB_TIME_NO_CHANGE_LO &&
439 IVAL(p,4) == SMB_TIME_NO_CHANGE_HI) {
442 return interpret_long_date(p);
446 /****************************************************************************
447 Get a level dependent lanman2 dir entry.
448 ****************************************************************************/
450 static BOOL get_lanman2_dir_entry(connection_struct *conn,
451 void *inbuf, void *outbuf,
452 char *path_mask,int dirtype,int info_level,
453 int requires_resume_key,
454 BOOL dont_descend,char **ppdata,
455 char *base_data, int space_remaining,
456 BOOL *out_of_space, BOOL *got_exact_match,
461 SMB_STRUCT_STAT sbuf;
465 char *p, *q, *pdata = *ppdata;
469 SMB_OFF_T file_size = 0;
470 SMB_OFF_T allocation_size = 0;
472 time_t mdate=0, adate=0, cdate=0;
475 int nt_extmode; /* Used for NT connections instead of mode */
476 BOOL needslash = ( conn->dirpath[strlen(conn->dirpath) -1] != '/');
479 *out_of_space = False;
480 *got_exact_match = False;
485 p = strrchr_m(path_mask,'/');
492 pstrcpy(mask, path_mask);
497 /* Needed if we run out of space */
498 prev_dirpos = TellDir(conn->dirptr);
499 dname = ReadDirName(conn->dirptr);
502 * Due to bugs in NT client redirectors we are not using
503 * resume keys any more - set them to zero.
504 * Check out the related comments in findfirst/findnext.
510 DEBUG(8,("get_lanman2_dir_entry:readdir on dirptr 0x%lx now at offset %d\n",
511 (long)conn->dirptr,TellDir(conn->dirptr)));
516 pstrcpy(fname,dname);
518 if(!(got_match = *got_exact_match = exact_match(fname, mask, case_sensitive)))
519 got_match = mask_match(fname, mask, case_sensitive);
521 if(!got_match && !mangle_is_8_3(fname, False)) {
524 * It turns out that NT matches wildcards against
525 * both long *and* short names. This may explain some
526 * of the wildcard wierdness from old DOS clients
527 * that some people have been seeing.... JRA.
531 pstrcpy( newname, fname);
532 mangle_map( newname, True, False, SNUM(conn));
533 if(!(got_match = *got_exact_match = exact_match(newname, mask, case_sensitive)))
534 got_match = mask_match(newname, mask, case_sensitive);
538 BOOL isdots = (strequal(fname,"..") || strequal(fname,"."));
539 if (dont_descend && !isdots)
542 pstrcpy(pathreal,conn->dirpath);
544 pstrcat(pathreal,"/");
545 pstrcat(pathreal,dname);
547 if (INFO_LEVEL_IS_UNIX(info_level)) {
548 if (vfs_lstat(conn,pathreal,&sbuf) != 0) {
549 DEBUG(5,("get_lanman2_dir_entry:Couldn't lstat [%s] (%s)\n",
550 pathreal,strerror(errno)));
553 } else if (vfs_stat(conn,pathreal,&sbuf) != 0) {
555 /* Needed to show the msdfs symlinks as
558 if(lp_host_msdfs() &&
559 lp_msdfs_root(SNUM(conn)) &&
560 is_msdfs_link(conn, pathreal, NULL, NULL,
563 DEBUG(5,("get_lanman2_dir_entry: Masquerading msdfs link %s as a directory\n", pathreal));
564 sbuf.st_mode = (sbuf.st_mode & 0xFFF) | S_IFDIR;
568 DEBUG(5,("get_lanman2_dir_entry:Couldn't stat [%s] (%s)\n",
569 pathreal,strerror(errno)));
574 mode = dos_mode(conn,pathreal,&sbuf);
576 if (!dir_check_ftype(conn,mode,&sbuf,dirtype)) {
577 DEBUG(5,("[%s] attribs didn't match %x\n",fname,dirtype));
581 file_size = get_file_size(sbuf);
582 allocation_size = get_allocation_size(&sbuf);
583 mdate = sbuf.st_mtime;
584 adate = sbuf.st_atime;
585 cdate = get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(conn)));
587 if (lp_dos_filetime_resolution(SNUM(conn))) {
596 DEBUG(5,("get_lanman2_dir_entry found %s fname=%s\n",pathreal,fname));
602 mangle_map(fname,False,True,SNUM(conn));
607 nt_extmode = mode ? mode : FILE_ATTRIBUTE_NORMAL;
609 switch (info_level) {
610 case SMB_INFO_STANDARD:
611 if(requires_resume_key) {
615 put_dos_date2(p,l1_fdateCreation,cdate);
616 put_dos_date2(p,l1_fdateLastAccess,adate);
617 put_dos_date2(p,l1_fdateLastWrite,mdate);
618 SIVAL(p,l1_cbFile,(uint32)file_size);
619 SIVAL(p,l1_cbFileAlloc,(uint32)allocation_size);
620 SSVAL(p,l1_attrFile,mode);
623 p += align_string(outbuf, p, 0);
624 len = srvstr_push(outbuf, p, fname, -1, STR_TERMINATE);
625 SCVAL(nameptr, -1, len);
629 case SMB_INFO_QUERY_EA_SIZE:
630 if(requires_resume_key) {
634 put_dos_date2(p,l2_fdateCreation,cdate);
635 put_dos_date2(p,l2_fdateLastAccess,adate);
636 put_dos_date2(p,l2_fdateLastWrite,mdate);
637 SIVAL(p,l2_cbFile,(uint32)file_size);
638 SIVAL(p,l2_cbFileAlloc,(uint32)allocation_size);
639 SSVAL(p,l2_attrFile,mode);
640 SIVAL(p,l2_cbList,0); /* No extended attributes */
643 len = srvstr_push(outbuf, p, fname, -1, STR_NOALIGN);
646 *p++ = 0; /* craig from unisys pointed out we need this */
649 case SMB_FIND_FILE_BOTH_DIRECTORY_INFO:
650 was_8_3 = mangle_is_8_3(fname, True);
652 SIVAL(p,0,reskey); p += 4;
653 put_long_date(p,cdate); p += 8;
654 put_long_date(p,adate); p += 8;
655 put_long_date(p,mdate); p += 8;
656 put_long_date(p,mdate); p += 8;
657 SOFF_T(p,0,file_size);
658 SOFF_T(p,8,allocation_size);
660 SIVAL(p,0,nt_extmode); p += 4;
662 SIVAL(p,0,0); p += 4;
664 pstring mangled_name;
665 pstrcpy(mangled_name, fname);
666 mangle_map(mangled_name,True,True,SNUM(conn));
667 mangled_name[12] = 0;
668 len = srvstr_push(outbuf, p+2, mangled_name, 24, STR_UPPER);
675 len = srvstr_push(outbuf, p, fname, -1, 0);
678 len = PTR_DIFF(p, pdata);
679 len = (len + 3) & ~3;
684 case SMB_FIND_FILE_DIRECTORY_INFO:
686 SIVAL(p,0,reskey); p += 4;
687 put_long_date(p,cdate); p += 8;
688 put_long_date(p,adate); p += 8;
689 put_long_date(p,mdate); p += 8;
690 put_long_date(p,mdate); p += 8;
691 SOFF_T(p,0,file_size);
692 SOFF_T(p,8,allocation_size);
694 SIVAL(p,0,nt_extmode); p += 4;
696 len = srvstr_push(outbuf, p, fname, -1, 0);
699 len = PTR_DIFF(p, pdata);
700 len = (len + 3) & ~3;
705 case SMB_FIND_FILE_FULL_DIRECTORY_INFO:
707 SIVAL(p,0,reskey); p += 4;
708 put_long_date(p,cdate); p += 8;
709 put_long_date(p,adate); p += 8;
710 put_long_date(p,mdate); p += 8;
711 put_long_date(p,mdate); p += 8;
712 SOFF_T(p,0,file_size);
713 SOFF_T(p,8,allocation_size);
715 SIVAL(p,0,nt_extmode); p += 4;
717 SIVAL(p,0,0); p += 4;
719 len = srvstr_push(outbuf, p, fname, -1, 0);
723 len = PTR_DIFF(p, pdata);
724 len = (len + 3) & ~3;
729 case SMB_FIND_FILE_NAMES_INFO:
731 SIVAL(p,0,reskey); p += 4;
733 /* this must *not* be null terminated or w2k gets in a loop trying to set an
734 acl on a dir (tridge) */
735 len = srvstr_push(outbuf, p, fname, -1, 0);
738 len = PTR_DIFF(p, pdata);
739 len = (len + 3) & ~3;
744 /* CIFS UNIX Extension. */
746 case SMB_FIND_FILE_UNIX:
748 SIVAL(p,0,reskey); p+= 4; /* Used for continuing search. */
750 /* Begin of SMB_QUERY_FILE_UNIX_BASIC */
751 SOFF_T(p,0,get_file_size(sbuf)); /* File size 64 Bit */
754 #if defined(HAVE_STAT_ST_BLOCKS) && defined(STAT_ST_BLOCKSIZE)
755 SOFF_T(p,0,sbuf.st_blocks*STAT_ST_BLOCKSIZE); /* Number of bytes used on disk - 64 Bit */
757 /* Can't get the value - fake it using size. */
758 SOFF_T(p,0,get_file_size(sbuf)); /* Number of bytes used on disk - 64 Bit */
762 put_long_date(p,sbuf.st_ctime); /* Creation Time 64 Bit */
763 put_long_date(p+8,sbuf.st_atime); /* Last access time 64 Bit */
764 put_long_date(p+16,sbuf.st_mtime); /* Last modification time 64 Bit */
767 SIVAL(p,0,sbuf.st_uid); /* user id for the owner */
771 SIVAL(p,0,sbuf.st_gid); /* group id of owner */
775 SIVAL(p,0,unix_filetype(sbuf.st_mode));
778 SIVAL(p,0,unix_dev_major(sbuf.st_rdev)); /* Major device number if type is device */
782 SIVAL(p,0,unix_dev_minor(sbuf.st_rdev)); /* Minor device number if type is device */
786 SINO_T(p,0,(SMB_INO_T)sbuf.st_ino); /* inode number */
789 SIVAL(p,0, unix_perms_to_wire(sbuf.st_mode)); /* Standard UNIX file permissions */
793 SIVAL(p,0,sbuf.st_nlink); /* number of hard links */
797 len = srvstr_push(outbuf, p, fname, -1, STR_TERMINATE);
800 len = PTR_DIFF(p, pdata);
801 len = (len + 3) & ~3;
802 SIVAL(pdata,0,len); /* Offset from this structure to the beginning of the next one */
804 /* End of SMB_QUERY_FILE_UNIX_BASIC */
813 if (PTR_DIFF(p,pdata) > space_remaining) {
814 /* Move the dirptr back to prev_dirpos */
815 SeekDir(conn->dirptr, prev_dirpos);
816 *out_of_space = True;
817 DEBUG(9,("get_lanman2_dir_entry: out of space\n"));
818 return False; /* Not finished - just out of space */
821 /* Setup the last_filename pointer, as an offset from base_data */
822 *last_name_off = PTR_DIFF(nameptr,base_data);
823 /* Advance the data pointer to the next slot */
829 /****************************************************************************
830 Reply to a TRANS2_FINDFIRST.
831 ****************************************************************************/
833 static int call_trans2findfirst(connection_struct *conn, char *inbuf, char *outbuf, int bufsize,
834 char **pparams, int total_params, char **ppdata, int total_data)
836 /* We must be careful here that we don't return more than the
837 allowed number of data bytes. If this means returning fewer than
838 maxentries then so be it. We assume that the redirector has
839 enough room for the fixed number of parameter bytes it has
841 uint32 max_data_bytes = SVAL(inbuf, smb_mdrcnt);
842 char *params = *pparams;
843 char *pdata = *ppdata;
844 int dirtype = SVAL(params,0);
845 int maxentries = SVAL(params,2);
846 BOOL close_after_first = BITSETW(params+4,0);
847 BOOL close_if_end = BITSETW(params+4,1);
848 BOOL requires_resume_key = BITSETW(params+4,2);
849 int info_level = SVAL(params,6);
857 BOOL finished = False;
858 BOOL dont_descend = False;
859 BOOL out_of_space = False;
861 BOOL bad_path = False;
862 SMB_STRUCT_STAT sbuf;
864 if (total_params < 12)
865 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
867 *directory = *mask = 0;
869 DEBUG(3,("call_trans2findfirst: dirtype = %d, maxentries = %d, close_after_first=%d, \
870 close_if_end = %d requires_resume_key = %d level = %d, max_data_bytes = %d\n",
871 dirtype, maxentries, close_after_first, close_if_end, requires_resume_key,
872 info_level, max_data_bytes));
874 switch (info_level) {
875 case SMB_INFO_STANDARD:
876 case SMB_INFO_QUERY_EA_SIZE:
877 case SMB_FIND_FILE_DIRECTORY_INFO:
878 case SMB_FIND_FILE_FULL_DIRECTORY_INFO:
879 case SMB_FIND_FILE_NAMES_INFO:
880 case SMB_FIND_FILE_BOTH_DIRECTORY_INFO:
882 case SMB_FIND_FILE_UNIX:
883 if (!lp_unix_extensions())
884 return(ERROR_DOS(ERRDOS,ERRunknownlevel));
887 return(ERROR_DOS(ERRDOS,ERRunknownlevel));
890 srvstr_pull(inbuf, directory, params+12, sizeof(directory), -1, STR_TERMINATE);
892 RESOLVE_FINDFIRST_DFSPATH(directory, conn, inbuf, outbuf);
894 unix_convert(directory,conn,0,&bad_path,&sbuf);
895 if(!check_name(directory,conn)) {
896 set_bad_path_error(errno, bad_path);
897 return(UNIXERROR(ERRDOS,ERRbadpath));
900 p = strrchr_m(directory,'/');
902 pstrcpy(mask,directory);
903 pstrcpy(directory,"./");
909 DEBUG(5,("dir=%s, mask = %s\n",directory, mask));
911 pdata = Realloc(*ppdata, max_data_bytes + 1024);
913 return(ERROR_DOS(ERRDOS,ERRnomem));
916 memset((char *)pdata,'\0',max_data_bytes + 1024);
918 /* Realloc the params space */
919 params = Realloc(*pparams, 10);
921 return ERROR_DOS(ERRDOS,ERRnomem);
924 dptr_num = dptr_create(conn,directory, False, True ,SVAL(inbuf,smb_pid));
926 return(UNIXERROR(ERRDOS,ERRbadfile));
928 /* Save the wildcard match and attribs we are using on this directory -
929 needed as lanman2 assumes these are being saved between calls */
931 if(!(wcard = strdup(mask))) {
932 dptr_close(&dptr_num);
933 return ERROR_DOS(ERRDOS,ERRnomem);
936 dptr_set_wcard(dptr_num, wcard);
937 dptr_set_attr(dptr_num, dirtype);
939 DEBUG(4,("dptr_num is %d, wcard = %s, attr = %d\n",dptr_num, wcard, dirtype));
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;
952 for (i=0;(i<maxentries) && !finished && !out_of_space;i++) {
953 BOOL got_exact_match = False;
955 /* this is a heuristic to avoid seeking the dirptr except when
956 absolutely necessary. It allows for a filename of about 40 chars */
957 if (space_remaining < DIRLEN_GUESS && numentries > 0) {
961 finished = !get_lanman2_dir_entry(conn,
963 mask,dirtype,info_level,
964 requires_resume_key,dont_descend,
965 &p,pdata,space_remaining, &out_of_space, &got_exact_match,
969 if (finished && out_of_space)
972 if (!finished && !out_of_space)
976 * As an optimisation if we know we aren't looking
977 * for a wildcard name (ie. the name matches the wildcard exactly)
978 * then we can finish on any (first) match.
979 * This speeds up large directory searches. JRA.
985 space_remaining = max_data_bytes - PTR_DIFF(p,pdata);
988 /* Check if we can close the dirptr */
989 if(close_after_first || (finished && close_if_end)) {
990 DEBUG(5,("call_trans2findfirst - (2) closing dptr_num %d\n", dptr_num));
991 dptr_close(&dptr_num);
995 * If there are no matching entries we must return ERRDOS/ERRbadfile -
996 * from observation of NT.
999 if(numentries == 0) {
1000 dptr_close(&dptr_num);
1001 return ERROR_DOS(ERRDOS,ERRbadfile);
1004 /* At this point pdata points to numentries directory entries. */
1006 /* Set up the return parameter block */
1007 SSVAL(params,0,dptr_num);
1008 SSVAL(params,2,numentries);
1009 SSVAL(params,4,finished);
1010 SSVAL(params,6,0); /* Never an EA error */
1011 SSVAL(params,8,last_name_off);
1013 send_trans2_replies( outbuf, bufsize, params, 10, pdata, PTR_DIFF(p,pdata));
1015 if ((! *directory) && dptr_path(dptr_num))
1016 slprintf(directory,sizeof(directory)-1, "(%s)",dptr_path(dptr_num));
1018 DEBUG( 4, ( "%s mask=%s directory=%s dirtype=%d numentries=%d\n",
1019 smb_fn_name(CVAL(inbuf,smb_com)),
1020 mask, directory, dirtype, numentries ) );
1023 * Force a name mangle here to ensure that the
1024 * mask as an 8.3 name is top of the mangled cache.
1025 * The reasons for this are subtle. Don't remove
1026 * this code unless you know what you are doing
1027 * (see PR#13758). JRA.
1030 if(!mangle_is_8_3_wildcards( mask, False))
1031 mangle_map(mask, True, True, SNUM(conn));
1036 /****************************************************************************
1037 Reply to a TRANS2_FINDNEXT.
1038 ****************************************************************************/
1040 static int call_trans2findnext(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize,
1041 char **pparams, int total_params, char **ppdata, int total_data)
1043 /* We must be careful here that we don't return more than the
1044 allowed number of data bytes. If this means returning fewer than
1045 maxentries then so be it. We assume that the redirector has
1046 enough room for the fixed number of parameter bytes it has
1048 int max_data_bytes = SVAL(inbuf, smb_mdrcnt);
1049 char *params = *pparams;
1050 char *pdata = *ppdata;
1051 int dptr_num = SVAL(params,0);
1052 int maxentries = SVAL(params,2);
1053 uint16 info_level = SVAL(params,4);
1054 uint32 resume_key = IVAL(params,6);
1055 BOOL close_after_request = BITSETW(params+10,0);
1056 BOOL close_if_end = BITSETW(params+10,1);
1057 BOOL requires_resume_key = BITSETW(params+10,2);
1058 BOOL continue_bit = BITSETW(params+10,3);
1059 pstring resume_name;
1065 int i, last_name_off=0;
1066 BOOL finished = False;
1067 BOOL dont_descend = False;
1068 BOOL out_of_space = False;
1069 int space_remaining;
1071 if (total_params < 12)
1072 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
1074 *mask = *directory = *resume_name = 0;
1076 srvstr_pull(inbuf, resume_name, params+12, sizeof(resume_name), -1, STR_TERMINATE);
1078 DEBUG(3,("call_trans2findnext: dirhandle = %d, max_data_bytes = %d, maxentries = %d, \
1079 close_after_request=%d, close_if_end = %d requires_resume_key = %d \
1080 resume_key = %d resume name = %s continue=%d level = %d\n",
1081 dptr_num, max_data_bytes, maxentries, close_after_request, close_if_end,
1082 requires_resume_key, resume_key, resume_name, continue_bit, info_level));
1084 switch (info_level) {
1085 case SMB_INFO_STANDARD:
1086 case SMB_INFO_QUERY_EA_SIZE:
1087 case SMB_FIND_FILE_DIRECTORY_INFO:
1088 case SMB_FIND_FILE_FULL_DIRECTORY_INFO:
1089 case SMB_FIND_FILE_NAMES_INFO:
1090 case SMB_FIND_FILE_BOTH_DIRECTORY_INFO:
1092 case SMB_FIND_FILE_UNIX:
1093 if (!lp_unix_extensions())
1094 return(ERROR_DOS(ERRDOS,ERRunknownlevel));
1097 return ERROR_DOS(ERRDOS,ERRunknownlevel);
1100 pdata = Realloc( *ppdata, max_data_bytes + 1024);
1102 return ERROR_DOS(ERRDOS,ERRnomem);
1105 memset((char *)pdata,'\0',max_data_bytes + 1024);
1107 /* Realloc the params space */
1108 params = Realloc(*pparams, 6*SIZEOFWORD);
1109 if( params == NULL )
1110 return ERROR_DOS(ERRDOS,ERRnomem);
1114 /* Check that the dptr is valid */
1115 if(!(conn->dirptr = dptr_fetch_lanman2(dptr_num)))
1116 return ERROR_DOS(ERRDOS,ERRnofiles);
1118 string_set(&conn->dirpath,dptr_path(dptr_num));
1120 /* Get the wildcard mask from the dptr */
1121 if((p = dptr_wcard(dptr_num))== NULL) {
1122 DEBUG(2,("dptr_num %d has no wildcard\n", dptr_num));
1123 return ERROR_DOS(ERRDOS,ERRnofiles);
1127 pstrcpy(directory,conn->dirpath);
1129 /* Get the attr mask from the dptr */
1130 dirtype = dptr_attr(dptr_num);
1132 DEBUG(3,("dptr_num is %d, mask = %s, attr = %x, dirptr=(0x%lX,%d)\n",
1133 dptr_num, mask, dirtype,
1135 TellDir(conn->dirptr)));
1137 /* We don't need to check for VOL here as this is returned by
1138 a different TRANS2 call. */
1140 DEBUG(8,("dirpath=<%s> dontdescend=<%s>\n",conn->dirpath,lp_dontdescend(SNUM(conn))));
1141 if (in_list(conn->dirpath,lp_dontdescend(SNUM(conn)),case_sensitive))
1142 dont_descend = True;
1145 space_remaining = max_data_bytes;
1146 out_of_space = False;
1149 * Seek to the correct position. We no longer use the resume key but
1150 * depend on the last file name instead.
1153 if(requires_resume_key && *resume_name && !continue_bit) {
1156 * Fix for NT redirector problem triggered by resume key indexes
1157 * changing between directory scans. We now return a resume key of 0
1158 * and instead look for the filename to continue from (also given
1159 * to us by NT/95/smbfs/smbclient). If no other scans have been done between the
1160 * findfirst/findnext (as is usual) then the directory pointer
1161 * should already be at the correct place. Check this by scanning
1162 * backwards looking for an exact (ie. case sensitive) filename match.
1163 * If we get to the beginning of the directory and haven't found it then scan
1164 * forwards again looking for a match. JRA.
1167 int current_pos, start_pos;
1169 void *dirptr = conn->dirptr;
1170 start_pos = TellDir(dirptr);
1171 for(current_pos = start_pos; current_pos >= 0; current_pos--) {
1172 DEBUG(7,("call_trans2findnext: seeking to pos %d\n", current_pos));
1174 SeekDir(dirptr, current_pos);
1175 dname = ReadDirName(dirptr);
1178 * Remember, mangle_map is called by
1179 * get_lanman2_dir_entry(), so the resume name
1180 * could be mangled. Ensure we do the same
1185 mangle_map( dname, False, True, SNUM(conn));
1187 if(dname && strcsequal( resume_name, dname)) {
1188 SeekDir(dirptr, current_pos+1);
1189 DEBUG(7,("call_trans2findnext: got match at pos %d\n", current_pos+1 ));
1195 * Scan forward from start if not found going backwards.
1198 if(current_pos < 0) {
1199 DEBUG(7,("call_trans2findnext: notfound: seeking to pos %d\n", start_pos));
1200 SeekDir(dirptr, start_pos);
1201 for(current_pos = start_pos; (dname = ReadDirName(dirptr)) != NULL; SeekDir(dirptr,++current_pos)) {
1204 * Remember, mangle_map is called by
1205 * get_lanman2_dir_entry(), so the resume name
1206 * could be mangled. Ensure we do the same
1211 mangle_map( dname, False, True, SNUM(conn));
1213 if(dname && strcsequal( resume_name, dname)) {
1214 SeekDir(dirptr, current_pos+1);
1215 DEBUG(7,("call_trans2findnext: got match at pos %d\n", current_pos+1 ));
1219 } /* end if current_pos */
1220 } /* end if requires_resume_key && !continue_bit */
1222 for (i=0;(i<(int)maxentries) && !finished && !out_of_space ;i++) {
1223 BOOL got_exact_match = False;
1225 /* this is a heuristic to avoid seeking the dirptr except when
1226 absolutely necessary. It allows for a filename of about 40 chars */
1227 if (space_remaining < DIRLEN_GUESS && numentries > 0) {
1228 out_of_space = True;
1231 finished = !get_lanman2_dir_entry(conn,
1233 mask,dirtype,info_level,
1234 requires_resume_key,dont_descend,
1235 &p,pdata,space_remaining, &out_of_space, &got_exact_match,
1239 if (finished && out_of_space)
1242 if (!finished && !out_of_space)
1246 * As an optimisation if we know we aren't looking
1247 * for a wildcard name (ie. the name matches the wildcard exactly)
1248 * then we can finish on any (first) match.
1249 * This speeds up large directory searches. JRA.
1255 space_remaining = max_data_bytes - PTR_DIFF(p,pdata);
1258 /* Check if we can close the dirptr */
1259 if(close_after_request || (finished && close_if_end)) {
1260 DEBUG(5,("call_trans2findnext: closing dptr_num = %d\n", dptr_num));
1261 dptr_close(&dptr_num); /* This frees up the saved mask */
1265 /* Set up the return parameter block */
1266 SSVAL(params,0,numentries);
1267 SSVAL(params,2,finished);
1268 SSVAL(params,4,0); /* Never an EA error */
1269 SSVAL(params,6,last_name_off);
1271 send_trans2_replies( outbuf, bufsize, params, 8, pdata, PTR_DIFF(p,pdata));
1273 if ((! *directory) && dptr_path(dptr_num))
1274 slprintf(directory,sizeof(directory)-1, "(%s)",dptr_path(dptr_num));
1276 DEBUG( 3, ( "%s mask=%s directory=%s dirtype=%d numentries=%d\n",
1277 smb_fn_name(CVAL(inbuf,smb_com)),
1278 mask, directory, dirtype, numentries ) );
1283 /****************************************************************************
1284 Reply to a TRANS2_QFSINFO (query filesystem info).
1285 ****************************************************************************/
1287 static int call_trans2qfsinfo(connection_struct *conn, char *inbuf, char *outbuf,
1288 int length, int bufsize,
1289 char **pparams, int total_params, char **ppdata, int total_data)
1291 int max_data_bytes = SVAL(inbuf, smb_mdrcnt);
1292 char *pdata = *ppdata;
1293 char *params = *pparams;
1294 uint16 info_level = SVAL(params,0);
1297 char *vname = volume_label(SNUM(conn));
1298 int snum = SNUM(conn);
1299 char *fstype = lp_fstype(SNUM(conn));
1301 DEBUG(3,("call_trans2qfsinfo: level = %d\n", info_level));
1303 if(vfs_stat(conn,".",&st)!=0) {
1304 DEBUG(2,("call_trans2qfsinfo: stat of . failed (%s)\n", strerror(errno)));
1305 return ERROR_DOS(ERRSRV,ERRinvdevice);
1308 pdata = Realloc(*ppdata, max_data_bytes + 1024);
1309 if ( pdata == NULL )
1310 return ERROR_DOS(ERRDOS,ERRnomem);
1313 memset((char *)pdata,'\0',max_data_bytes + 1024);
1315 switch (info_level) {
1316 case SMB_INFO_ALLOCATION:
1318 SMB_BIG_UINT dfree,dsize,bsize;
1320 conn->vfs_ops.disk_free(conn,".",False,&bsize,&dfree,&dsize);
1321 SIVAL(pdata,l1_idFileSystem,st.st_dev);
1322 SIVAL(pdata,l1_cSectorUnit,bsize/512);
1323 SIVAL(pdata,l1_cUnit,dsize);
1324 SIVAL(pdata,l1_cUnitAvail,dfree);
1325 SSVAL(pdata,l1_cbSector,512);
1326 DEBUG(5,("call_trans2qfsinfo : bsize=%u, id=%x, cSectorUnit=%u, cUnit=%u, cUnitAvail=%u, cbSector=%d\n",
1327 (unsigned int)bsize, (unsigned int)st.st_dev, ((unsigned int)bsize)/512, (unsigned int)dsize,
1328 (unsigned int)dfree, 512));
1332 case SMB_INFO_VOLUME:
1333 /* Return volume name */
1335 * Add volume serial number - hash of a combination of
1336 * the called hostname and the service name.
1338 SIVAL(pdata,0,str_checksum(lp_servicename(snum)) ^ (str_checksum(local_machine)<<16) );
1339 len = srvstr_push(outbuf, pdata+l2_vol_szVolLabel, vname, -1, STR_TERMINATE);
1340 SCVAL(pdata,l2_vol_cch,len);
1341 data_len = l2_vol_szVolLabel + len;
1342 DEBUG(5,("call_trans2qfsinfo : time = %x, namelen = %d, name = %s\n",
1343 (unsigned)st.st_ctime, len, vname));
1346 case SMB_QUERY_FS_ATTRIBUTE_INFO:
1347 case SMB_FS_ATTRIBUTE_INFORMATION:
1349 SIVAL(pdata,0,FILE_CASE_PRESERVED_NAMES|FILE_CASE_SENSITIVE_SEARCH|
1350 (lp_nt_acl_support(SNUM(conn)) ? FILE_PERSISTENT_ACLS : 0)); /* FS ATTRIBUTES */
1351 SIVAL(pdata,4,255); /* Max filename component length */
1352 /* NOTE! the fstype must *not* be null terminated or win98 won't recognise it
1353 and will think we can't do long filenames */
1354 len = srvstr_push(outbuf, pdata+12, fstype, -1, 0);
1356 data_len = 12 + len;
1359 case SMB_QUERY_FS_LABEL_INFO:
1360 case SMB_FS_LABEL_INFORMATION:
1361 len = srvstr_push(outbuf, pdata+4, vname, -1, STR_TERMINATE);
1366 case SMB_QUERY_FS_VOLUME_INFO:
1367 case SMB_FS_VOLUME_INFORMATION:
1370 * Add volume serial number - hash of a combination of
1371 * the called hostname and the service name.
1373 SIVAL(pdata,8,str_checksum(lp_servicename(snum)) ^
1374 (str_checksum(local_machine)<<16));
1376 len = srvstr_push(outbuf, pdata+18, vname, -1, STR_TERMINATE);
1377 SIVAL(pdata,12,len);
1379 DEBUG(5,("call_trans2qfsinfo : SMB_QUERY_FS_VOLUME_INFO namelen = %d, vol=%s serv=%s\n",
1380 (int)strlen(vname),vname, lp_servicename(snum)));
1383 case SMB_QUERY_FS_SIZE_INFO:
1384 case SMB_FS_SIZE_INFORMATION:
1386 SMB_BIG_UINT dfree,dsize,bsize,block_size,sectors_per_unit,bytes_per_sector;
1388 conn->vfs_ops.disk_free(conn,".",False,&bsize,&dfree,&dsize);
1389 block_size = lp_block_size(snum);
1390 if (bsize < block_size) {
1391 SMB_BIG_UINT factor = block_size/bsize;
1396 if (bsize > block_size) {
1397 SMB_BIG_UINT factor = bsize/block_size;
1402 bytes_per_sector = 512;
1403 sectors_per_unit = bsize/bytes_per_sector;
1404 DEBUG(5,("call_trans2qfsinfo : SMB_QUERY_FS_SIZE_INFO bsize=%u, cSectorUnit=%u, \
1405 cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize, (unsigned int)sectors_per_unit,
1406 (unsigned int)bytes_per_sector, (unsigned int)dsize, (unsigned int)dfree));
1407 SBIG_UINT(pdata,0,dsize);
1408 SBIG_UINT(pdata,8,dfree);
1409 SIVAL(pdata,16,sectors_per_unit);
1410 SIVAL(pdata,20,bytes_per_sector);
1414 case SMB_FS_FULL_SIZE_INFORMATION:
1416 SMB_BIG_UINT dfree,dsize,bsize,block_size,sectors_per_unit,bytes_per_sector;
1418 conn->vfs_ops.disk_free(conn,".",False,&bsize,&dfree,&dsize);
1419 block_size = lp_block_size(snum);
1420 if (bsize < block_size) {
1421 SMB_BIG_UINT factor = block_size/bsize;
1426 if (bsize > block_size) {
1427 SMB_BIG_UINT factor = bsize/block_size;
1432 bytes_per_sector = 512;
1433 sectors_per_unit = bsize/bytes_per_sector;
1434 DEBUG(5,("call_trans2qfsinfo : SMB_QUERY_FS_FULL_SIZE_INFO bsize=%u, cSectorUnit=%u, \
1435 cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize, (unsigned int)sectors_per_unit,
1436 (unsigned int)bytes_per_sector, (unsigned int)dsize, (unsigned int)dfree));
1437 SBIG_UINT(pdata,0,dsize); /* Total Allocation units. */
1438 SBIG_UINT(pdata,8,dfree); /* Caller available allocation units. */
1439 SBIG_UINT(pdata,16,dfree); /* Actual available allocation units. */
1440 SIVAL(pdata,24,sectors_per_unit); /* Sectors per allocation unit. */
1441 SIVAL(pdata,28,bytes_per_sector); /* Bytes per sector. */
1445 case SMB_QUERY_FS_DEVICE_INFO:
1446 case SMB_FS_DEVICE_INFORMATION:
1448 SIVAL(pdata,0,0); /* dev type */
1449 SIVAL(pdata,4,0); /* characteristics */
1452 case SMB_FS_OBJECTID_INFORMATION:
1457 * Query the version and capabilities of the CIFS UNIX extensions
1461 case SMB_QUERY_CIFS_UNIX_INFO:
1462 if (!lp_unix_extensions())
1463 return ERROR_DOS(ERRDOS,ERRunknownlevel);
1465 SSVAL(pdata,0,CIFS_UNIX_MAJOR_VERSION);
1466 SSVAL(pdata,2,CIFS_UNIX_MINOR_VERSION);
1467 SBIG_UINT(pdata,4,((SMB_BIG_UINT)0)); /* No capabilities for now... */
1470 case SMB_MAC_QUERY_FS_INFO:
1472 * Thursby MAC extension... ONLY on NTFS filesystems
1473 * once we do streams then we don't need this
1475 if (strequal(lp_fstype(SNUM(conn)),"NTFS")) {
1477 SIVAL(pdata,84,0x100); /* Don't support mac... */
1482 return ERROR_DOS(ERRDOS,ERRunknownlevel);
1486 send_trans2_replies( outbuf, bufsize, params, 0, pdata, data_len);
1488 DEBUG( 4, ( "%s info_level = %d\n", smb_fn_name(CVAL(inbuf,smb_com)), info_level) );
1493 /****************************************************************************
1494 Reply to a TRANS2_SETFSINFO (set filesystem info).
1495 ****************************************************************************/
1497 static int call_trans2setfsinfo(connection_struct *conn,
1498 char *inbuf, char *outbuf, int length, int bufsize,
1499 char **pparams, int total_params, char **ppdata, int total_data)
1501 /* Just say yes we did it - there is nothing that
1502 can be set here so it doesn't matter. */
1504 DEBUG(3,("call_trans2setfsinfo\n"));
1506 if (!CAN_WRITE(conn))
1507 return ERROR_DOS(ERRSRV,ERRaccess);
1509 outsize = set_message(outbuf,10,0,True);
1514 /****************************************************************************
1515 * Utility function to set bad path error.
1516 ****************************************************************************/
1518 NTSTATUS set_bad_path_error(int err, BOOL bad_path)
1520 if((err == ENOENT) && bad_path) {
1521 unix_ERR_class = ERRDOS;
1522 unix_ERR_code = ERRbadpath;
1523 return NT_STATUS_OBJECT_PATH_NOT_FOUND;
1525 return NT_STATUS_OK;
1528 /****************************************************************************
1529 Reply to a TRANS2_QFILEPATHINFO or TRANSACT2_QFILEINFO (query file info by
1530 file name or file id).
1531 ****************************************************************************/
1533 static int call_trans2qfilepathinfo(connection_struct *conn,
1534 char *inbuf, char *outbuf, int length,
1536 char **pparams, int total_params, char **ppdata, int total_data)
1538 int max_data_bytes = SVAL(inbuf, smb_mdrcnt);
1539 char *params = *pparams;
1540 char *pdata = *ppdata;
1541 uint16 tran_call = SVAL(inbuf, smb_setup0);
1544 SMB_OFF_T file_size=0;
1545 SMB_OFF_T allocation_size=0;
1546 unsigned int data_size;
1547 SMB_STRUCT_STAT sbuf;
1548 pstring fname, dos_fname;
1553 BOOL bad_path = False;
1554 BOOL delete_pending = False;
1559 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
1561 if (tran_call == TRANSACT2_QFILEINFO) {
1562 files_struct *fsp = file_fsp(params,0);
1563 info_level = SVAL(params,2);
1565 DEBUG(3,("call_trans2qfilepathinfo: TRANSACT2_QFILEINFO: level = %d\n", info_level));
1567 if(fsp && (fsp->is_directory || fsp->fd == -1)) {
1569 * This is actually a QFILEINFO on a directory
1570 * handle (returned from an NT SMB). NT5.0 seems
1571 * to do this call. JRA.
1573 pstrcpy(fname, fsp->fsp_name);
1574 unix_convert(fname,conn,0,&bad_path,&sbuf);
1575 if (!check_name(fname,conn)) {
1576 DEBUG(3,("call_trans2qfilepathinfo: fileinfo of %s failed (%s)\n",fname,strerror(errno)));
1577 set_bad_path_error(errno, bad_path);
1578 return(UNIXERROR(ERRDOS,ERRbadpath));
1581 if (INFO_LEVEL_IS_UNIX(info_level)) {
1582 /* Always do lstat for UNIX calls. */
1583 if (vfs_lstat(conn,fname,&sbuf)) {
1584 DEBUG(3,("call_trans2qfilepathinfo: vfs_lstat of %s failed (%s)\n",fname,strerror(errno)));
1585 set_bad_path_error(errno, bad_path);
1586 return(UNIXERROR(ERRDOS,ERRbadpath));
1588 } else if (!VALID_STAT(sbuf) && vfs_stat(conn,fname,&sbuf)) {
1589 DEBUG(3,("call_trans2qfilepathinfo: vfs_stat of %s failed (%s)\n",fname,strerror(errno)));
1590 set_bad_path_error(errno, bad_path);
1591 return(UNIXERROR(ERRDOS,ERRbadpath));
1594 delete_pending = fsp->directory_delete_on_close;
1597 * Original code - this is an open file.
1599 CHECK_FSP(fsp,conn);
1601 pstrcpy(fname, fsp->fsp_name);
1602 if (vfs_fstat(fsp,fsp->fd,&sbuf) != 0) {
1603 DEBUG(3,("fstat of fnum %d failed (%s)\n", fsp->fnum, strerror(errno)));
1604 return(UNIXERROR(ERRDOS,ERRbadfid));
1606 if((pos = fsp->conn->vfs_ops.lseek(fsp,fsp->fd,0,SEEK_CUR)) == -1)
1607 return(UNIXERROR(ERRDOS,ERRnoaccess));
1609 delete_pending = fsp->delete_on_close;
1613 if (total_params < 6)
1614 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
1616 info_level = SVAL(params,0);
1618 DEBUG(3,("call_trans2qfilepathinfo: TRANSACT2_QPATHINFO: level = %d\n", info_level));
1620 srvstr_pull(inbuf, fname, ¶ms[6], sizeof(fname), -1, STR_TERMINATE);
1622 RESOLVE_DFSPATH(fname, conn, inbuf, outbuf);
1624 unix_convert(fname,conn,0,&bad_path,&sbuf);
1625 if (!check_name(fname,conn)) {
1626 DEBUG(3,("call_trans2qfilepathinfo: fileinfo of %s failed (%s)\n",fname,strerror(errno)));
1627 set_bad_path_error(errno, bad_path);
1628 return(UNIXERROR(ERRDOS,ERRbadpath));
1631 if (INFO_LEVEL_IS_UNIX(info_level)) {
1632 /* Always do lstat for UNIX calls. */
1633 if (vfs_lstat(conn,fname,&sbuf)) {
1634 DEBUG(3,("call_trans2qfilepathinfo: vfs_lstat of %s failed (%s)\n",fname,strerror(errno)));
1635 set_bad_path_error(errno, bad_path);
1636 return(UNIXERROR(ERRDOS,ERRbadpath));
1638 } else if (!VALID_STAT(sbuf) && vfs_stat(conn,fname,&sbuf)) {
1639 DEBUG(3,("call_trans2qfilepathinfo: vfs_stat of %s failed (%s)\n",fname,strerror(errno)));
1640 set_bad_path_error(errno, bad_path);
1641 return(UNIXERROR(ERRDOS,ERRbadpath));
1645 if (INFO_LEVEL_IS_UNIX(info_level) && !lp_unix_extensions())
1646 return ERROR_DOS(ERRDOS,ERRunknownlevel);
1648 DEBUG(3,("call_trans2qfilepathinfo %s level=%d call=%d total_data=%d\n",
1649 fname,info_level,tran_call,total_data));
1651 p = strrchr_m(fname,'/');
1657 mode = dos_mode(conn,fname,&sbuf);
1658 fullpathname = fname;
1659 file_size = get_file_size(sbuf);
1660 allocation_size = get_allocation_size(&sbuf);
1664 params = Realloc(*pparams,2);
1666 return ERROR_DOS(ERRDOS,ERRnomem);
1668 memset((char *)params,'\0',2);
1669 data_size = max_data_bytes + 1024;
1670 pdata = Realloc(*ppdata, data_size);
1671 if ( pdata == NULL )
1672 return ERROR_DOS(ERRDOS,ERRnomem);
1675 if (total_data > 0 && IVAL(pdata,0) == total_data) {
1676 /* uggh, EAs for OS2 */
1677 DEBUG(4,("Rejecting EA request with total_data=%d\n",total_data));
1678 return ERROR_DOS(ERRDOS,ERReasnotsupported);
1681 memset((char *)pdata,'\0',data_size);
1683 c_time = get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(conn)));
1685 if (lp_dos_filetime_resolution(SNUM(conn))) {
1687 sbuf.st_atime &= ~1;
1688 sbuf.st_mtime &= ~1;
1689 sbuf.st_mtime &= ~1;
1692 /* NT expects the name to be in an exact form of the *full*
1693 filename. See the trans2 torture test */
1694 if (strequal(base_name,".")) {
1695 pstrcpy(dos_fname, "\\");
1697 snprintf(dos_fname, sizeof(dos_fname), "\\%s", fname);
1698 string_replace(dos_fname, '/', '\\');
1701 switch (info_level) {
1702 case SMB_INFO_STANDARD:
1703 case SMB_INFO_QUERY_EA_SIZE:
1704 data_size = (info_level==1?22:26);
1705 put_dos_date2(pdata,l1_fdateCreation,c_time);
1706 put_dos_date2(pdata,l1_fdateLastAccess,sbuf.st_atime);
1707 put_dos_date2(pdata,l1_fdateLastWrite,sbuf.st_mtime); /* write time */
1708 SIVAL(pdata,l1_cbFile,(uint32)file_size);
1709 SIVAL(pdata,l1_cbFileAlloc,(uint32)allocation_size);
1710 SSVAL(pdata,l1_attrFile,mode);
1711 SIVAL(pdata,l1_attrFile+2,4); /* this is what OS2 does */
1714 case SMB_INFO_QUERY_EAS_FROM_LIST:
1716 put_dos_date2(pdata,0,c_time);
1717 put_dos_date2(pdata,4,sbuf.st_atime);
1718 put_dos_date2(pdata,8,sbuf.st_mtime);
1719 SIVAL(pdata,12,(uint32)file_size);
1720 SIVAL(pdata,16,(uint32)allocation_size);
1721 SIVAL(pdata,20,mode);
1724 case SMB_INFO_QUERY_ALL_EAS:
1726 SIVAL(pdata,0,data_size);
1730 return ERROR_DOS(ERRDOS,ERRbadfunc); /* os/2 needs this */
1732 case SMB_FILE_BASIC_INFORMATION:
1733 case SMB_QUERY_FILE_BASIC_INFO:
1735 if (info_level == SMB_QUERY_FILE_BASIC_INFO)
1736 data_size = 36; /* w95 returns 40 bytes not 36 - why ?. */
1741 put_long_date(pdata,c_time);
1742 put_long_date(pdata+8,sbuf.st_atime);
1743 put_long_date(pdata+16,sbuf.st_mtime); /* write time */
1744 put_long_date(pdata+24,sbuf.st_mtime); /* change time */
1745 SIVAL(pdata,32,mode);
1747 DEBUG(5,("SMB_QFBI - "));
1749 time_t create_time = c_time;
1750 DEBUG(5,("create: %s ", ctime(&create_time)));
1752 DEBUG(5,("access: %s ", ctime(&sbuf.st_atime)));
1753 DEBUG(5,("write: %s ", ctime(&sbuf.st_mtime)));
1754 DEBUG(5,("change: %s ", ctime(&sbuf.st_mtime)));
1755 DEBUG(5,("mode: %x\n", mode));
1759 case SMB_FILE_STANDARD_INFORMATION:
1760 case SMB_QUERY_FILE_STANDARD_INFO:
1763 SOFF_T(pdata,0,allocation_size);
1764 SOFF_T(pdata,8,file_size);
1765 SIVAL(pdata,16,sbuf.st_nlink);
1767 SCVAL(pdata,21,(mode&aDIR)?1:0);
1770 case SMB_FILE_EA_INFORMATION:
1771 case SMB_QUERY_FILE_EA_INFO:
1775 /* Get the 8.3 name - used if NT SMB was negotiated. */
1776 case SMB_QUERY_FILE_ALT_NAME_INFO:
1780 pstrcpy(short_name,base_name);
1781 /* Mangle if not already 8.3 */
1782 if(!mangle_is_8_3(short_name, True)) {
1783 mangle_map(short_name,True,True,SNUM(conn));
1785 len = srvstr_push(outbuf, pdata+4, short_name, -1, STR_TERMINATE|STR_UPPER);
1786 data_size = 4 + len;
1791 case SMB_QUERY_FILE_NAME_INFO:
1793 this must be *exactly* right for ACLs on mapped drives to work
1795 len = srvstr_push(outbuf, pdata+4, dos_fname, -1, STR_UNICODE);
1796 data_size = 4 + len;
1800 case SMB_FILE_ALLOCATION_INFORMATION:
1801 case SMB_QUERY_FILE_ALLOCATION_INFO:
1803 SOFF_T(pdata,0,allocation_size);
1806 case SMB_FILE_END_OF_FILE_INFORMATION:
1807 case SMB_QUERY_FILE_END_OF_FILEINFO:
1809 SOFF_T(pdata,0,file_size);
1812 case SMB_QUERY_FILE_ALL_INFO:
1813 put_long_date(pdata,c_time);
1814 put_long_date(pdata+8,sbuf.st_atime);
1815 put_long_date(pdata+16,sbuf.st_mtime); /* write time */
1816 put_long_date(pdata+24,sbuf.st_mtime); /* change time */
1817 SIVAL(pdata,32,mode);
1819 SOFF_T(pdata,0,allocation_size);
1820 SOFF_T(pdata,8,file_size);
1821 SIVAL(pdata,16,sbuf.st_nlink);
1822 SCVAL(pdata,20,delete_pending);
1823 SCVAL(pdata,21,(mode&aDIR)?1:0);
1825 SINO_T(pdata,0,(SMB_INO_T)sbuf.st_ino);
1826 pdata += 8; /* index number */
1827 pdata += 4; /* EA info */
1829 SIVAL(pdata,0,0xA9);
1831 SIVAL(pdata,0,0xd01BF);
1833 SOFF_T(pdata,0,pos); /* current offset */
1835 SIVAL(pdata,0,mode); /* is this the right sort of mode info? */
1837 pdata += 4; /* alignment */
1838 len = srvstr_push(outbuf, pdata+4, dos_fname, -1, STR_TERMINATE);
1841 data_size = PTR_DIFF(pdata,(*ppdata));
1844 case SMB_FILE_INTERNAL_INFORMATION:
1845 /* This should be an index number - looks like dev/ino to me :-) */
1846 SIVAL(pdata,0,sbuf.st_dev);
1847 SIVAL(pdata,4,sbuf.st_ino);
1851 case SMB_FILE_ACCESS_INFORMATION:
1852 SIVAL(pdata,0,0x12019F); /* ??? */
1856 case SMB_FILE_NAME_INFORMATION:
1857 /* Pathname with leading '\'. */
1860 byte_len = dos_PutUniCode(pdata+4,dos_fname,max_data_bytes,False);
1861 SIVAL(pdata,0,byte_len);
1862 data_size = 4 + byte_len;
1866 case SMB_FILE_DISPOSITION_INFORMATION:
1868 SCVAL(pdata,0,delete_pending);
1871 case SMB_FILE_POSITION_INFORMATION:
1873 SOFF_T(pdata,0,pos);
1876 case SMB_FILE_MODE_INFORMATION:
1877 SIVAL(pdata,0,mode);
1881 case SMB_FILE_ALIGNMENT_INFORMATION:
1882 SIVAL(pdata,0,0); /* No alignment needed. */
1887 /* Not yet finished... JRA */
1890 put_long_date(pdata,c_time);
1891 put_long_date(pdata+8,sbuf.st_atime);
1892 put_long_date(pdata+16,sbuf.st_mtime); /* write time */
1893 put_long_date(pdata+24,sbuf.st_mtime); /* change time */
1894 SIVAL(pdata,32,mode);
1895 SIVAL(pdata,36,0); /* ??? */
1896 SIVAL(pdata,40,0x20); /* ??? */
1897 SIVAL(pdata,44,0); /* ??? */
1898 SOFF_T(pdata,48,size);
1899 SIVAL(pdata,56,0x1); /* ??? */
1900 SIVAL(pdata,60,0); /* ??? */
1901 SIVAL(pdata,64,0); /* ??? */
1902 SIVAL(pdata,68,length); /* Following string length in bytes. */
1903 dos_PutUniCode(pdata+72,,False);
1908 case SMB_FILE_ALTERNATE_NAME_INFORMATION:
1909 /* Last component of pathname. */
1911 size_t byte_len = dos_PutUniCode(pdata+4,fname,max_data_bytes,False);
1912 SIVAL(pdata,0,byte_len);
1913 data_size = 4 + byte_len;
1919 * NT4 server just returns "invalid query" to this - if we try to answer
1920 * it then NTws gets a BSOD! (tridge).
1921 * W2K seems to want this. JRA.
1923 case SMB_QUERY_FILE_STREAM_INFO:
1925 case SMB_FILE_STREAM_INFORMATION:
1929 size_t byte_len = dos_PutUniCode(pdata+24,"::$DATA", 0xE, False);
1930 SIVAL(pdata,0,0); /* ??? */
1931 SIVAL(pdata,4,byte_len); /* Byte length of unicode string ::$DATA */
1932 SOFF_T(pdata,8,file_size);
1933 SIVAL(pdata,16,allocation_size);
1934 SIVAL(pdata,20,0); /* ??? */
1935 data_size = 24 + byte_len;
1939 case SMB_FILE_COMPRESSION_INFORMATION:
1940 SOFF_T(pdata,0,allocation_size);
1941 SIVAL(pdata,8,0); /* ??? */
1942 SIVAL(pdata,12,0); /* ??? */
1946 case SMB_FILE_NETWORK_OPEN_INFORMATION:
1947 put_long_date(pdata,c_time);
1948 put_long_date(pdata+8,sbuf.st_atime);
1949 put_long_date(pdata+16,sbuf.st_mtime); /* write time */
1950 put_long_date(pdata+24,sbuf.st_mtime); /* change time */
1951 SIVAL(pdata,32,allocation_size);
1952 SOFF_T(pdata,40,file_size);
1953 SIVAL(pdata,48,mode);
1954 SIVAL(pdata,52,0); /* ??? */
1958 case SMB_FILE_ATTRIBUTE_TAG_INFORMATION:
1959 SIVAL(pdata,0,mode);
1965 * CIFS UNIX Extensions.
1968 case SMB_QUERY_FILE_UNIX_BASIC:
1970 DEBUG(4,("call_trans2qfilepathinfo: st_mode=%o\n",(int)sbuf.st_mode));
1972 SOFF_T(pdata,0,get_file_size(sbuf)); /* File size 64 Bit */
1975 #if defined(HAVE_STAT_ST_BLOCKS) && defined(STAT_ST_BLOCKSIZE)
1976 SOFF_T(pdata,0,sbuf.st_blocks*STAT_ST_BLOCKSIZE); /* Number of bytes used on disk - 64 Bit */
1978 /* Can't get the value - fake it using size. */
1979 SOFF_T(pdata,0,get_file_size(sbuf)); /* Number of bytes used on disk - 64 Bit */
1983 put_long_date(pdata,sbuf.st_ctime); /* Creation Time 64 Bit */
1984 put_long_date(pdata+8,sbuf.st_atime); /* Last access time 64 Bit */
1985 put_long_date(pdata+16,sbuf.st_mtime); /* Last modification time 64 Bit */
1988 SIVAL(pdata,0,sbuf.st_uid); /* user id for the owner */
1992 SIVAL(pdata,0,sbuf.st_gid); /* group id of owner */
1996 SIVAL(pdata,0,unix_filetype(sbuf.st_mode));
1999 SIVAL(pdata,0,unix_dev_major(sbuf.st_rdev)); /* Major device number if type is device */
2003 SIVAL(pdata,0,unix_dev_minor(sbuf.st_rdev)); /* Minor device number if type is device */
2007 SINO_T(pdata,0,(SMB_INO_T)sbuf.st_ino); /* inode number */
2010 SIVAL(pdata,0, unix_perms_to_wire(sbuf.st_mode)); /* Standard UNIX file permissions */
2014 SIVAL(pdata,0,sbuf.st_nlink); /* number of hard links */
2017 data_size = PTR_DIFF(pdata,(*ppdata));
2021 DEBUG(4,("call_trans2qfilepathinfo: SMB_QUERY_FILE_UNIX_BASIC"));
2023 for (i=0; i<100; i++)
2024 DEBUG(4,("%d=%x, ",i, (*ppdata)[i]));
2030 case SMB_QUERY_FILE_UNIX_LINK:
2035 if(!S_ISLNK(sbuf.st_mode))
2036 return(UNIXERROR(ERRSRV,ERRbadlink));
2038 return(UNIXERROR(ERRDOS,ERRbadlink));
2040 len = conn->vfs_ops.readlink(conn,fullpathname, buffer, sizeof(pstring)-1); /* read link */
2042 return(UNIXERROR(ERRDOS,ERRnoaccess));
2044 len = srvstr_push(outbuf, pdata, buffer, -1, STR_TERMINATE);
2046 data_size = PTR_DIFF(pdata,(*ppdata));
2052 return ERROR_DOS(ERRDOS,ERRunknownlevel);
2055 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, data_size);
2060 /****************************************************************************
2061 Deal with the internal needs of setting the delete on close flag. Note that
2062 as the tdb locking is recursive, it is safe to call this from within
2063 open_file_shared. JRA.
2064 ****************************************************************************/
2066 NTSTATUS set_delete_on_close_internal(files_struct *fsp, BOOL delete_on_close)
2069 * Only allow delete on close for writable shares.
2072 if (delete_on_close && !CAN_WRITE(fsp->conn)) {
2073 DEBUG(10,("set_delete_on_close_internal: file %s delete on close flag set but write access denied on share.\n",
2075 return NT_STATUS_ACCESS_DENIED;
2078 * Only allow delete on close for files/directories opened with delete intent.
2081 if (delete_on_close && !(fsp->desired_access & DELETE_ACCESS)) {
2082 DEBUG(10,("set_delete_on_close_internal: file %s delete on close flag set but delete access denied.\n",
2084 return NT_STATUS_ACCESS_DENIED;
2087 if(fsp->is_directory) {
2088 fsp->directory_delete_on_close = delete_on_close;
2089 DEBUG(10, ("set_delete_on_close_internal: %s delete on close flag for fnum = %d, directory %s\n",
2090 delete_on_close ? "Added" : "Removed", fsp->fnum, fsp->fsp_name ));
2093 files_struct *iterate_fsp;
2096 * Modify the share mode entry for all files open
2097 * on this device and inode to tell other smbds we have
2098 * changed the delete on close flag. This will be noticed
2099 * in the close code, the last closer will delete the file
2103 DEBUG(10,("set_delete_on_close_internal: %s delete on close flag for fnum = %d, file %s\n",
2104 delete_on_close ? "Adding" : "Removing", fsp->fnum, fsp->fsp_name ));
2106 if (lock_share_entry_fsp(fsp) == False)
2107 return NT_STATUS_ACCESS_DENIED;
2109 if (!modify_delete_flag(fsp->dev, fsp->inode, delete_on_close)) {
2110 DEBUG(0,("set_delete_on_close_internal: failed to change delete on close flag for file %s\n",
2112 unlock_share_entry_fsp(fsp);
2113 return NT_STATUS_ACCESS_DENIED;
2120 unlock_share_entry_fsp(fsp);
2123 * Go through all files we have open on the same device and
2124 * inode (hanging off the same hash bucket) and set the DELETE_ON_CLOSE_FLAG.
2125 * Other smbd's that have this file open will look in the share_mode on close.
2126 * take care of this (rare) case in close_file(). See the comment there.
2127 * NB. JRA. We don't really need to do this anymore - all should be taken
2128 * care of in the share_mode changes in the tdb.
2131 for(iterate_fsp = file_find_di_first(fsp->dev, fsp->inode);
2132 iterate_fsp; iterate_fsp = file_find_di_next(iterate_fsp))
2133 fsp->delete_on_close = delete_on_close;
2136 * Set the delete on close flag in the fsp.
2138 fsp->delete_on_close = delete_on_close;
2140 DEBUG(10, ("set_delete_on_close_internal: %s delete on close flag for fnum = %d, file %s\n",
2141 delete_on_close ? "Added" : "Removed", fsp->fnum, fsp->fsp_name ));
2145 return NT_STATUS_OK;
2148 /****************************************************************************
2149 Returns true if this pathname is within the share, and thus safe.
2150 ****************************************************************************/
2152 static int ensure_link_is_safe(connection_struct *conn, const char *link_dest_in, char *link_dest_out)
2155 char resolved_name[PATH_MAX+1];
2157 pstring resolved_name;
2159 fstring last_component;
2163 BOOL bad_path = False;
2164 SMB_STRUCT_STAT sbuf;
2166 pstrcpy(link_dest, link_dest_in);
2167 unix_convert(link_dest,conn,0,&bad_path,&sbuf);
2169 /* Store the UNIX converted path. */
2170 pstrcpy(link_dest_out, link_dest);
2172 p = strrchr(link_dest, '/');
2174 fstrcpy(last_component, p+1);
2177 fstrcpy(last_component, link_dest);
2178 pstrcpy(link_dest, "./");
2181 if (conn->vfs_ops.realpath(conn,link_dest,resolved_name) == NULL)
2184 pstrcpy(link_dest, resolved_name);
2185 pstrcat(link_dest, "/");
2186 pstrcat(link_dest, last_component);
2188 if (*link_dest != '/') {
2189 /* Relative path. */
2190 pstrcpy(link_test, conn->connectpath);
2191 pstrcat(link_test, "/");
2192 pstrcat(link_test, link_dest);
2194 pstrcpy(link_test, link_dest);
2198 * Check if the link is within the share.
2201 if (strncmp(conn->connectpath, link_test, strlen(conn->connectpath))) {
2208 /****************************************************************************
2209 Reply to a TRANS2_SETFILEINFO (set file info by fileid).
2210 ****************************************************************************/
2212 static int call_trans2setfilepathinfo(connection_struct *conn,
2213 char *inbuf, char *outbuf, int length, int bufsize,
2214 char **pparams, int total_params, char **ppdata, int total_data)
2216 char *params = *pparams;
2217 char *pdata = *ppdata;
2218 uint16 tran_call = SVAL(inbuf, smb_setup0);
2223 SMB_STRUCT_STAT sbuf;
2226 BOOL bad_path = False;
2227 files_struct *fsp = NULL;
2228 uid_t set_owner = (uid_t)SMB_UID_NO_CHANGE;
2229 gid_t set_grp = (uid_t)SMB_GID_NO_CHANGE;
2230 mode_t unixmode = 0;
2232 if (tran_call == TRANSACT2_SETFILEINFO) {
2233 fsp = file_fsp(params,0);
2234 info_level = SVAL(params,2);
2236 if(fsp && (fsp->is_directory || fsp->fd == -1)) {
2238 * This is actually a SETFILEINFO on a directory
2239 * handle (returned from an NT SMB). NT5.0 seems
2240 * to do this call. JRA.
2242 pstrcpy(fname, fsp->fsp_name);
2243 unix_convert(fname,conn,0,&bad_path,&sbuf);
2244 if (!check_name(fname,conn) || (!VALID_STAT(sbuf))) {
2245 DEBUG(3,("call_trans2setfilepathinfo: fileinfo of %s failed (%s)\n",fname,strerror(errno)));
2246 set_bad_path_error(errno, bad_path);
2247 return(UNIXERROR(ERRDOS,ERRbadpath));
2249 } else if (fsp && fsp->print_file) {
2251 * Doing a DELETE_ON_CLOSE should cancel a print job.
2253 if ((info_level == SMB_SET_FILE_DISPOSITION_INFO) && CVAL(pdata,0)) {
2254 fsp->share_mode = FILE_DELETE_ON_CLOSE;
2256 DEBUG(3,("call_trans2setfilepathinfo: Cancelling print job (%s)\n", fsp->fsp_name ));
2259 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
2262 return (UNIXERROR(ERRDOS,ERRbadpath));
2265 * Original code - this is an open file.
2267 CHECK_FSP(fsp,conn);
2269 pstrcpy(fname, fsp->fsp_name);
2272 if (vfs_fstat(fsp,fd,&sbuf) != 0) {
2273 DEBUG(3,("call_trans2setfilepathinfo: fstat of fnum %d failed (%s)\n",fsp->fnum, strerror(errno)));
2274 return(UNIXERROR(ERRDOS,ERRbadfid));
2279 if (total_params < 6)
2280 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
2282 info_level = SVAL(params,0);
2283 srvstr_pull(inbuf, fname, ¶ms[6], sizeof(fname), -1, STR_TERMINATE);
2284 unix_convert(fname,conn,0,&bad_path,&sbuf);
2285 if(!check_name(fname, conn)) {
2286 set_bad_path_error(errno, bad_path);
2287 return(UNIXERROR(ERRDOS,ERRbadpath));
2291 * For CIFS UNIX extensions the target name may not exist.
2294 if(!VALID_STAT(sbuf) && !INFO_LEVEL_IS_UNIX(info_level)) {
2295 DEBUG(3,("call_trans2setfilepathinfo: stat of %s failed (%s)\n", fname, strerror(errno)));
2296 set_bad_path_error(errno, bad_path);
2297 return(UNIXERROR(ERRDOS,ERRbadpath));
2301 if (!CAN_WRITE(conn))
2302 return ERROR_DOS(ERRSRV,ERRaccess);
2304 if (INFO_LEVEL_IS_UNIX(info_level) && !lp_unix_extensions())
2305 return ERROR_DOS(ERRDOS,ERRunknownlevel);
2307 if (VALID_STAT(sbuf))
2308 unixmode = sbuf.st_mode;
2310 DEBUG(3,("call_trans2setfilepathinfo(%d) %s info_level=%d totdata=%d\n",
2311 tran_call,fname,info_level,total_data));
2313 /* Realloc the parameter and data sizes */
2314 params = Realloc(*pparams,2);
2316 return ERROR_DOS(ERRDOS,ERRnomem);
2322 /* the pending modtime overrides the current modtime */
2323 sbuf.st_mtime = fsp->pending_modtime;
2326 size = get_file_size(sbuf);
2327 tvs.modtime = sbuf.st_mtime;
2328 tvs.actime = sbuf.st_atime;
2329 dosmode = dos_mode(conn,fname,&sbuf);
2330 unixmode = sbuf.st_mode;
2332 set_owner = VALID_STAT(sbuf) ? sbuf.st_uid : (uid_t)SMB_UID_NO_CHANGE;
2333 set_grp = VALID_STAT(sbuf) ? sbuf.st_gid : (gid_t)SMB_GID_NO_CHANGE;
2335 switch (info_level) {
2336 case SMB_INFO_STANDARD:
2337 case SMB_INFO_QUERY_EA_SIZE:
2339 if (total_data < l1_cbFile+4)
2340 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
2343 tvs.actime = make_unix_date2(pdata+l1_fdateLastAccess);
2346 tvs.modtime = make_unix_date2(pdata+l1_fdateLastWrite);
2348 dosmode = SVAL(pdata,l1_attrFile);
2349 size = IVAL(pdata,l1_cbFile);
2354 /* XXXX um, i don't think this is right.
2355 it's also not in the cifs6.txt spec.
2357 case SMB_INFO_QUERY_EAS_FROM_LIST:
2358 if (total_data < 28)
2359 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
2361 tvs.actime = make_unix_date2(pdata+8);
2362 tvs.modtime = make_unix_date2(pdata+12);
2363 size = IVAL(pdata,16);
2364 dosmode = IVAL(pdata,24);
2367 /* XXXX nor this. not in cifs6.txt, either. */
2368 case SMB_INFO_QUERY_ALL_EAS:
2369 if (total_data < 28)
2370 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
2372 tvs.actime = make_unix_date2(pdata+8);
2373 tvs.modtime = make_unix_date2(pdata+12);
2374 size = IVAL(pdata,16);
2375 dosmode = IVAL(pdata,24);
2378 case SMB_SET_FILE_BASIC_INFO:
2379 case SMB_FILE_BASIC_INFORMATION:
2381 /* Patch to do this correctly from Paul Eggert <eggert@twinsun.com>. */
2383 time_t changed_time;
2385 if (total_data < 36)
2386 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
2388 /* Ignore create time at offset pdata. */
2391 tvs.actime = interpret_long_date(pdata+8);
2393 write_time = interpret_long_date(pdata+16);
2394 changed_time = interpret_long_date(pdata+24);
2396 tvs.modtime = MIN(write_time, changed_time);
2398 if (write_time > tvs.modtime && write_time != 0xffffffff) {
2399 tvs.modtime = write_time;
2401 /* Prefer a defined time to an undefined one. */
2402 if (tvs.modtime == (time_t)0 || tvs.modtime == (time_t)-1)
2403 tvs.modtime = (write_time == (time_t)0 || write_time == (time_t)-1
2404 ? changed_time : write_time);
2407 dosmode = IVAL(pdata,32);
2411 case SMB_FILE_ALLOCATION_INFORMATION:
2412 case SMB_SET_FILE_ALLOCATION_INFO:
2415 SMB_OFF_T allocation_size = IVAL(pdata,0);
2418 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
2420 #ifdef LARGE_SMB_OFF_T
2421 allocation_size |= (((SMB_OFF_T)IVAL(pdata,4)) << 32);
2422 #else /* LARGE_SMB_OFF_T */
2423 if (IVAL(pdata,4) != 0) /* more than 32 bits? */
2424 return ERROR_DOS(ERRDOS,ERRunknownlevel);
2425 #endif /* LARGE_SMB_OFF_T */
2426 DEBUG(10,("call_trans2setfilepathinfo: Set file allocation info for file %s to %.0f\n",
2427 fname, (double)allocation_size ));
2429 if(allocation_size != get_file_size(sbuf)) {
2430 SMB_STRUCT_STAT new_sbuf;
2432 DEBUG(10,("call_trans2setfilepathinfo: file %s : setting new allocation size to %.0f\n",
2433 fname, (double)allocation_size ));
2436 files_struct *new_fsp = NULL;
2437 int access_mode = 0;
2440 if(global_oplock_break) {
2441 /* Queue this file modify as we are the process of an oplock break. */
2443 DEBUG(2,("call_trans2setfilepathinfo: queueing message due to being "));
2444 DEBUGADD(2,( "in oplock break state.\n"));
2446 push_oplock_pending_smb_message(inbuf, length);
2450 new_fsp = open_file_shared1(conn, fname, &sbuf,FILE_WRITE_DATA,
2451 SET_OPEN_MODE(DOS_OPEN_RDWR),
2452 (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN),
2453 0, 0, &access_mode, &action);
2455 if (new_fsp == NULL)
2456 return(UNIXERROR(ERRDOS,ERRbadpath));
2457 ret = vfs_allocate_file_space(new_fsp, allocation_size);
2458 if (vfs_fstat(new_fsp,new_fsp->fd,&new_sbuf) != 0) {
2459 DEBUG(3,("call_trans2setfilepathinfo: fstat of fnum %d failed (%s)\n",
2460 new_fsp->fnum, strerror(errno)));
2463 close_file(new_fsp,True);
2465 ret = vfs_allocate_file_space(fsp, allocation_size);
2466 if (vfs_fstat(fsp,fd,&new_sbuf) != 0) {
2467 DEBUG(3,("call_trans2setfilepathinfo: fstat of fnum %d failed (%s)\n",
2468 fsp->fnum, strerror(errno)));
2473 return ERROR_NT(NT_STATUS_DISK_FULL);
2475 /* Allocate can truncate size... */
2476 size = get_file_size(new_sbuf);
2482 case SMB_FILE_END_OF_FILE_INFORMATION:
2483 case SMB_SET_FILE_END_OF_FILE_INFO:
2486 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
2488 size = IVAL(pdata,0);
2489 #ifdef LARGE_SMB_OFF_T
2490 size |= (((SMB_OFF_T)IVAL(pdata,4)) << 32);
2491 #else /* LARGE_SMB_OFF_T */
2492 if (IVAL(pdata,4) != 0) /* more than 32 bits? */
2493 return ERROR_DOS(ERRDOS,ERRunknownlevel);
2494 #endif /* LARGE_SMB_OFF_T */
2495 DEBUG(10,("call_trans2setfilepathinfo: Set end of file info for file %s to %.0f\n", fname, (double)size ));
2499 case SMB_FILE_DISPOSITION_INFORMATION:
2500 case SMB_SET_FILE_DISPOSITION_INFO: /* Set delete on close for open file. */
2502 BOOL delete_on_close = (CVAL(pdata,0) ? True : False);
2506 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
2508 if (tran_call != TRANSACT2_SETFILEINFO)
2509 return ERROR_DOS(ERRDOS,ERRunknownlevel);
2512 return(UNIXERROR(ERRDOS,ERRbadfid));
2514 status = set_delete_on_close_internal(fsp, delete_on_close);
2516 if (NT_STATUS_V(status) != NT_STATUS_V(NT_STATUS_OK))
2517 return ERROR_NT(status);
2523 * CIFS UNIX extensions.
2526 case SMB_SET_FILE_UNIX_BASIC:
2528 uint32 raw_unixmode;
2530 if (total_data < 100)
2531 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
2533 if(IVAL(pdata, 0) != SMB_SIZE_NO_CHANGE_LO &&
2534 IVAL(pdata, 4) != SMB_SIZE_NO_CHANGE_HI) {
2535 size=IVAL(pdata,0); /* first 8 Bytes are size */
2536 #ifdef LARGE_SMB_OFF_T
2537 size |= (((SMB_OFF_T)IVAL(pdata,4)) << 32);
2538 #else /* LARGE_SMB_OFF_T */
2539 if (IVAL(pdata,4) != 0) /* more than 32 bits? */
2540 return ERROR_DOS(ERRDOS,ERRunknownlevel);
2541 #endif /* LARGE_SMB_OFF_T */
2543 pdata+=24; /* ctime & st_blocks are not changed */
2544 tvs.actime = interpret_long_unix_date(pdata); /* access_time */
2545 tvs.modtime = interpret_long_unix_date(pdata+8); /* modification_time */
2547 set_owner = (uid_t)IVAL(pdata,0);
2549 set_grp = (gid_t)IVAL(pdata,0);
2551 raw_unixmode = IVAL(pdata,28);
2552 unixmode = unix_perms_from_wire(conn, &sbuf, raw_unixmode);
2553 dosmode = 0; /* Ensure dos mode change doesn't override this. */
2555 DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_BASIC: name = %s \
2556 size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n",
2557 fname, (double)size, (unsigned int)set_owner, (unsigned int)set_grp, (int)raw_unixmode));
2559 if (!VALID_STAT(sbuf)) {
2562 * The only valid use of this is to create character and block
2563 * devices, and named pipes. This is deprecated (IMHO) and
2564 * a new info level should be used for mknod. JRA.
2567 #if !defined(HAVE_MAKEDEV_FN)
2568 return(ERROR_DOS(ERRDOS,ERRnoaccess));
2569 #else /* HAVE_MAKEDEV_FN */
2570 uint32 file_type = IVAL(pdata,0);
2571 uint32 dev_major = IVAL(pdata,4);
2572 uint32 dev_minor = IVAL(pdata,12);
2574 uid_t myuid = geteuid();
2575 gid_t mygid = getegid();
2578 if (tran_call == TRANSACT2_SETFILEINFO)
2579 return(ERROR_DOS(ERRDOS,ERRnoaccess));
2581 if (raw_unixmode == SMB_MODE_NO_CHANGE)
2582 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
2584 dev = makedev(dev_major, dev_minor);
2586 /* We can only create as the owner/group we are. */
2588 if ((set_owner != myuid) && (set_owner != (uid_t)SMB_UID_NO_CHANGE))
2589 return(ERROR_DOS(ERRDOS,ERRnoaccess));
2590 if ((set_grp != mygid) && (set_grp != (gid_t)SMB_GID_NO_CHANGE))
2591 return(ERROR_DOS(ERRDOS,ERRnoaccess));
2593 if (file_type != UNIX_TYPE_CHARDEV && file_type != UNIX_TYPE_BLKDEV &&
2594 file_type != UNIX_TYPE_FIFO)
2595 return(ERROR_DOS(ERRDOS,ERRnoaccess));
2597 DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_BASIC doing mknod dev %.0f mode \
2598 0%o for file %s\n", (double)dev, unixmode, fname ));
2600 /* Ok - do the mknod. */
2601 if (conn->vfs_ops.mknod(conn,dos_to_unix_static(fname), unixmode, dev) != 0)
2602 return(UNIXERROR(ERRDOS,ERRnoaccess));
2605 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
2607 #endif /* HAVE_MAKEDEV_FN */
2612 * Deal with the UNIX specific mode set.
2615 if (raw_unixmode != SMB_MODE_NO_CHANGE) {
2616 DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_BASIC setting mode 0%o for file %s\n",
2617 (unsigned int)unixmode, fname ));
2618 if (vfs_chmod(conn,fname,unixmode) != 0)
2619 return(UNIXERROR(ERRDOS,ERRnoaccess));
2623 * Deal with the UNIX specific uid set.
2626 if ((set_owner != (uid_t)SMB_UID_NO_CHANGE) && (sbuf.st_uid != set_owner)) {
2627 DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_BASIC changing owner %u for file %s\n",
2628 (unsigned int)set_owner, fname ));
2629 if (vfs_chown(conn,fname,set_owner, (gid_t)-1) != 0)
2630 return(UNIXERROR(ERRDOS,ERRnoaccess));
2634 * Deal with the UNIX specific gid set.
2637 if ((set_grp != (uid_t)SMB_GID_NO_CHANGE) && (sbuf.st_gid != set_grp)) {
2638 DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_BASIC changing group %u for file %s\n",
2639 (unsigned int)set_owner, fname ));
2640 if (vfs_chown(conn,fname,(uid_t)-1, set_grp) != 0)
2641 return(UNIXERROR(ERRDOS,ERRnoaccess));
2646 case SMB_SET_FILE_UNIX_LINK:
2649 /* Set a symbolic link. */
2650 /* Don't allow this if follow links is false. */
2652 if (!lp_symlinks(SNUM(conn)))
2653 return(ERROR_DOS(ERRDOS,ERRnoaccess));
2655 /* Disallow if already exists. */
2656 if (VALID_STAT(sbuf))
2657 return(ERROR_DOS(ERRDOS,ERRbadpath));
2659 srvstr_pull(inbuf, link_dest, pdata, sizeof(link_dest), -1, STR_TERMINATE);
2661 if (ensure_link_is_safe(conn, link_dest, link_dest) != 0)
2662 return(UNIXERROR(ERRDOS,ERRnoaccess));
2664 DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_LINK doing symlink %s -> %s\n",
2665 fname, link_dest ));
2667 if (conn->vfs_ops.symlink(conn,link_dest,fname) != 0)
2668 return(UNIXERROR(ERRDOS,ERRnoaccess));
2670 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
2674 case SMB_SET_FILE_UNIX_HLINK:
2678 /* Set a hard link. */
2680 /* Disallow if already exists. */
2681 if (VALID_STAT(sbuf))
2682 return(ERROR_DOS(ERRDOS,ERRbadpath));
2684 srvstr_pull(inbuf, link_dest, pdata, sizeof(link_dest), -1, STR_TERMINATE);
2686 if (ensure_link_is_safe(conn, link_dest, link_dest) != 0)
2687 return(UNIXERROR(ERRDOS,ERRnoaccess));
2689 DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_LINK doing hard link %s -> %s\n",
2690 fname, link_dest ));
2692 if (conn->vfs_ops.link(conn,link_dest,fname) != 0)
2693 return(UNIXERROR(ERRDOS,ERRnoaccess));
2695 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
2700 return ERROR_DOS(ERRDOS,ERRunknownlevel);
2703 /* get some defaults (no modifications) if any info is zero or -1. */
2704 if (tvs.actime == (time_t)0 || tvs.actime == (time_t)-1)
2705 tvs.actime = sbuf.st_atime;
2707 if (tvs.modtime == (time_t)0 || tvs.modtime == (time_t)-1)
2708 tvs.modtime = sbuf.st_mtime;
2710 DEBUG(6,("actime: %s " , ctime(&tvs.actime)));
2711 DEBUG(6,("modtime: %s ", ctime(&tvs.modtime)));
2712 DEBUG(6,("size: %.0f ", (double)size));
2714 if (S_ISDIR(sbuf.st_mode))
2719 DEBUG(6,("dosmode: %x\n" , dosmode));
2721 if(!((info_level == SMB_SET_FILE_END_OF_FILE_INFO) ||
2722 (info_level == SMB_SET_FILE_ALLOCATION_INFO) ||
2723 (info_level == SMB_FILE_ALLOCATION_INFORMATION) ||
2724 (info_level == SMB_FILE_END_OF_FILE_INFORMATION))) {
2727 * Only do this test if we are not explicitly
2728 * changing the size of a file.
2731 size = get_file_size(sbuf);
2735 * Try and set the times, size and mode of this file -
2736 * if they are different from the current values
2738 if (sbuf.st_mtime != tvs.modtime || sbuf.st_atime != tvs.actime) {
2741 * This was a setfileinfo on an open file.
2742 * NT does this a lot. It's actually pointless
2743 * setting the time here, as it will be overwritten
2744 * on the next write, so we save the request
2745 * away and will set it on file close. JRA.
2748 if (tvs.modtime != (time_t)0 && tvs.modtime != (time_t)-1) {
2749 DEBUG(10,("call_trans2setfilepathinfo: setting pending modtime to %s\n", ctime(&tvs.modtime) ));
2750 fsp->pending_modtime = tvs.modtime;
2755 DEBUG(10,("call_trans2setfilepathinfo: setting utimes to modified values.\n"));
2757 if(file_utime(conn, fname, &tvs)!=0)
2758 return(UNIXERROR(ERRDOS,ERRnoaccess));
2762 /* check the mode isn't different, before changing it */
2763 if ((dosmode != 0) && (dosmode != dos_mode(conn, fname, &sbuf))) {
2765 DEBUG(10,("call_trans2setfilepathinfo: file %s : setting dos mode %x\n", fname, dosmode ));
2767 if(file_chmod(conn, fname, dosmode, NULL)) {
2768 DEBUG(2,("chmod of %s failed (%s)\n", fname, strerror(errno)));
2769 return(UNIXERROR(ERRDOS,ERRnoaccess));
2773 if (size != get_file_size(sbuf)) {
2777 DEBUG(10,("call_trans2setfilepathinfo: file %s : setting new size to %.0f\n",
2778 fname, (double)size ));
2781 files_struct *new_fsp = NULL;
2782 int access_mode = 0;
2785 if(global_oplock_break) {
2786 /* Queue this file modify as we are the process of an oplock break. */
2788 DEBUG(2,("call_trans2setfilepathinfo: queueing message due to being "));
2789 DEBUGADD(2,( "in oplock break state.\n"));
2791 push_oplock_pending_smb_message(inbuf, length);
2795 new_fsp = open_file_shared(conn, fname, &sbuf,
2796 SET_OPEN_MODE(DOS_OPEN_RDWR),
2797 (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN),
2798 0, 0, &access_mode, &action);
2800 if (new_fsp == NULL)
2801 return(UNIXERROR(ERRDOS,ERRbadpath));
2802 ret = vfs_set_filelen(new_fsp, size);
2803 close_file(new_fsp,True);
2805 ret = vfs_set_filelen(fsp, size);
2809 return (UNIXERROR(ERRHRD,ERRdiskfull));
2813 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
2818 /****************************************************************************
2819 Reply to a TRANS2_MKDIR (make directory with extended attributes).
2820 ****************************************************************************/
2822 static int call_trans2mkdir(connection_struct *conn,
2823 char *inbuf, char *outbuf, int length, int bufsize,
2824 char **pparams, int total_params, char **ppdata, int total_data)
2826 char *params = *pparams;
2829 SMB_STRUCT_STAT sbuf;
2830 BOOL bad_path = False;
2832 if (!CAN_WRITE(conn))
2833 return ERROR_DOS(ERRSRV,ERRaccess);
2835 if (total_params < 4)
2836 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
2838 srvstr_pull(inbuf, directory, ¶ms[4], sizeof(directory), -1, STR_TERMINATE);
2840 DEBUG(3,("call_trans2mkdir : name = %s\n", directory));
2842 unix_convert(directory,conn,0,&bad_path,&sbuf);
2843 if (check_name(directory,conn))
2844 ret = vfs_mkdir(conn,directory,unix_mode(conn,aDIR,directory));
2847 DEBUG(5,("call_trans2mkdir error (%s)\n", strerror(errno)));
2848 set_bad_path_error(errno, bad_path);
2849 return(UNIXERROR(ERRDOS,ERRnoaccess));
2852 /* Realloc the parameter and data sizes */
2853 params = Realloc(*pparams,2);
2855 return ERROR_DOS(ERRDOS,ERRnomem);
2860 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
2865 /****************************************************************************
2866 Reply to a TRANS2_FINDNOTIFYFIRST (start monitoring a directory for changes).
2867 We don't actually do this - we just send a null response.
2868 ****************************************************************************/
2870 static int call_trans2findnotifyfirst(connection_struct *conn,
2871 char *inbuf, char *outbuf, int length, int bufsize,
2872 char **pparams, int total_params, char **ppdata, int total_data)
2874 static uint16 fnf_handle = 257;
2875 char *params = *pparams;
2878 if (total_params < 6)
2879 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
2881 info_level = SVAL(params,4);
2882 DEBUG(3,("call_trans2findnotifyfirst - info_level %d\n", info_level));
2884 switch (info_level) {
2889 return ERROR_DOS(ERRDOS,ERRunknownlevel);
2892 /* Realloc the parameter and data sizes */
2893 params = Realloc(*pparams,6);
2895 return ERROR_DOS(ERRDOS,ERRnomem);
2898 SSVAL(params,0,fnf_handle);
2899 SSVAL(params,2,0); /* No changes */
2900 SSVAL(params,4,0); /* No EA errors */
2907 send_trans2_replies(outbuf, bufsize, params, 6, *ppdata, 0);
2912 /****************************************************************************
2913 Reply to a TRANS2_FINDNOTIFYNEXT (continue monitoring a directory for
2914 changes). Currently this does nothing.
2915 ****************************************************************************/
2917 static int call_trans2findnotifynext(connection_struct *conn,
2918 char *inbuf, char *outbuf, int length, int bufsize,
2919 char **pparams, int total_params, char **ppdata, int total_data)
2921 char *params = *pparams;
2923 DEBUG(3,("call_trans2findnotifynext\n"));
2925 /* Realloc the parameter and data sizes */
2926 params = Realloc(*pparams,4);
2928 return ERROR_DOS(ERRDOS,ERRnomem);
2931 SSVAL(params,0,0); /* No changes */
2932 SSVAL(params,2,0); /* No EA errors */
2934 send_trans2_replies(outbuf, bufsize, params, 4, *ppdata, 0);
2939 /****************************************************************************
2940 Reply to a TRANS2_GET_DFS_REFERRAL - Shirish Kalele <kalele@veritas.com>.
2941 ****************************************************************************/
2943 static int call_trans2getdfsreferral(connection_struct *conn, char* inbuf,
2944 char* outbuf, int length, int bufsize,
2945 char **pparams, int total_params, char **ppdata, int total_data)
2947 char *params = *pparams;
2950 int max_referral_level;
2952 DEBUG(10,("call_trans2getdfsreferral\n"));
2954 if (total_params < 2)
2955 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
2957 max_referral_level = SVAL(params,0);
2959 if(!lp_host_msdfs())
2960 return ERROR_DOS(ERRDOS,ERRbadfunc);
2962 srvstr_pull(inbuf, pathname, ¶ms[2], sizeof(pathname), -1, STR_TERMINATE);
2964 if((reply_size = setup_dfs_referral(pathname,max_referral_level,ppdata)) < 0)
2965 return ERROR_DOS(ERRDOS,ERRbadfile);
2967 SSVAL(outbuf,smb_flg2,SVAL(outbuf,smb_flg2) | FLAGS2_DFS_PATHNAMES);
2968 send_trans2_replies(outbuf,bufsize,0,0,*ppdata,reply_size);
2973 #define LMCAT_SPL 0x53
2974 #define LMFUNC_GETJOBID 0x60
2976 /****************************************************************************
2977 Reply to a TRANS2_IOCTL - used for OS/2 printing.
2978 ****************************************************************************/
2980 static int call_trans2ioctl(connection_struct *conn, char* inbuf,
2981 char* outbuf, int length, int bufsize,
2982 char **pparams, int total_params, char **ppdata, int total_data)
2984 char *pdata = *ppdata;
2985 files_struct *fsp = file_fsp(inbuf,smb_vwv15);
2987 if ((SVAL(inbuf,(smb_setup+4)) == LMCAT_SPL) &&
2988 (SVAL(inbuf,(smb_setup+6)) == LMFUNC_GETJOBID)) {
2991 pdata = Realloc(*ppdata, 32);
2993 return ERROR_DOS(ERRDOS,ERRnomem);
2996 /* NOTE - THIS IS ASCII ONLY AT THE MOMENT - NOT SURE IF OS/2
2997 CAN ACCEPT THIS IN UNICODE. JRA. */
2999 rap_jobid = pjobid_to_rap(SNUM(fsp->conn), fsp->print_jobid); /* Job number */
3000 SSVAL(pdata,0,rap_jobid); /* Job number */
3001 srvstr_push( outbuf, pdata + 2, global_myname, 15, STR_ASCII|STR_TERMINATE); /* Our NetBIOS name */
3002 srvstr_push( outbuf, pdata+18, lp_servicename(SNUM(conn)), 13, STR_ASCII|STR_TERMINATE); /* Service name */
3003 send_trans2_replies(outbuf,bufsize,*pparams,0,*ppdata,32);
3006 DEBUG(2,("Unknown TRANS2_IOCTL\n"));
3007 return ERROR_DOS(ERRSRV,ERRerror);
3011 /****************************************************************************
3012 Reply to a SMBfindclose (stop trans2 directory search).
3013 ****************************************************************************/
3015 int reply_findclose(connection_struct *conn,
3016 char *inbuf,char *outbuf,int length,int bufsize)
3019 int dptr_num=SVALS(inbuf,smb_vwv0);
3020 START_PROFILE(SMBfindclose);
3022 DEBUG(3,("reply_findclose, dptr_num = %d\n", dptr_num));
3024 dptr_close(&dptr_num);
3026 outsize = set_message(outbuf,0,0,True);
3028 DEBUG(3,("SMBfindclose dptr_num = %d\n", dptr_num));
3030 END_PROFILE(SMBfindclose);
3034 /****************************************************************************
3035 Reply to a SMBfindnclose (stop FINDNOTIFYFIRST directory search).
3036 ****************************************************************************/
3038 int reply_findnclose(connection_struct *conn,
3039 char *inbuf,char *outbuf,int length,int bufsize)
3043 START_PROFILE(SMBfindnclose);
3045 dptr_num = SVAL(inbuf,smb_vwv0);
3047 DEBUG(3,("reply_findnclose, dptr_num = %d\n", dptr_num));
3049 /* We never give out valid handles for a
3050 findnotifyfirst - so any dptr_num is ok here.
3053 outsize = set_message(outbuf,0,0,True);
3055 DEBUG(3,("SMB_findnclose dptr_num = %d\n", dptr_num));
3057 END_PROFILE(SMBfindnclose);
3061 /****************************************************************************
3062 Reply to a SMBtranss2 - just ignore it!
3063 ****************************************************************************/
3065 int reply_transs2(connection_struct *conn,
3066 char *inbuf,char *outbuf,int length,int bufsize)
3068 START_PROFILE(SMBtranss2);
3069 DEBUG(4,("Ignoring transs2 of length %d\n",length));
3070 END_PROFILE(SMBtranss2);
3074 /****************************************************************************
3075 Reply to a SMBtrans2.
3076 ****************************************************************************/
3078 int reply_trans2(connection_struct *conn,
3079 char *inbuf,char *outbuf,int length,int bufsize)
3082 unsigned int total_params = SVAL(inbuf, smb_tpscnt);
3083 unsigned int total_data =SVAL(inbuf, smb_tdscnt);
3085 unsigned int max_param_reply = SVAL(inbuf, smb_mprcnt);
3086 unsigned int max_data_reply = SVAL(inbuf, smb_mdrcnt);
3087 unsigned int max_setup_fields = SVAL(inbuf, smb_msrcnt);
3088 BOOL close_tid = BITSETW(inbuf+smb_flags,0);
3089 BOOL no_final_response = BITSETW(inbuf+smb_flags,1);
3090 int32 timeout = IVALS(inbuf,smb_timeout);
3092 unsigned int suwcnt = SVAL(inbuf, smb_suwcnt);
3093 unsigned int tran_call = SVAL(inbuf, smb_setup0);
3094 char *params = NULL, *data = NULL;
3095 int num_params, num_params_sofar, num_data, num_data_sofar;
3096 START_PROFILE(SMBtrans2);
3098 if(global_oplock_break && (tran_call == TRANSACT2_OPEN)) {
3099 /* Queue this open message as we are the process of an
3102 DEBUG(2,("reply_trans2: queueing message trans2open due to being "));
3103 DEBUGADD(2,( "in oplock break state.\n"));
3105 push_oplock_pending_smb_message(inbuf, length);
3106 END_PROFILE(SMBtrans2);
3110 if (IS_IPC(conn) && (tran_call != TRANSACT2_OPEN)
3111 && (tran_call != TRANSACT2_GET_DFS_REFERRAL)) {
3112 END_PROFILE(SMBtrans2);
3113 return ERROR_DOS(ERRSRV,ERRaccess);
3116 outsize = set_message(outbuf,0,0,True);
3118 /* All trans2 messages we handle have smb_sucnt == 1 - ensure this
3119 is so as a sanity check */
3122 * Need to have rc=0 for ioctl to get job id for OS/2.
3123 * Network printing will fail if function is not successful.
3124 * Similar function in reply.c will be used if protocol
3125 * is LANMAN1.0 instead of LM1.2X002.
3126 * Until DosPrintSetJobInfo with PRJINFO3 is supported,
3127 * outbuf doesn't have to be set(only job id is used).
3129 if ( (suwcnt == 4) && (tran_call == TRANSACT2_IOCTL) &&
3130 (SVAL(inbuf,(smb_setup+4)) == LMCAT_SPL) &&
3131 (SVAL(inbuf,(smb_setup+6)) == LMFUNC_GETJOBID)) {
3132 DEBUG(2,("Got Trans2 DevIOctl jobid\n"));
3134 DEBUG(2,("Invalid smb_sucnt in trans2 call(%d)\n",suwcnt));
3135 DEBUG(2,("Transaction is %d\n",tran_call));
3136 END_PROFILE(SMBtrans2);
3137 return ERROR_DOS(ERRSRV,ERRerror);
3141 /* Allocate the space for the maximum needed parameters and data */
3142 if (total_params > 0)
3143 params = (char *)malloc(total_params);
3145 data = (char *)malloc(total_data);
3147 if ((total_params && !params) || (total_data && !data)) {
3148 DEBUG(2,("Out of memory in reply_trans2\n"));
3151 END_PROFILE(SMBtrans2);
3152 return ERROR_DOS(ERRDOS,ERRnomem);
3155 /* Copy the param and data bytes sent with this request into
3156 the params buffer */
3157 num_params = num_params_sofar = SVAL(inbuf,smb_pscnt);
3158 num_data = num_data_sofar = SVAL(inbuf, smb_dscnt);
3160 if (num_params > total_params || num_data > total_data)
3161 exit_server("invalid params in reply_trans2");
3164 memcpy( params, smb_base(inbuf) + SVAL(inbuf, smb_psoff), num_params);
3166 memcpy( data, smb_base(inbuf) + SVAL(inbuf, smb_dsoff), num_data);
3168 if(num_data_sofar < total_data || num_params_sofar < total_params) {
3169 /* We need to send an interim response then receive the rest
3170 of the parameter/data bytes */
3171 outsize = set_message(outbuf,0,0,True);
3172 if (!send_smb(smbd_server_fd(),outbuf))
3173 exit_server("reply_trans2: send_smb failed.");
3175 while (num_data_sofar < total_data ||
3176 num_params_sofar < total_params) {
3179 ret = receive_next_smb(inbuf,bufsize,SMB_SECONDARY_WAIT);
3182 (CVAL(inbuf, smb_com) != SMBtranss2)) || !ret) {
3183 outsize = set_message(outbuf,0,0,True);
3185 DEBUG(0,("reply_trans2: Invalid secondary trans2 packet\n"));
3187 DEBUG(0,("reply_trans2: %s in getting secondary trans2 response.\n",
3188 (smb_read_error == READ_ERROR) ? "error" : "timeout" ));
3191 END_PROFILE(SMBtrans2);
3192 return ERROR_DOS(ERRSRV,ERRerror);
3195 /* Revise total_params and total_data in case
3196 they have changed downwards */
3197 total_params = SVAL(inbuf, smb_tpscnt);
3198 total_data = SVAL(inbuf, smb_tdscnt);
3199 num_params_sofar += (num_params = SVAL(inbuf,smb_spscnt));
3200 num_data_sofar += ( num_data = SVAL(inbuf, smb_sdscnt));
3201 if (num_params_sofar > total_params || num_data_sofar > total_data)
3202 exit_server("data overflow in trans2");
3204 memcpy( ¶ms[ SVAL(inbuf, smb_spsdisp)],
3205 smb_base(inbuf) + SVAL(inbuf, smb_spsoff), num_params);
3206 memcpy( &data[SVAL(inbuf, smb_sdsdisp)],
3207 smb_base(inbuf)+ SVAL(inbuf, smb_sdsoff), num_data);
3211 if (Protocol >= PROTOCOL_NT1) {
3212 SSVAL(outbuf,smb_flg2,SVAL(outbuf,smb_flg2) | 0x40); /* IS_LONG_NAME */
3215 /* Now we must call the relevant TRANS2 function */
3217 case TRANSACT2_OPEN:
3218 START_PROFILE_NESTED(Trans2_open);
3219 outsize = call_trans2open(conn, inbuf, outbuf, bufsize,
3220 ¶ms, total_params, &data, total_data);
3221 END_PROFILE_NESTED(Trans2_open);
3224 case TRANSACT2_FINDFIRST:
3225 START_PROFILE_NESTED(Trans2_findfirst);
3226 outsize = call_trans2findfirst(conn, inbuf, outbuf, bufsize,
3227 ¶ms, total_params, &data, total_data);
3228 END_PROFILE_NESTED(Trans2_findfirst);
3231 case TRANSACT2_FINDNEXT:
3232 START_PROFILE_NESTED(Trans2_findnext);
3233 outsize = call_trans2findnext(conn, inbuf, outbuf, length, bufsize,
3234 ¶ms, total_params, &data, total_data);
3235 END_PROFILE_NESTED(Trans2_findnext);
3238 case TRANSACT2_QFSINFO:
3239 START_PROFILE_NESTED(Trans2_qfsinfo);
3240 outsize = call_trans2qfsinfo(conn, inbuf, outbuf, length, bufsize,
3241 ¶ms, total_params, &data, total_data);
3242 END_PROFILE_NESTED(Trans2_qfsinfo);
3245 case TRANSACT2_SETFSINFO:
3246 START_PROFILE_NESTED(Trans2_setfsinfo);
3247 outsize = call_trans2setfsinfo(conn, inbuf, outbuf, length, bufsize,
3248 ¶ms, total_params, &data, total_data);
3249 END_PROFILE_NESTED(Trans2_setfsinfo);
3252 case TRANSACT2_QPATHINFO:
3253 case TRANSACT2_QFILEINFO:
3254 START_PROFILE_NESTED(Trans2_qpathinfo);
3255 outsize = call_trans2qfilepathinfo(conn, inbuf, outbuf, length, bufsize,
3256 ¶ms, total_params, &data, total_data);
3257 END_PROFILE_NESTED(Trans2_qpathinfo);
3259 case TRANSACT2_SETPATHINFO:
3260 case TRANSACT2_SETFILEINFO:
3261 START_PROFILE_NESTED(Trans2_setpathinfo);
3262 outsize = call_trans2setfilepathinfo(conn, inbuf, outbuf, length, bufsize,
3263 ¶ms, total_params, &data, total_data);
3264 END_PROFILE_NESTED(Trans2_setpathinfo);
3267 case TRANSACT2_FINDNOTIFYFIRST:
3268 START_PROFILE_NESTED(Trans2_findnotifyfirst);
3269 outsize = call_trans2findnotifyfirst(conn, inbuf, outbuf, length, bufsize,
3270 ¶ms, total_params, &data, total_data);
3271 END_PROFILE_NESTED(Trans2_findnotifyfirst);
3274 case TRANSACT2_FINDNOTIFYNEXT:
3275 START_PROFILE_NESTED(Trans2_findnotifynext);
3276 outsize = call_trans2findnotifynext(conn, inbuf, outbuf, length, bufsize,
3277 ¶ms, total_params, &data, total_data);
3278 END_PROFILE_NESTED(Trans2_findnotifynext);
3280 case TRANSACT2_MKDIR:
3281 START_PROFILE_NESTED(Trans2_mkdir);
3282 outsize = call_trans2mkdir(conn, inbuf, outbuf, length, bufsize,
3283 ¶ms, total_params, &data, total_data);
3284 END_PROFILE_NESTED(Trans2_mkdir);
3287 case TRANSACT2_GET_DFS_REFERRAL:
3288 START_PROFILE_NESTED(Trans2_get_dfs_referral);
3289 outsize = call_trans2getdfsreferral(conn,inbuf,outbuf,length, bufsize,
3290 ¶ms, total_params, &data, total_data);
3291 END_PROFILE_NESTED(Trans2_get_dfs_referral);
3293 case TRANSACT2_IOCTL:
3294 START_PROFILE_NESTED(Trans2_ioctl);
3295 outsize = call_trans2ioctl(conn,inbuf,outbuf,length, bufsize,
3296 ¶ms, total_params, &data, total_data);
3297 END_PROFILE_NESTED(Trans2_ioctl);
3300 /* Error in request */
3301 DEBUG(2,("Unknown request %d in trans2 call\n", tran_call));
3304 END_PROFILE(SMBtrans2);
3305 return ERROR_DOS(ERRSRV,ERRerror);
3308 /* As we do not know how many data packets will need to be
3309 returned here the various call_trans2xxxx calls
3310 must send their own. Thus a call_trans2xxx routine only
3311 returns a value other than -1 when it wants to send
3317 END_PROFILE(SMBtrans2);
3318 return outsize; /* If a correct response was needed the
3319 call_trans2xxx calls have already sent
3320 it. If outsize != -1 then it is returning */