2 Unix SMB/CIFS implementation.
3 SMB transaction2 handling
4 Copyright (C) Jeremy Allison 1994-2003
5 Copyright (C) Stefan (metze) Metzmacher 2003
7 Extensively modified by Andrew Tridgell, 1995
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
27 extern BOOL case_sensitive;
28 extern int smb_read_error;
29 extern fstring local_machine;
30 extern int global_oplock_break;
31 extern uint32 global_client_caps;
32 extern struct current_user current_user;
34 #define get_file_size(sbuf) ((sbuf).st_size)
36 /* given a stat buffer return the allocated size on disk, taking into
37 account sparse files */
38 SMB_BIG_UINT get_allocation_size(files_struct *fsp, SMB_STRUCT_STAT *sbuf)
41 #if defined(HAVE_STAT_ST_BLOCKS) && defined(STAT_ST_BLOCKSIZE)
42 ret = (SMB_BIG_UINT)STAT_ST_BLOCKSIZE * (SMB_BIG_UINT)sbuf->st_blocks;
44 ret = (SMB_BIG_UINT)get_file_size(*sbuf);
46 if (!ret && fsp && fsp->initial_allocation_size)
47 ret = fsp->initial_allocation_size;
48 ret = SMB_ROUNDUP(ret,SMB_ROUNDUP_ALLOCATION_SIZE);
52 /****************************************************************************
53 Send the required number of replies back.
54 We assume all fields other than the data fields are
55 set correctly for the type of call.
56 HACK ! Always assumes smb_setup field is zero.
57 ****************************************************************************/
59 static int send_trans2_replies(char *outbuf,
66 /* As we are using a protocol > LANMAN1 then the max_send
67 variable must have been set in the sessetupX call.
68 This takes precedence over the max_xmit field in the
69 global struct. These different max_xmit variables should
70 be merged as this is now too confusing */
73 int data_to_send = datasize;
74 int params_to_send = paramsize;
78 int params_sent_thistime, data_sent_thistime, total_sent_thistime;
79 int alignment_offset = 1; /* JRA. This used to be 3. Set to 1 to make netmon parse ok. */
80 int data_alignment_offset = 0;
82 /* Initially set the wcnt area to be 10 - this is true for all trans2 replies */
84 set_message(outbuf,10,0,True);
86 /* If there genuinely are no parameters or data to send just send the empty packet */
88 if(params_to_send == 0 && data_to_send == 0) {
89 if (!send_smb(smbd_server_fd(),outbuf))
90 exit_server("send_trans2_replies: send_smb failed.");
94 /* When sending params and data ensure that both are nicely aligned */
95 /* Only do this alignment when there is also data to send - else
96 can cause NT redirector problems. */
98 if (((params_to_send % 4) != 0) && (data_to_send != 0))
99 data_alignment_offset = 4 - (params_to_send % 4);
101 /* Space is bufsize minus Netbios over TCP header minus SMB header */
102 /* The alignment_offset is to align the param bytes on an even byte
103 boundary. NT 4.0 Beta needs this to work correctly. */
105 useable_space = bufsize - ((smb_buf(outbuf)+ alignment_offset+data_alignment_offset) - outbuf);
107 /* useable_space can never be more than max_send minus the alignment offset. */
109 useable_space = MIN(useable_space, max_send - (alignment_offset+data_alignment_offset));
111 while (params_to_send || data_to_send) {
112 /* Calculate whether we will totally or partially fill this packet */
114 total_sent_thistime = params_to_send + data_to_send + alignment_offset + data_alignment_offset;
116 /* We can never send more than useable_space */
118 * Note that 'useable_space' does not include the alignment offsets,
119 * but we must include the alignment offsets in the calculation of
120 * the length of the data we send over the wire, as the alignment offsets
121 * are sent here. Fix from Marc_Jacobsen@hp.com.
124 total_sent_thistime = MIN(total_sent_thistime, useable_space+ alignment_offset + data_alignment_offset);
126 set_message(outbuf, 10, total_sent_thistime, True);
128 /* Set total params and data to be sent */
129 SSVAL(outbuf,smb_tprcnt,paramsize);
130 SSVAL(outbuf,smb_tdrcnt,datasize);
132 /* Calculate how many parameters and data we can fit into
133 * this packet. Parameters get precedence
136 params_sent_thistime = MIN(params_to_send,useable_space);
137 data_sent_thistime = useable_space - params_sent_thistime;
138 data_sent_thistime = MIN(data_sent_thistime,data_to_send);
140 SSVAL(outbuf,smb_prcnt, params_sent_thistime);
142 /* smb_proff is the offset from the start of the SMB header to the
143 parameter bytes, however the first 4 bytes of outbuf are
144 the Netbios over TCP header. Thus use smb_base() to subtract
145 them from the calculation */
147 SSVAL(outbuf,smb_proff,((smb_buf(outbuf)+alignment_offset) - smb_base(outbuf)));
149 if(params_sent_thistime == 0)
150 SSVAL(outbuf,smb_prdisp,0);
152 /* Absolute displacement of param bytes sent in this packet */
153 SSVAL(outbuf,smb_prdisp,pp - params);
155 SSVAL(outbuf,smb_drcnt, data_sent_thistime);
156 if(data_sent_thistime == 0) {
157 SSVAL(outbuf,smb_droff,0);
158 SSVAL(outbuf,smb_drdisp, 0);
160 /* The offset of the data bytes is the offset of the
161 parameter bytes plus the number of parameters being sent this time */
162 SSVAL(outbuf,smb_droff,((smb_buf(outbuf)+alignment_offset) -
163 smb_base(outbuf)) + params_sent_thistime + data_alignment_offset);
164 SSVAL(outbuf,smb_drdisp, pd - pdata);
167 /* Copy the param bytes into the packet */
169 if(params_sent_thistime)
170 memcpy((smb_buf(outbuf)+alignment_offset),pp,params_sent_thistime);
172 /* Copy in the data bytes */
173 if(data_sent_thistime)
174 memcpy(smb_buf(outbuf)+alignment_offset+params_sent_thistime+
175 data_alignment_offset,pd,data_sent_thistime);
177 DEBUG(9,("t2_rep: params_sent_thistime = %d, data_sent_thistime = %d, useable_space = %d\n",
178 params_sent_thistime, data_sent_thistime, useable_space));
179 DEBUG(9,("t2_rep: params_to_send = %d, data_to_send = %d, paramsize = %d, datasize = %d\n",
180 params_to_send, data_to_send, paramsize, datasize));
182 /* Send the packet */
183 if (!send_smb(smbd_server_fd(),outbuf))
184 exit_server("send_trans2_replies: send_smb failed.");
186 pp += params_sent_thistime;
187 pd += data_sent_thistime;
189 params_to_send -= params_sent_thistime;
190 data_to_send -= data_sent_thistime;
193 if(params_to_send < 0 || data_to_send < 0) {
194 DEBUG(0,("send_trans2_replies failed sanity check pts = %d, dts = %d\n!!!",
195 params_to_send, data_to_send));
203 /****************************************************************************
204 Reply to a TRANSACT2_OPEN.
205 ****************************************************************************/
207 static int call_trans2open(connection_struct *conn, char *inbuf, char *outbuf, int bufsize,
208 char **pparams, int total_params, char **ppdata, int total_data)
210 char *params = *pparams;
215 BOOL return_additional_info;
225 int fmode=0,mtime=0,rmode;
227 SMB_STRUCT_STAT sbuf;
229 BOOL bad_path = False;
234 * Ensure we have enough parameters to perform the operation.
237 if (total_params < 29)
238 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
240 open_mode = SVAL(params, 2);
241 open_attr = SVAL(params,6);
242 oplock_request = (((SVAL(params,0)|(1<<1))>>1) | ((SVAL(params,0)|(1<<2))>>1));
244 return_additional_info = BITSETW(params,0);
245 open_sattr = SVAL(params, 4);
246 open_time = make_unix_date3(params+8);
248 open_ofun = SVAL(params,12);
249 open_size = IVAL(params,14);
253 return(ERROR_DOS(ERRSRV,ERRaccess));
255 srvstr_get_path(inbuf, fname, pname, sizeof(fname), -1, STR_TERMINATE, &status);
256 if (!NT_STATUS_IS_OK(status)) {
257 return ERROR_NT(status);
260 DEBUG(3,("trans2open %s mode=%d attr=%d ofun=%d size=%d\n",
261 fname,open_mode, open_attr, open_ofun, open_size));
263 /* XXXX we need to handle passed times, sattr and flags */
265 unix_convert(fname,conn,0,&bad_path,&sbuf);
267 if (!check_name(fname,conn)) {
268 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRnoaccess);
271 unixmode = unix_mode(conn,open_attr | aARCH, fname);
273 fsp = open_file_shared(conn,fname,&sbuf,open_mode,open_ofun,unixmode,
274 oplock_request, &rmode,&smb_action);
277 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRnoaccess);
280 size = get_file_size(sbuf);
281 fmode = dos_mode(conn,fname,&sbuf);
282 mtime = sbuf.st_mtime;
285 close_file(fsp,False);
286 return(ERROR_DOS(ERRDOS,ERRnoaccess));
289 /* Realloc the size of parameters and data we will return */
290 params = Realloc(*pparams, 28);
292 return(ERROR_DOS(ERRDOS,ERRnomem));
295 memset((char *)params,'\0',28);
296 SSVAL(params,0,fsp->fnum);
297 SSVAL(params,2,fmode);
298 put_dos_date2(params,4, mtime);
299 SIVAL(params,8, (uint32)size);
300 SSVAL(params,12,rmode);
302 if (oplock_request && lp_fake_oplocks(SNUM(conn)))
303 smb_action |= EXTENDED_OPLOCK_GRANTED;
305 SSVAL(params,18,smb_action);
308 * WARNING - this may need to be changed if SMB_INO_T <> 4 bytes.
310 SIVAL(params,20,inode);
312 /* Send the required number of replies */
313 send_trans2_replies(outbuf, bufsize, params, 28, *ppdata, 0);
318 /*********************************************************
319 Routine to check if a given string matches exactly.
320 as a special case a mask of "." does NOT match. That
321 is required for correct wildcard semantics
322 Case can be significant or not.
323 **********************************************************/
325 static BOOL exact_match(char *str,char *mask, BOOL case_sig)
327 if (mask[0] == '.' && mask[1] == 0)
330 return strcmp(str,mask)==0;
331 if (StrCaseCmp(str,mask) != 0) {
334 if (ms_has_wild(str)) {
340 /****************************************************************************
341 Return the filetype for UNIX extensions.
342 ****************************************************************************/
344 static uint32 unix_filetype(mode_t mode)
347 return UNIX_TYPE_FILE;
348 else if(S_ISDIR(mode))
349 return UNIX_TYPE_DIR;
351 else if(S_ISLNK(mode))
352 return UNIX_TYPE_SYMLINK;
355 else if(S_ISCHR(mode))
356 return UNIX_TYPE_CHARDEV;
359 else if(S_ISBLK(mode))
360 return UNIX_TYPE_BLKDEV;
363 else if(S_ISFIFO(mode))
364 return UNIX_TYPE_FIFO;
367 else if(S_ISSOCK(mode))
368 return UNIX_TYPE_SOCKET;
371 DEBUG(0,("unix_filetype: unknown filetype %u", (unsigned)mode));
372 return UNIX_TYPE_UNKNOWN;
375 /****************************************************************************
376 Return the major devicenumber for UNIX extensions.
377 ****************************************************************************/
379 static uint32 unix_dev_major(SMB_DEV_T dev)
381 #if defined(HAVE_DEVICE_MAJOR_FN)
382 return (uint32)major(dev);
384 return (uint32)(dev >> 8);
388 /****************************************************************************
389 Return the minor devicenumber for UNIX extensions.
390 ****************************************************************************/
392 static uint32 unix_dev_minor(SMB_DEV_T dev)
394 #if defined(HAVE_DEVICE_MINOR_FN)
395 return (uint32)minor(dev);
397 return (uint32)(dev & 0xff);
401 /****************************************************************************
402 Map wire perms onto standard UNIX permissions. Obey share restrictions.
403 ****************************************************************************/
405 static mode_t unix_perms_from_wire( connection_struct *conn, SMB_STRUCT_STAT *pst, uint32 perms)
409 if (perms == SMB_MODE_NO_CHANGE)
412 ret |= ((perms & UNIX_X_OTH ) ? S_IXOTH : 0);
413 ret |= ((perms & UNIX_W_OTH ) ? S_IWOTH : 0);
414 ret |= ((perms & UNIX_R_OTH ) ? S_IROTH : 0);
415 ret |= ((perms & UNIX_X_GRP ) ? S_IXGRP : 0);
416 ret |= ((perms & UNIX_W_GRP ) ? S_IWGRP : 0);
417 ret |= ((perms & UNIX_R_GRP ) ? S_IRGRP : 0);
418 ret |= ((perms & UNIX_X_USR ) ? S_IXUSR : 0);
419 ret |= ((perms & UNIX_W_USR ) ? S_IWUSR : 0);
420 ret |= ((perms & UNIX_R_USR ) ? S_IRUSR : 0);
422 ret |= ((perms & UNIX_STICKY ) ? S_ISVTX : 0);
425 ret |= ((perms & UNIX_SET_GID ) ? S_ISGID : 0);
428 ret |= ((perms & UNIX_SET_UID ) ? S_ISUID : 0);
431 if (VALID_STAT(*pst) && S_ISDIR(pst->st_mode)) {
432 ret &= lp_dir_mask(SNUM(conn));
433 /* Add in force bits */
434 ret |= lp_force_dir_mode(SNUM(conn));
436 /* Apply mode mask */
437 ret &= lp_create_mask(SNUM(conn));
438 /* Add in force bits */
439 ret |= lp_force_create_mode(SNUM(conn));
445 /****************************************************************************
446 Checks for SMB_TIME_NO_CHANGE and if not found calls interpret_long_date.
447 ****************************************************************************/
449 time_t interpret_long_unix_date(char *p)
451 DEBUG(1,("interpret_long_unix_date\n"));
452 if(IVAL(p,0) == SMB_TIME_NO_CHANGE_LO &&
453 IVAL(p,4) == SMB_TIME_NO_CHANGE_HI) {
456 return interpret_long_date(p);
460 /****************************************************************************
461 Get a level dependent lanman2 dir entry.
462 ****************************************************************************/
464 static BOOL get_lanman2_dir_entry(connection_struct *conn,
465 void *inbuf, void *outbuf,
466 char *path_mask,int dirtype,int info_level,
467 int requires_resume_key,
468 BOOL dont_descend,char **ppdata,
469 char *base_data, int space_remaining,
470 BOOL *out_of_space, BOOL *got_exact_match,
475 SMB_STRUCT_STAT sbuf;
479 char *p, *q, *pdata = *ppdata;
483 SMB_OFF_T file_size = 0;
484 SMB_BIG_UINT allocation_size = 0;
486 time_t mdate=0, adate=0, cdate=0;
489 int nt_extmode; /* Used for NT connections instead of mode */
490 BOOL needslash = ( conn->dirpath[strlen(conn->dirpath) -1] != '/');
493 *out_of_space = False;
494 *got_exact_match = False;
499 p = strrchr_m(path_mask,'/');
506 pstrcpy(mask, path_mask);
511 /* Needed if we run out of space */
512 prev_dirpos = TellDir(conn->dirptr);
513 dname = ReadDirName(conn->dirptr);
516 * Due to bugs in NT client redirectors we are not using
517 * resume keys any more - set them to zero.
518 * Check out the related comments in findfirst/findnext.
524 DEBUG(8,("get_lanman2_dir_entry:readdir on dirptr 0x%lx now at offset %d\n",
525 (long)conn->dirptr,TellDir(conn->dirptr)));
530 pstrcpy(fname,dname);
532 if(!(got_match = *got_exact_match = exact_match(fname, mask, case_sensitive)))
533 got_match = mask_match(fname, mask, case_sensitive);
535 if(!got_match && !mangle_is_8_3(fname, False)) {
538 * It turns out that NT matches wildcards against
539 * both long *and* short names. This may explain some
540 * of the wildcard wierdness from old DOS clients
541 * that some people have been seeing.... JRA.
545 pstrcpy( newname, fname);
546 mangle_map( newname, True, False, SNUM(conn));
547 if(!(got_match = *got_exact_match = exact_match(newname, mask, case_sensitive)))
548 got_match = mask_match(newname, mask, case_sensitive);
552 BOOL isdots = (strequal(fname,"..") || strequal(fname,"."));
553 if (dont_descend && !isdots)
556 pstrcpy(pathreal,conn->dirpath);
558 pstrcat(pathreal,"/");
559 pstrcat(pathreal,dname);
561 if (INFO_LEVEL_IS_UNIX(info_level)) {
562 if (SMB_VFS_LSTAT(conn,pathreal,&sbuf) != 0) {
563 DEBUG(5,("get_lanman2_dir_entry:Couldn't lstat [%s] (%s)\n",
564 pathreal,strerror(errno)));
567 } else if (SMB_VFS_STAT(conn,pathreal,&sbuf) != 0) {
569 /* Needed to show the msdfs symlinks as
572 if(lp_host_msdfs() &&
573 lp_msdfs_root(SNUM(conn)) &&
574 is_msdfs_link(conn, pathreal, NULL, NULL,
577 DEBUG(5,("get_lanman2_dir_entry: Masquerading msdfs link %s as a directory\n", pathreal));
578 sbuf.st_mode = (sbuf.st_mode & 0xFFF) | S_IFDIR;
582 DEBUG(5,("get_lanman2_dir_entry:Couldn't stat [%s] (%s)\n",
583 pathreal,strerror(errno)));
588 mode = dos_mode(conn,pathreal,&sbuf);
590 if (!dir_check_ftype(conn,mode,&sbuf,dirtype)) {
591 DEBUG(5,("[%s] attribs didn't match %x\n",fname,dirtype));
595 file_size = get_file_size(sbuf);
596 allocation_size = get_allocation_size(NULL,&sbuf);
597 mdate = sbuf.st_mtime;
598 adate = sbuf.st_atime;
599 cdate = get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(conn)));
601 if (lp_dos_filetime_resolution(SNUM(conn))) {
610 DEBUG(5,("get_lanman2_dir_entry found %s fname=%s\n",pathreal,fname));
616 mangle_map(fname,False,True,SNUM(conn));
621 nt_extmode = mode ? mode : FILE_ATTRIBUTE_NORMAL;
623 switch (info_level) {
624 case SMB_INFO_STANDARD:
625 if(requires_resume_key) {
629 put_dos_date2(p,l1_fdateCreation,cdate);
630 put_dos_date2(p,l1_fdateLastAccess,adate);
631 put_dos_date2(p,l1_fdateLastWrite,mdate);
632 SIVAL(p,l1_cbFile,(uint32)file_size);
633 SIVAL(p,l1_cbFileAlloc,(uint32)allocation_size);
634 SSVAL(p,l1_attrFile,mode);
637 p += align_string(outbuf, p, 0);
638 len = srvstr_push(outbuf, p, fname, -1, STR_TERMINATE);
639 if (SVAL(outbuf, smb_flg2) & FLAGS2_UNICODE_STRINGS)
640 SCVAL(nameptr, -1, len-2);
642 SCVAL(nameptr, -1, len-1);
646 case SMB_INFO_QUERY_EA_SIZE:
647 if(requires_resume_key) {
651 put_dos_date2(p,l2_fdateCreation,cdate);
652 put_dos_date2(p,l2_fdateLastAccess,adate);
653 put_dos_date2(p,l2_fdateLastWrite,mdate);
654 SIVAL(p,l2_cbFile,(uint32)file_size);
655 SIVAL(p,l2_cbFileAlloc,(uint32)allocation_size);
656 SSVAL(p,l2_attrFile,mode);
657 SIVAL(p,l2_cbList,0); /* No extended attributes */
660 len = srvstr_push(outbuf, p, fname, -1, STR_TERMINATE | STR_NOALIGN);
661 if (SVAL(outbuf, smb_flg2) & FLAGS2_UNICODE_STRINGS)
662 SCVAL(nameptr, -1, len-2);
664 SCVAL(nameptr, -1, len-1);
668 case SMB_FIND_FILE_BOTH_DIRECTORY_INFO:
669 was_8_3 = mangle_is_8_3(fname, True);
671 SIVAL(p,0,reskey); p += 4;
672 put_long_date(p,cdate); p += 8;
673 put_long_date(p,adate); p += 8;
674 put_long_date(p,mdate); p += 8;
675 put_long_date(p,mdate); p += 8;
676 SOFF_T(p,0,file_size);
677 SOFF_T(p,8,allocation_size);
679 SIVAL(p,0,nt_extmode); p += 4;
681 SIVAL(p,0,0); p += 4;
682 /* Clear the short name buffer. This is
683 * IMPORTANT as not doing so will trigger
684 * a Win2k client bug. JRA.
687 if (!was_8_3 && lp_manglednames(SNUM(conn))) {
688 pstring mangled_name;
689 pstrcpy(mangled_name, fname);
690 mangle_map(mangled_name,True,True,SNUM(conn));
691 mangled_name[12] = 0;
692 len = srvstr_push(outbuf, p+2, mangled_name, 24, STR_UPPER|STR_UNICODE);
699 len = srvstr_push(outbuf, p, fname, -1, STR_TERMINATE_ASCII);
702 len = PTR_DIFF(p, pdata);
703 len = (len + 3) & ~3;
708 case SMB_FIND_FILE_DIRECTORY_INFO:
710 SIVAL(p,0,reskey); p += 4;
711 put_long_date(p,cdate); p += 8;
712 put_long_date(p,adate); p += 8;
713 put_long_date(p,mdate); p += 8;
714 put_long_date(p,mdate); p += 8;
715 SOFF_T(p,0,file_size);
716 SOFF_T(p,8,allocation_size);
718 SIVAL(p,0,nt_extmode); p += 4;
720 len = srvstr_push(outbuf, p, fname, -1, STR_TERMINATE_ASCII);
723 len = PTR_DIFF(p, pdata);
724 len = (len + 3) & ~3;
729 case SMB_FIND_FILE_FULL_DIRECTORY_INFO:
731 SIVAL(p,0,reskey); p += 4;
732 put_long_date(p,cdate); p += 8;
733 put_long_date(p,adate); p += 8;
734 put_long_date(p,mdate); p += 8;
735 put_long_date(p,mdate); p += 8;
736 SOFF_T(p,0,file_size);
737 SOFF_T(p,8,allocation_size);
739 SIVAL(p,0,nt_extmode);
742 SIVAL(p,4,0); /* ea size */
743 len = srvstr_push(outbuf, p+8, fname, -1, STR_TERMINATE_ASCII);
747 len = PTR_DIFF(p, pdata);
748 len = (len + 3) & ~3;
753 case SMB_FIND_FILE_NAMES_INFO:
755 SIVAL(p,0,reskey); p += 4;
757 /* this must *not* be null terminated or w2k gets in a loop trying to set an
758 acl on a dir (tridge) */
759 len = srvstr_push(outbuf, p, fname, -1, STR_TERMINATE_ASCII);
762 len = PTR_DIFF(p, pdata);
763 len = (len + 3) & ~3;
768 case SMB_FIND_FILE_LEVEL_261:
770 SIVAL(p,0,reskey); p += 4;
771 put_long_date(p,cdate); p += 8;
772 put_long_date(p,adate); p += 8;
773 put_long_date(p,mdate); p += 8;
774 put_long_date(p,mdate); p += 8;
775 SOFF_T(p,0,file_size);
776 SOFF_T(p,8,allocation_size);
778 SIVAL(p,0,nt_extmode);
780 len = srvstr_push(outbuf, p + 20, fname, -1, STR_TERMINATE_ASCII);
782 memset(p+4,'\0',16); /* EA size. Unknown 0 1 2 */
783 p += 20 + len; /* Strlen, EA size. Unknown 0 1 2, string itself */
784 len = PTR_DIFF(p, pdata);
785 len = (len + 3) & ~3;
790 case SMB_FIND_FILE_LEVEL_262:
791 was_8_3 = mangle_is_8_3(fname, True);
793 SIVAL(p,0,reskey); p += 4;
794 put_long_date(p,cdate); p += 8;
795 put_long_date(p,adate); p += 8;
796 put_long_date(p,mdate); p += 8;
797 put_long_date(p,mdate); p += 8;
798 SOFF_T(p,0,file_size);
799 SOFF_T(p,8,allocation_size);
801 SIVAL(p,0,nt_extmode); p += 4;
803 SIVAL(p,0,0); p += 4;
804 /* Clear the short name buffer. This is
805 * IMPORTANT as not doing so will trigger
806 * a Win2k client bug. JRA.
809 if (!was_8_3 && lp_manglednames(SNUM(conn))) {
810 pstring mangled_name;
811 pstrcpy(mangled_name, fname);
812 mangle_map(mangled_name,True,True,SNUM(conn));
813 mangled_name[12] = 0;
814 len = srvstr_push(outbuf, p+2, mangled_name, 24, STR_UPPER|STR_UNICODE);
821 memset(p, '\0', 10); /* 2 4 byte unknowns plus a zero reserved. */
823 len = srvstr_push(outbuf, p, fname, -1, STR_TERMINATE_ASCII);
826 len = PTR_DIFF(p, pdata);
827 len = (len + 3) & ~3;
832 /* CIFS UNIX Extension. */
834 case SMB_FIND_FILE_UNIX:
836 SIVAL(p,0,reskey); p+= 4; /* Used for continuing search. */
838 /* Begin of SMB_QUERY_FILE_UNIX_BASIC */
839 SOFF_T(p,0,get_file_size(sbuf)); /* File size 64 Bit */
842 SOFF_T(p,0,get_allocation_size(NULL,&sbuf)); /* Number of bytes used on disk - 64 Bit */
845 put_long_date(p,sbuf.st_ctime); /* Creation Time 64 Bit */
846 put_long_date(p+8,sbuf.st_atime); /* Last access time 64 Bit */
847 put_long_date(p+16,sbuf.st_mtime); /* Last modification time 64 Bit */
850 SIVAL(p,0,sbuf.st_uid); /* user id for the owner */
854 SIVAL(p,0,sbuf.st_gid); /* group id of owner */
858 SIVAL(p,0,unix_filetype(sbuf.st_mode));
861 SIVAL(p,0,unix_dev_major(sbuf.st_rdev)); /* Major device number if type is device */
865 SIVAL(p,0,unix_dev_minor(sbuf.st_rdev)); /* Minor device number if type is device */
869 SINO_T(p,0,(SMB_INO_T)sbuf.st_ino); /* inode number */
872 SIVAL(p,0, unix_perms_to_wire(sbuf.st_mode)); /* Standard UNIX file permissions */
876 SIVAL(p,0,sbuf.st_nlink); /* number of hard links */
880 len = srvstr_push(outbuf, p, fname, -1, STR_TERMINATE);
883 len = PTR_DIFF(p, pdata);
884 len = (len + 3) & ~3;
885 SIVAL(pdata,0,len); /* Offset from this structure to the beginning of the next one */
887 /* End of SMB_QUERY_FILE_UNIX_BASIC */
896 if (PTR_DIFF(p,pdata) > space_remaining) {
897 /* Move the dirptr back to prev_dirpos */
898 SeekDir(conn->dirptr, prev_dirpos);
899 *out_of_space = True;
900 DEBUG(9,("get_lanman2_dir_entry: out of space\n"));
901 return False; /* Not finished - just out of space */
904 /* Setup the last_filename pointer, as an offset from base_data */
905 *last_name_off = PTR_DIFF(nameptr,base_data);
906 /* Advance the data pointer to the next slot */
912 /****************************************************************************
913 Reply to a TRANS2_FINDFIRST.
914 ****************************************************************************/
916 static int call_trans2findfirst(connection_struct *conn, char *inbuf, char *outbuf, int bufsize,
917 char **pparams, int total_params, char **ppdata, int total_data)
919 /* We must be careful here that we don't return more than the
920 allowed number of data bytes. If this means returning fewer than
921 maxentries then so be it. We assume that the redirector has
922 enough room for the fixed number of parameter bytes it has
924 uint32 max_data_bytes = SVAL(inbuf, smb_mdrcnt);
925 char *params = *pparams;
926 char *pdata = *ppdata;
927 int dirtype = SVAL(params,0);
928 int maxentries = SVAL(params,2);
929 BOOL close_after_first = BITSETW(params+4,0);
930 BOOL close_if_end = BITSETW(params+4,1);
931 BOOL requires_resume_key = BITSETW(params+4,2);
932 int info_level = SVAL(params,6);
940 BOOL finished = False;
941 BOOL dont_descend = False;
942 BOOL out_of_space = False;
944 BOOL bad_path = False;
945 SMB_STRUCT_STAT sbuf;
946 NTSTATUS ntstatus = NT_STATUS_OK;
948 if (total_params < 12)
949 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
951 *directory = *mask = 0;
953 DEBUG(3,("call_trans2findfirst: dirtype = %d, maxentries = %d, close_after_first=%d, \
954 close_if_end = %d requires_resume_key = %d level = %d, max_data_bytes = %d\n",
955 dirtype, maxentries, close_after_first, close_if_end, requires_resume_key,
956 info_level, max_data_bytes));
958 switch (info_level) {
959 case SMB_INFO_STANDARD:
960 case SMB_INFO_QUERY_EA_SIZE:
961 case SMB_FIND_FILE_DIRECTORY_INFO:
962 case SMB_FIND_FILE_FULL_DIRECTORY_INFO:
963 case SMB_FIND_FILE_NAMES_INFO:
964 case SMB_FIND_FILE_BOTH_DIRECTORY_INFO:
965 case SMB_FIND_FILE_LEVEL_261:
966 case SMB_FIND_FILE_LEVEL_262:
968 case SMB_FIND_FILE_UNIX:
969 if (!lp_unix_extensions())
970 return(ERROR_DOS(ERRDOS,ERRunknownlevel));
973 return(ERROR_DOS(ERRDOS,ERRunknownlevel));
976 srvstr_get_path(inbuf, directory, params+12, sizeof(directory), -1, STR_TERMINATE, &ntstatus);
977 if (!NT_STATUS_IS_OK(ntstatus)) {
978 return ERROR_NT(ntstatus);
981 RESOLVE_FINDFIRST_DFSPATH(directory, conn, inbuf, outbuf);
983 unix_convert(directory,conn,0,&bad_path,&sbuf);
984 if(!check_name(directory,conn)) {
985 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRbadpath);
988 p = strrchr_m(directory,'/');
990 /* Windows and OS/2 systems treat search on the root '\' as if it were '\*' */
991 if((directory[0] == '.') && (directory[1] == '\0'))
994 pstrcpy(mask,directory);
995 pstrcpy(directory,"./");
1001 DEBUG(5,("dir=%s, mask = %s\n",directory, mask));
1003 pdata = Realloc(*ppdata, max_data_bytes + 1024);
1005 return(ERROR_DOS(ERRDOS,ERRnomem));
1008 memset((char *)pdata,'\0',max_data_bytes + 1024);
1010 /* Realloc the params space */
1011 params = Realloc(*pparams, 10);
1013 return ERROR_DOS(ERRDOS,ERRnomem);
1016 dptr_num = dptr_create(conn,directory, False, True ,SVAL(inbuf,smb_pid));
1018 return(UNIXERROR(ERRDOS,ERRbadfile));
1020 /* Save the wildcard match and attribs we are using on this directory -
1021 needed as lanman2 assumes these are being saved between calls */
1023 if(!(wcard = strdup(mask))) {
1024 dptr_close(&dptr_num);
1025 return ERROR_DOS(ERRDOS,ERRnomem);
1028 dptr_set_wcard(dptr_num, wcard);
1029 dptr_set_attr(dptr_num, dirtype);
1031 DEBUG(4,("dptr_num is %d, wcard = %s, attr = %d\n",dptr_num, wcard, dirtype));
1033 /* We don't need to check for VOL here as this is returned by
1034 a different TRANS2 call. */
1036 DEBUG(8,("dirpath=<%s> dontdescend=<%s>\n", conn->dirpath,lp_dontdescend(SNUM(conn))));
1037 if (in_list(conn->dirpath,lp_dontdescend(SNUM(conn)),case_sensitive))
1038 dont_descend = True;
1041 space_remaining = max_data_bytes;
1042 out_of_space = False;
1044 for (i=0;(i<maxentries) && !finished && !out_of_space;i++) {
1045 BOOL got_exact_match = False;
1047 /* this is a heuristic to avoid seeking the dirptr except when
1048 absolutely necessary. It allows for a filename of about 40 chars */
1049 if (space_remaining < DIRLEN_GUESS && numentries > 0) {
1050 out_of_space = True;
1053 finished = !get_lanman2_dir_entry(conn,
1055 mask,dirtype,info_level,
1056 requires_resume_key,dont_descend,
1057 &p,pdata,space_remaining, &out_of_space, &got_exact_match,
1061 if (finished && out_of_space)
1064 if (!finished && !out_of_space)
1068 * As an optimisation if we know we aren't looking
1069 * for a wildcard name (ie. the name matches the wildcard exactly)
1070 * then we can finish on any (first) match.
1071 * This speeds up large directory searches. JRA.
1077 space_remaining = max_data_bytes - PTR_DIFF(p,pdata);
1080 /* Check if we can close the dirptr */
1081 if(close_after_first || (finished && close_if_end)) {
1082 DEBUG(5,("call_trans2findfirst - (2) closing dptr_num %d\n", dptr_num));
1083 dptr_close(&dptr_num);
1087 * If there are no matching entries we must return ERRDOS/ERRbadfile -
1088 * from observation of NT.
1091 if(numentries == 0) {
1092 dptr_close(&dptr_num);
1093 return ERROR_DOS(ERRDOS,ERRbadfile);
1096 /* At this point pdata points to numentries directory entries. */
1098 /* Set up the return parameter block */
1099 SSVAL(params,0,dptr_num);
1100 SSVAL(params,2,numentries);
1101 SSVAL(params,4,finished);
1102 SSVAL(params,6,0); /* Never an EA error */
1103 SSVAL(params,8,last_name_off);
1105 send_trans2_replies( outbuf, bufsize, params, 10, pdata, PTR_DIFF(p,pdata));
1107 if ((! *directory) && dptr_path(dptr_num))
1108 slprintf(directory,sizeof(directory)-1, "(%s)",dptr_path(dptr_num));
1110 DEBUG( 4, ( "%s mask=%s directory=%s dirtype=%d numentries=%d\n",
1111 smb_fn_name(CVAL(inbuf,smb_com)),
1112 mask, directory, dirtype, numentries ) );
1115 * Force a name mangle here to ensure that the
1116 * mask as an 8.3 name is top of the mangled cache.
1117 * The reasons for this are subtle. Don't remove
1118 * this code unless you know what you are doing
1119 * (see PR#13758). JRA.
1122 if(!mangle_is_8_3_wildcards( mask, False))
1123 mangle_map(mask, True, True, SNUM(conn));
1128 /****************************************************************************
1129 Reply to a TRANS2_FINDNEXT.
1130 ****************************************************************************/
1132 static int call_trans2findnext(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize,
1133 char **pparams, int total_params, char **ppdata, int total_data)
1135 /* We must be careful here that we don't return more than the
1136 allowed number of data bytes. If this means returning fewer than
1137 maxentries then so be it. We assume that the redirector has
1138 enough room for the fixed number of parameter bytes it has
1140 int max_data_bytes = SVAL(inbuf, smb_mdrcnt);
1141 char *params = *pparams;
1142 char *pdata = *ppdata;
1143 int dptr_num = SVAL(params,0);
1144 int maxentries = SVAL(params,2);
1145 uint16 info_level = SVAL(params,4);
1146 uint32 resume_key = IVAL(params,6);
1147 BOOL close_after_request = BITSETW(params+10,0);
1148 BOOL close_if_end = BITSETW(params+10,1);
1149 BOOL requires_resume_key = BITSETW(params+10,2);
1150 BOOL continue_bit = BITSETW(params+10,3);
1151 pstring resume_name;
1157 int i, last_name_off=0;
1158 BOOL finished = False;
1159 BOOL dont_descend = False;
1160 BOOL out_of_space = False;
1161 int space_remaining;
1162 NTSTATUS ntstatus = NT_STATUS_OK;
1164 if (total_params < 12)
1165 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
1167 *mask = *directory = *resume_name = 0;
1169 srvstr_get_path(inbuf, resume_name, params+12, sizeof(resume_name), -1, STR_TERMINATE, &ntstatus);
1170 if (!NT_STATUS_IS_OK(ntstatus)) {
1171 return ERROR_NT(ntstatus);
1174 DEBUG(3,("call_trans2findnext: dirhandle = %d, max_data_bytes = %d, maxentries = %d, \
1175 close_after_request=%d, close_if_end = %d requires_resume_key = %d \
1176 resume_key = %d resume name = %s continue=%d level = %d\n",
1177 dptr_num, max_data_bytes, maxentries, close_after_request, close_if_end,
1178 requires_resume_key, resume_key, resume_name, continue_bit, info_level));
1180 switch (info_level) {
1181 case SMB_INFO_STANDARD:
1182 case SMB_INFO_QUERY_EA_SIZE:
1183 case SMB_FIND_FILE_DIRECTORY_INFO:
1184 case SMB_FIND_FILE_FULL_DIRECTORY_INFO:
1185 case SMB_FIND_FILE_NAMES_INFO:
1186 case SMB_FIND_FILE_BOTH_DIRECTORY_INFO:
1188 case SMB_FIND_FILE_UNIX:
1189 if (!lp_unix_extensions())
1190 return(ERROR_DOS(ERRDOS,ERRunknownlevel));
1193 return ERROR_DOS(ERRDOS,ERRunknownlevel);
1196 pdata = Realloc( *ppdata, max_data_bytes + 1024);
1198 return ERROR_DOS(ERRDOS,ERRnomem);
1201 memset((char *)pdata,'\0',max_data_bytes + 1024);
1203 /* Realloc the params space */
1204 params = Realloc(*pparams, 6*SIZEOFWORD);
1205 if( params == NULL )
1206 return ERROR_DOS(ERRDOS,ERRnomem);
1210 /* Check that the dptr is valid */
1211 if(!(conn->dirptr = dptr_fetch_lanman2(dptr_num)))
1212 return ERROR_DOS(ERRDOS,ERRnofiles);
1214 string_set(&conn->dirpath,dptr_path(dptr_num));
1216 /* Get the wildcard mask from the dptr */
1217 if((p = dptr_wcard(dptr_num))== NULL) {
1218 DEBUG(2,("dptr_num %d has no wildcard\n", dptr_num));
1219 return ERROR_DOS(ERRDOS,ERRnofiles);
1223 pstrcpy(directory,conn->dirpath);
1225 /* Get the attr mask from the dptr */
1226 dirtype = dptr_attr(dptr_num);
1228 DEBUG(3,("dptr_num is %d, mask = %s, attr = %x, dirptr=(0x%lX,%d)\n",
1229 dptr_num, mask, dirtype,
1231 TellDir(conn->dirptr)));
1233 /* We don't need to check for VOL here as this is returned by
1234 a different TRANS2 call. */
1236 DEBUG(8,("dirpath=<%s> dontdescend=<%s>\n",conn->dirpath,lp_dontdescend(SNUM(conn))));
1237 if (in_list(conn->dirpath,lp_dontdescend(SNUM(conn)),case_sensitive))
1238 dont_descend = True;
1241 space_remaining = max_data_bytes;
1242 out_of_space = False;
1245 * Seek to the correct position. We no longer use the resume key but
1246 * depend on the last file name instead.
1249 if(requires_resume_key && *resume_name && !continue_bit) {
1252 * Fix for NT redirector problem triggered by resume key indexes
1253 * changing between directory scans. We now return a resume key of 0
1254 * and instead look for the filename to continue from (also given
1255 * to us by NT/95/smbfs/smbclient). If no other scans have been done between the
1256 * findfirst/findnext (as is usual) then the directory pointer
1257 * should already be at the correct place. Check this by scanning
1258 * backwards looking for an exact (ie. case sensitive) filename match.
1259 * If we get to the beginning of the directory and haven't found it then scan
1260 * forwards again looking for a match. JRA.
1263 int current_pos, start_pos;
1264 const char *dname = NULL;
1265 pstring dname_pstring;
1266 void *dirptr = conn->dirptr;
1267 start_pos = TellDir(dirptr);
1268 for(current_pos = start_pos; current_pos >= 0; current_pos--) {
1269 DEBUG(7,("call_trans2findnext: seeking to pos %d\n", current_pos));
1271 SeekDir(dirptr, current_pos);
1272 dname = ReadDirName(dirptr);
1275 * Remember, mangle_map is called by
1276 * get_lanman2_dir_entry(), so the resume name
1277 * could be mangled. Ensure we do the same
1281 /* make sure we get a copy that mangle_map can modify */
1283 pstrcpy(dname_pstring, dname);
1284 mangle_map( dname_pstring, False, True, SNUM(conn));
1286 if(strcsequal( resume_name, dname_pstring)) {
1287 SeekDir(dirptr, current_pos+1);
1288 DEBUG(7,("call_trans2findnext: got match at pos %d\n", current_pos+1 ));
1295 * Scan forward from start if not found going backwards.
1298 if(current_pos < 0) {
1299 DEBUG(7,("call_trans2findnext: notfound: seeking to pos %d\n", start_pos));
1300 SeekDir(dirptr, start_pos);
1301 for(current_pos = start_pos; (dname = ReadDirName(dirptr)) != NULL; SeekDir(dirptr,++current_pos)) {
1304 * Remember, mangle_map is called by
1305 * get_lanman2_dir_entry(), so the resume name
1306 * could be mangled. Ensure we do the same
1311 /* make sure we get a copy that mangle_map can modify */
1313 pstrcpy(dname_pstring, dname);
1314 mangle_map(dname_pstring, False, True, SNUM(conn));
1316 if(strcsequal( resume_name, dname_pstring)) {
1317 SeekDir(dirptr, current_pos+1);
1318 DEBUG(7,("call_trans2findnext: got match at pos %d\n", current_pos+1 ));
1323 } /* end if current_pos */
1324 } /* end if requires_resume_key && !continue_bit */
1326 for (i=0;(i<(int)maxentries) && !finished && !out_of_space ;i++) {
1327 BOOL got_exact_match = False;
1329 /* this is a heuristic to avoid seeking the dirptr except when
1330 absolutely necessary. It allows for a filename of about 40 chars */
1331 if (space_remaining < DIRLEN_GUESS && numentries > 0) {
1332 out_of_space = True;
1335 finished = !get_lanman2_dir_entry(conn,
1337 mask,dirtype,info_level,
1338 requires_resume_key,dont_descend,
1339 &p,pdata,space_remaining, &out_of_space, &got_exact_match,
1343 if (finished && out_of_space)
1346 if (!finished && !out_of_space)
1350 * As an optimisation if we know we aren't looking
1351 * for a wildcard name (ie. the name matches the wildcard exactly)
1352 * then we can finish on any (first) match.
1353 * This speeds up large directory searches. JRA.
1359 space_remaining = max_data_bytes - PTR_DIFF(p,pdata);
1362 /* Check if we can close the dirptr */
1363 if(close_after_request || (finished && close_if_end)) {
1364 DEBUG(5,("call_trans2findnext: closing dptr_num = %d\n", dptr_num));
1365 dptr_close(&dptr_num); /* This frees up the saved mask */
1368 /* Set up the return parameter block */
1369 SSVAL(params,0,numentries);
1370 SSVAL(params,2,finished);
1371 SSVAL(params,4,0); /* Never an EA error */
1372 SSVAL(params,6,last_name_off);
1374 send_trans2_replies( outbuf, bufsize, params, 8, pdata, PTR_DIFF(p,pdata));
1376 if ((! *directory) && dptr_path(dptr_num))
1377 slprintf(directory,sizeof(directory)-1, "(%s)",dptr_path(dptr_num));
1379 DEBUG( 3, ( "%s mask=%s directory=%s dirtype=%d numentries=%d\n",
1380 smb_fn_name(CVAL(inbuf,smb_com)),
1381 mask, directory, dirtype, numentries ) );
1386 /****************************************************************************
1387 Reply to a TRANS2_QFSINFO (query filesystem info).
1388 ****************************************************************************/
1390 static int call_trans2qfsinfo(connection_struct *conn, char *inbuf, char *outbuf,
1391 int length, int bufsize,
1392 char **pparams, int total_params, char **ppdata, int total_data)
1394 int max_data_bytes = SVAL(inbuf, smb_mdrcnt);
1395 char *pdata = *ppdata;
1396 char *params = *pparams;
1397 uint16 info_level = SVAL(params,0);
1400 char *vname = volume_label(SNUM(conn));
1401 int snum = SNUM(conn);
1402 char *fstype = lp_fstype(SNUM(conn));
1405 DEBUG(3,("call_trans2qfsinfo: level = %d\n", info_level));
1407 if(SMB_VFS_STAT(conn,".",&st)!=0) {
1408 DEBUG(2,("call_trans2qfsinfo: stat of . failed (%s)\n", strerror(errno)));
1409 return ERROR_DOS(ERRSRV,ERRinvdevice);
1412 pdata = Realloc(*ppdata, max_data_bytes + 1024);
1413 if ( pdata == NULL )
1414 return ERROR_DOS(ERRDOS,ERRnomem);
1417 memset((char *)pdata,'\0',max_data_bytes + 1024);
1419 switch (info_level) {
1420 case SMB_INFO_ALLOCATION:
1422 SMB_BIG_UINT dfree,dsize,bsize,block_size,sectors_per_unit,bytes_per_sector;
1424 SMB_VFS_DISK_FREE(conn,".",False,&bsize,&dfree,&dsize);
1425 block_size = lp_block_size(snum);
1426 if (bsize < block_size) {
1427 SMB_BIG_UINT factor = block_size/bsize;
1432 if (bsize > block_size) {
1433 SMB_BIG_UINT factor = bsize/block_size;
1438 bytes_per_sector = 512;
1439 sectors_per_unit = bsize/bytes_per_sector;
1441 DEBUG(5,("call_trans2qfsinfo : SMB_INFO_ALLOCATION id=%x, bsize=%u, cSectorUnit=%u, \
1442 cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)st.st_dev, (unsigned int)bsize, (unsigned int)sectors_per_unit,
1443 (unsigned int)bytes_per_sector, (unsigned int)dsize, (unsigned int)dfree));
1445 SIVAL(pdata,l1_idFileSystem,st.st_dev);
1446 SIVAL(pdata,l1_cSectorUnit,sectors_per_unit);
1447 SIVAL(pdata,l1_cUnit,dsize);
1448 SIVAL(pdata,l1_cUnitAvail,dfree);
1449 SSVAL(pdata,l1_cbSector,bytes_per_sector);
1453 case SMB_INFO_VOLUME:
1454 /* Return volume name */
1456 * Add volume serial number - hash of a combination of
1457 * the called hostname and the service name.
1459 SIVAL(pdata,0,str_checksum(lp_servicename(snum)) ^ (str_checksum(local_machine)<<16) );
1460 len = srvstr_push(outbuf, pdata+l2_vol_szVolLabel, vname, -1, STR_NOALIGN);
1461 SCVAL(pdata,l2_vol_cch,len);
1462 data_len = l2_vol_szVolLabel + len;
1463 DEBUG(5,("call_trans2qfsinfo : time = %x, namelen = %d, name = %s\n",
1464 (unsigned)st.st_ctime, len, vname));
1467 case SMB_QUERY_FS_ATTRIBUTE_INFO:
1468 case SMB_FS_ATTRIBUTE_INFORMATION:
1471 #if defined(HAVE_SYS_QUOTAS)
1472 quota_flag = FILE_VOLUME_QUOTAS;
1475 SIVAL(pdata,0,FILE_CASE_PRESERVED_NAMES|FILE_CASE_SENSITIVE_SEARCH|
1476 (lp_nt_acl_support(SNUM(conn)) ? FILE_PERSISTENT_ACLS : 0)|
1477 quota_flag); /* FS ATTRIBUTES */
1479 SIVAL(pdata,4,255); /* Max filename component length */
1480 /* NOTE! the fstype must *not* be null terminated or win98 won't recognise it
1481 and will think we can't do long filenames */
1482 len = srvstr_push(outbuf, pdata+12, fstype, -1, STR_UNICODE);
1484 data_len = 12 + len;
1487 case SMB_QUERY_FS_LABEL_INFO:
1488 case SMB_FS_LABEL_INFORMATION:
1489 len = srvstr_push(outbuf, pdata+4, vname, -1, 0);
1494 case SMB_QUERY_FS_VOLUME_INFO:
1495 case SMB_FS_VOLUME_INFORMATION:
1498 * Add volume serial number - hash of a combination of
1499 * the called hostname and the service name.
1501 SIVAL(pdata,8,str_checksum(lp_servicename(snum)) ^
1502 (str_checksum(local_machine)<<16));
1504 len = srvstr_push(outbuf, pdata+18, vname, -1, STR_UNICODE);
1505 SIVAL(pdata,12,len);
1507 DEBUG(5,("call_trans2qfsinfo : SMB_QUERY_FS_VOLUME_INFO namelen = %d, vol=%s serv=%s\n",
1508 (int)strlen(vname),vname, lp_servicename(snum)));
1511 case SMB_QUERY_FS_SIZE_INFO:
1512 case SMB_FS_SIZE_INFORMATION:
1514 SMB_BIG_UINT dfree,dsize,bsize,block_size,sectors_per_unit,bytes_per_sector;
1516 SMB_VFS_DISK_FREE(conn,".",False,&bsize,&dfree,&dsize);
1517 block_size = lp_block_size(snum);
1518 if (bsize < block_size) {
1519 SMB_BIG_UINT factor = block_size/bsize;
1524 if (bsize > block_size) {
1525 SMB_BIG_UINT factor = bsize/block_size;
1530 bytes_per_sector = 512;
1531 sectors_per_unit = bsize/bytes_per_sector;
1532 DEBUG(5,("call_trans2qfsinfo : SMB_QUERY_FS_SIZE_INFO bsize=%u, cSectorUnit=%u, \
1533 cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize, (unsigned int)sectors_per_unit,
1534 (unsigned int)bytes_per_sector, (unsigned int)dsize, (unsigned int)dfree));
1535 SBIG_UINT(pdata,0,dsize);
1536 SBIG_UINT(pdata,8,dfree);
1537 SIVAL(pdata,16,sectors_per_unit);
1538 SIVAL(pdata,20,bytes_per_sector);
1542 case SMB_FS_FULL_SIZE_INFORMATION:
1544 SMB_BIG_UINT dfree,dsize,bsize,block_size,sectors_per_unit,bytes_per_sector;
1546 SMB_VFS_DISK_FREE(conn,".",False,&bsize,&dfree,&dsize);
1547 block_size = lp_block_size(snum);
1548 if (bsize < block_size) {
1549 SMB_BIG_UINT factor = block_size/bsize;
1554 if (bsize > block_size) {
1555 SMB_BIG_UINT factor = bsize/block_size;
1560 bytes_per_sector = 512;
1561 sectors_per_unit = bsize/bytes_per_sector;
1562 DEBUG(5,("call_trans2qfsinfo : SMB_QUERY_FS_FULL_SIZE_INFO bsize=%u, cSectorUnit=%u, \
1563 cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize, (unsigned int)sectors_per_unit,
1564 (unsigned int)bytes_per_sector, (unsigned int)dsize, (unsigned int)dfree));
1565 SBIG_UINT(pdata,0,dsize); /* Total Allocation units. */
1566 SBIG_UINT(pdata,8,dfree); /* Caller available allocation units. */
1567 SBIG_UINT(pdata,16,dfree); /* Actual available allocation units. */
1568 SIVAL(pdata,24,sectors_per_unit); /* Sectors per allocation unit. */
1569 SIVAL(pdata,28,bytes_per_sector); /* Bytes per sector. */
1573 case SMB_QUERY_FS_DEVICE_INFO:
1574 case SMB_FS_DEVICE_INFORMATION:
1576 SIVAL(pdata,0,0); /* dev type */
1577 SIVAL(pdata,4,0); /* characteristics */
1580 #ifdef HAVE_SYS_QUOTAS
1581 case SMB_FS_QUOTA_INFORMATION:
1583 * what we have to send --metze:
1585 * Unknown1: 24 NULL bytes
1586 * Soft Quota Treshold: 8 bytes seems like SMB_BIG_UINT or so
1587 * Hard Quota Limit: 8 bytes seems like SMB_BIG_UINT or so
1588 * Quota Flags: 2 byte :
1589 * Unknown3: 6 NULL bytes
1593 * details for Quota Flags:
1595 * 0x0020 Log Limit: log if the user exceeds his Hard Quota
1596 * 0x0010 Log Warn: log if the user exceeds his Soft Quota
1597 * 0x0002 Deny Disk: deny disk access when the user exceeds his Hard Quota
1598 * 0x0001 Enable Quotas: enable quota for this fs
1602 /* we need to fake up a fsp here,
1603 * because its not send in this call
1606 SMB_NTQUOTA_STRUCT quotas;
1609 ZERO_STRUCT(quotas);
1616 if (conn->admin_user != True) {
1617 DEBUG(0,("set_user_quota: access_denied service [%s] user [%s]\n",
1618 lp_servicename(SNUM(conn)),conn->user));
1619 return ERROR_DOS(ERRDOS,ERRnoaccess);
1622 if (vfs_get_ntquota(&fsp, SMB_USER_FS_QUOTA_TYPE, NULL, "as)!=0) {
1623 DEBUG(0,("vfs_get_ntquota() failed for service [%s]\n",lp_servicename(SNUM(conn))));
1624 return ERROR_DOS(ERRSRV,ERRerror);
1629 DEBUG(10,("SMB_FS_QUOTA_INFORMATION: for service [%s]\n",lp_servicename(SNUM(conn))));
1631 /* Unknown1 24 NULL bytes*/
1632 SBIG_UINT(pdata,0,(SMB_BIG_UINT)0);
1633 SBIG_UINT(pdata,8,(SMB_BIG_UINT)0);
1634 SBIG_UINT(pdata,16,(SMB_BIG_UINT)0);
1636 /* Default Soft Quota 8 bytes */
1637 SBIG_UINT(pdata,24,quotas.softlim);
1639 /* Default Hard Quota 8 bytes */
1640 SBIG_UINT(pdata,32,quotas.hardlim);
1642 /* Quota flag 2 bytes */
1643 SSVAL(pdata,40,quotas.qflags);
1645 /* Unknown3 6 NULL bytes */
1651 #endif /* HAVE_SYS_QUOTAS */
1652 case SMB_FS_OBJECTID_INFORMATION:
1657 * Query the version and capabilities of the CIFS UNIX extensions
1661 case SMB_QUERY_CIFS_UNIX_INFO:
1662 if (!lp_unix_extensions())
1663 return ERROR_DOS(ERRDOS,ERRunknownlevel);
1665 SSVAL(pdata,0,CIFS_UNIX_MAJOR_VERSION);
1666 SSVAL(pdata,2,CIFS_UNIX_MINOR_VERSION);
1667 SBIG_UINT(pdata,4,((SMB_BIG_UINT)0)); /* No capabilities for now... */
1670 case SMB_MAC_QUERY_FS_INFO:
1672 * Thursby MAC extension... ONLY on NTFS filesystems
1673 * once we do streams then we don't need this
1675 if (strequal(lp_fstype(SNUM(conn)),"NTFS")) {
1677 SIVAL(pdata,84,0x100); /* Don't support mac... */
1682 return ERROR_DOS(ERRDOS,ERRunknownlevel);
1686 send_trans2_replies( outbuf, bufsize, params, 0, pdata, data_len);
1688 DEBUG( 4, ( "%s info_level = %d\n", smb_fn_name(CVAL(inbuf,smb_com)), info_level) );
1693 #ifdef HAVE_SYS_QUOTAS
1694 /****************************************************************************
1695 Reply to a TRANS2_SETFSINFO (set filesystem info).
1696 ****************************************************************************/
1698 static int call_trans2setfsinfo(connection_struct *conn,
1699 char *inbuf, char *outbuf, int length, int bufsize,
1700 char **pparams, int total_params, char **ppdata, int total_data)
1702 char *pdata = *ppdata;
1703 char *params = *pparams;
1704 files_struct *fsp = NULL;
1707 SMB_NTQUOTA_STRUCT quotas;
1709 ZERO_STRUCT(quotas);
1711 DEBUG(10,("call_trans2setfsinfo: SET_FS_QUOTA: for service [%s]\n",lp_servicename(SNUM(conn))));
1714 if ((conn->admin_user != True)||!CAN_WRITE(conn)) {
1715 DEBUG(0,("set_user_quota: access_denied service [%s] user [%s]\n",
1716 lp_servicename(SNUM(conn)),conn->user));
1717 return ERROR_DOS(ERRSRV,ERRaccess);
1721 if (total_params < 4) {
1722 DEBUG(0,("call_trans2setfsinfo: requires total_params(%d) >= 4 bytes!\n",
1724 return ERROR_DOS(ERRDOS,ERRinvalidparam);
1727 fsp = file_fsp(params,0);
1729 if (!CHECK_NTQUOTA_HANDLE_OK(fsp,conn)) {
1730 DEBUG(3,("TRANSACT_GET_USER_QUOTA: no valid QUOTA HANDLE\n"));
1731 return ERROR_NT(NT_STATUS_INVALID_HANDLE);
1734 info_level = SVAL(params,2);
1736 switch(info_level) {
1737 case SMB_FS_QUOTA_INFORMATION:
1738 /* note: normaly there're 48 bytes,
1739 * but we didn't use the last 6 bytes for now
1742 if (total_data < 42) {
1743 DEBUG(0,("call_trans2setfsinfo: SET_FS_QUOTA: requires total_data(%d) >= 42 bytes!\n",
1745 return ERROR_DOS(ERRDOS,ERRunknownlevel);
1748 /* unknown_1 24 NULL bytes in pdata*/
1750 /* the soft quotas 8 bytes (SMB_BIG_UINT)*/
1751 quotas.softlim = (SMB_BIG_UINT)IVAL(pdata,24);
1752 #ifdef LARGE_SMB_OFF_T
1753 quotas.softlim |= (((SMB_BIG_UINT)IVAL(pdata,28)) << 32);
1754 #else /* LARGE_SMB_OFF_T */
1755 if ((IVAL(pdata,28) != 0)&&
1756 ((quotas.softlim != 0xFFFFFFFF)||
1757 (IVAL(pdata,28)!=0xFFFFFFFF))) {
1758 /* more than 32 bits? */
1759 return ERROR_DOS(ERRDOS,ERRunknownlevel);
1761 #endif /* LARGE_SMB_OFF_T */
1763 /* the hard quotas 8 bytes (SMB_BIG_UINT)*/
1764 quotas.hardlim = (SMB_BIG_UINT)IVAL(pdata,32);
1765 #ifdef LARGE_SMB_OFF_T
1766 quotas.hardlim |= (((SMB_BIG_UINT)IVAL(pdata,36)) << 32);
1767 #else /* LARGE_SMB_OFF_T */
1768 if ((IVAL(pdata,36) != 0)&&
1769 ((quotas.hardlim != 0xFFFFFFFF)||
1770 (IVAL(pdata,36)!=0xFFFFFFFF))) {
1771 /* more than 32 bits? */
1772 return ERROR_DOS(ERRDOS,ERRunknownlevel);
1774 #endif /* LARGE_SMB_OFF_T */
1776 /* quota_flags 2 bytes **/
1777 quotas.qflags = SVAL(pdata,40);
1779 /* unknown_2 6 NULL bytes follow*/
1781 /* now set the quotas */
1782 if (vfs_set_ntquota(fsp, SMB_USER_FS_QUOTA_TYPE, NULL, "as)!=0) {
1783 DEBUG(0,("vfs_set_ntquota() failed for service [%s]\n",lp_servicename(SNUM(conn))));
1784 return ERROR_DOS(ERRSRV,ERRerror);
1789 DEBUG(3,("call_trans2setfsinfo: unknown level (0x%X) not implemented yet.\n",
1791 return ERROR_DOS(ERRDOS,ERRunknownlevel);
1796 * sending this reply works fine,
1797 * but I'm not sure it's the same
1798 * like windows do...
1801 outsize = set_message(outbuf,10,0,True);
1805 #endif /* HAVE_SYS_QUOTAS */
1807 /****************************************************************************
1808 * Utility function to set bad path error.
1809 ****************************************************************************/
1811 int set_bad_path_error(int err, BOOL bad_path, char *outbuf, int def_class, uint32 def_code)
1813 DEBUG(10,("set_bad_path_error: err = %d bad_path = %d\n",
1814 err, (int)bad_path ));
1818 return ERROR_NT(NT_STATUS_OBJECT_PATH_NOT_FOUND);
1820 return ERROR_NT(NT_STATUS_OBJECT_NAME_NOT_FOUND);
1823 return UNIXERROR(def_class,def_code);
1826 /****************************************************************************
1827 Reply to a TRANS2_QFILEPATHINFO or TRANSACT2_QFILEINFO (query file info by
1828 file name or file id).
1829 ****************************************************************************/
1831 static int call_trans2qfilepathinfo(connection_struct *conn,
1832 char *inbuf, char *outbuf, int length,
1834 char **pparams, int total_params, char **ppdata, int total_data)
1836 int max_data_bytes = SVAL(inbuf, smb_mdrcnt);
1837 char *params = *pparams;
1838 char *pdata = *ppdata;
1839 uint16 tran_call = SVAL(inbuf, smb_setup0);
1842 SMB_OFF_T file_size=0;
1843 SMB_BIG_UINT allocation_size=0;
1844 unsigned int data_size;
1845 unsigned int param_size = 2;
1846 SMB_STRUCT_STAT sbuf;
1847 pstring fname, dos_fname;
1852 BOOL bad_path = False;
1853 BOOL delete_pending = False;
1856 files_struct *fsp = NULL;
1857 uint32 desired_access = 0x12019F; /* Default - GENERIC_EXECUTE mapping from Windows */
1860 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
1862 if (tran_call == TRANSACT2_QFILEINFO) {
1863 if (total_params < 4)
1864 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
1866 fsp = file_fsp(params,0);
1867 info_level = SVAL(params,2);
1869 DEBUG(3,("call_trans2qfilepathinfo: TRANSACT2_QFILEINFO: level = %d\n", info_level));
1871 if(fsp && (fsp->fake_file_handle)) {
1873 * This is actually for the QUOTA_FAKE_FILE --metze
1876 pstrcpy(fname, fsp->fsp_name);
1877 unix_convert(fname,conn,0,&bad_path,&sbuf);
1878 if (!check_name(fname,conn)) {
1879 DEBUG(3,("call_trans2qfilepathinfo: fileinfo of %s failed for fake_file(%s)\n",fname,strerror(errno)));
1880 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRbadpath);
1883 } else if(fsp && (fsp->is_directory || fsp->fd == -1)) {
1885 * This is actually a QFILEINFO on a directory
1886 * handle (returned from an NT SMB). NT5.0 seems
1887 * to do this call. JRA.
1889 pstrcpy(fname, fsp->fsp_name);
1890 unix_convert(fname,conn,0,&bad_path,&sbuf);
1891 if (!check_name(fname,conn)) {
1892 DEBUG(3,("call_trans2qfilepathinfo: fileinfo of %s failed (%s)\n",fname,strerror(errno)));
1893 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRbadpath);
1896 if (INFO_LEVEL_IS_UNIX(info_level)) {
1897 /* Always do lstat for UNIX calls. */
1898 if (SMB_VFS_LSTAT(conn,fname,&sbuf)) {
1899 DEBUG(3,("call_trans2qfilepathinfo: SMB_VFS_LSTAT of %s failed (%s)\n",fname,strerror(errno)));
1900 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRbadpath);
1902 } else if (!VALID_STAT(sbuf) && SMB_VFS_STAT(conn,fname,&sbuf)) {
1903 DEBUG(3,("call_trans2qfilepathinfo: SMB_VFS_STAT of %s failed (%s)\n",fname,strerror(errno)));
1904 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRbadpath);
1907 delete_pending = fsp->directory_delete_on_close;
1910 * Original code - this is an open file.
1912 CHECK_FSP(fsp,conn);
1914 pstrcpy(fname, fsp->fsp_name);
1915 if (SMB_VFS_FSTAT(fsp,fsp->fd,&sbuf) != 0) {
1916 DEBUG(3,("fstat of fnum %d failed (%s)\n", fsp->fnum, strerror(errno)));
1917 return(UNIXERROR(ERRDOS,ERRbadfid));
1919 pos = fsp->position_information;
1920 delete_pending = fsp->delete_on_close;
1921 desired_access = fsp->desired_access;
1924 NTSTATUS status = NT_STATUS_OK;
1927 if (total_params < 6)
1928 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
1930 info_level = SVAL(params,0);
1932 DEBUG(3,("call_trans2qfilepathinfo: TRANSACT2_QPATHINFO: level = %d\n", info_level));
1934 srvstr_get_path(inbuf, fname, ¶ms[6], sizeof(fname), -1, STR_TERMINATE, &status);
1935 if (!NT_STATUS_IS_OK(status)) {
1936 return ERROR_NT(status);
1939 RESOLVE_DFSPATH(fname, conn, inbuf, outbuf);
1941 unix_convert(fname,conn,0,&bad_path,&sbuf);
1942 if (!check_name(fname,conn)) {
1943 DEBUG(3,("call_trans2qfilepathinfo: fileinfo of %s failed (%s)\n",fname,strerror(errno)));
1944 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRbadpath);
1947 if (INFO_LEVEL_IS_UNIX(info_level)) {
1948 /* Always do lstat for UNIX calls. */
1949 if (SMB_VFS_LSTAT(conn,fname,&sbuf)) {
1950 DEBUG(3,("call_trans2qfilepathinfo: SMB_VFS_LSTAT of %s failed (%s)\n",fname,strerror(errno)));
1951 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRbadpath);
1953 } else if (!VALID_STAT(sbuf) && SMB_VFS_STAT(conn,fname,&sbuf) && (info_level != SMB_INFO_IS_NAME_VALID)) {
1954 DEBUG(3,("call_trans2qfilepathinfo: SMB_VFS_STAT of %s failed (%s)\n",fname,strerror(errno)));
1955 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRbadpath);
1959 if (INFO_LEVEL_IS_UNIX(info_level) && !lp_unix_extensions())
1960 return ERROR_DOS(ERRDOS,ERRunknownlevel);
1962 DEBUG(3,("call_trans2qfilepathinfo %s (fnum = %d) level=%d call=%d total_data=%d\n",
1963 fname,fsp ? fsp->fnum : -1, info_level,tran_call,total_data));
1965 p = strrchr_m(fname,'/');
1971 mode = dos_mode(conn,fname,&sbuf);
1973 mode = FILE_ATTRIBUTE_NORMAL;
1975 fullpathname = fname;
1976 file_size = get_file_size(sbuf);
1977 allocation_size = get_allocation_size(fsp,&sbuf);
1981 params = Realloc(*pparams,2);
1983 return ERROR_DOS(ERRDOS,ERRnomem);
1985 memset((char *)params,'\0',2);
1986 data_size = max_data_bytes + 1024;
1987 pdata = Realloc(*ppdata, data_size);
1988 if ( pdata == NULL )
1989 return ERROR_DOS(ERRDOS,ERRnomem);
1992 if (total_data > 0 && IVAL(pdata,0) == total_data) {
1993 /* uggh, EAs for OS2 */
1994 DEBUG(4,("Rejecting EA request with total_data=%d\n",total_data));
1995 return ERROR_DOS(ERRDOS,ERReasnotsupported);
1998 memset((char *)pdata,'\0',data_size);
2000 c_time = get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(conn)));
2002 if (lp_dos_filetime_resolution(SNUM(conn))) {
2004 sbuf.st_atime &= ~1;
2005 sbuf.st_mtime &= ~1;
2006 sbuf.st_mtime &= ~1;
2009 /* NT expects the name to be in an exact form of the *full*
2010 filename. See the trans2 torture test */
2011 if (strequal(base_name,".")) {
2012 pstrcpy(dos_fname, "\\");
2014 pstr_sprintf(dos_fname, "\\%s", fname);
2015 string_replace(dos_fname, '/', '\\');
2018 switch (info_level) {
2019 case SMB_INFO_STANDARD:
2020 case SMB_INFO_QUERY_EA_SIZE:
2021 data_size = (info_level==1?22:26);
2022 put_dos_date2(pdata,l1_fdateCreation,c_time);
2023 put_dos_date2(pdata,l1_fdateLastAccess,sbuf.st_atime);
2024 put_dos_date2(pdata,l1_fdateLastWrite,sbuf.st_mtime); /* write time */
2025 SIVAL(pdata,l1_cbFile,(uint32)file_size);
2026 SIVAL(pdata,l1_cbFileAlloc,(uint32)allocation_size);
2027 SSVAL(pdata,l1_attrFile,mode);
2028 SIVAL(pdata,l1_attrFile+2,0); /* this is what win2003 does */
2031 case SMB_INFO_IS_NAME_VALID:
2032 if (tran_call == TRANSACT2_QFILEINFO) {
2033 /* os/2 needs this ? really ?*/
2034 return ERROR_DOS(ERRDOS,ERRbadfunc);
2040 case SMB_INFO_QUERY_EAS_FROM_LIST:
2042 put_dos_date2(pdata,0,c_time);
2043 put_dos_date2(pdata,4,sbuf.st_atime);
2044 put_dos_date2(pdata,8,sbuf.st_mtime);
2045 SIVAL(pdata,12,(uint32)file_size);
2046 SIVAL(pdata,16,(uint32)allocation_size);
2047 SIVAL(pdata,20,mode);
2050 case SMB_INFO_QUERY_ALL_EAS:
2052 SIVAL(pdata,0,0); /* ea size */
2055 case SMB_FILE_BASIC_INFORMATION:
2056 case SMB_QUERY_FILE_BASIC_INFO:
2058 if (info_level == SMB_QUERY_FILE_BASIC_INFO)
2059 data_size = 36; /* w95 returns 40 bytes not 36 - why ?. */
2064 put_long_date(pdata,c_time);
2065 put_long_date(pdata+8,sbuf.st_atime);
2066 put_long_date(pdata+16,sbuf.st_mtime); /* write time */
2067 put_long_date(pdata+24,sbuf.st_mtime); /* change time */
2068 SIVAL(pdata,32,mode);
2070 DEBUG(5,("SMB_QFBI - "));
2072 time_t create_time = c_time;
2073 DEBUG(5,("create: %s ", ctime(&create_time)));
2075 DEBUG(5,("access: %s ", ctime(&sbuf.st_atime)));
2076 DEBUG(5,("write: %s ", ctime(&sbuf.st_mtime)));
2077 DEBUG(5,("change: %s ", ctime(&sbuf.st_mtime)));
2078 DEBUG(5,("mode: %x\n", mode));
2082 case SMB_FILE_STANDARD_INFORMATION:
2083 case SMB_QUERY_FILE_STANDARD_INFO:
2086 SOFF_T(pdata,0,allocation_size);
2087 SOFF_T(pdata,8,file_size);
2088 if (delete_pending & sbuf.st_nlink)
2089 SIVAL(pdata,16,sbuf.st_nlink - 1);
2091 SIVAL(pdata,16,sbuf.st_nlink);
2093 SCVAL(pdata,21,(mode&aDIR)?1:0);
2096 case SMB_FILE_EA_INFORMATION:
2097 case SMB_QUERY_FILE_EA_INFO:
2101 /* Get the 8.3 name - used if NT SMB was negotiated. */
2102 case SMB_QUERY_FILE_ALT_NAME_INFO:
2103 case SMB_FILE_ALTERNATE_NAME_INFORMATION:
2107 pstrcpy(short_name,base_name);
2108 /* Mangle if not already 8.3 */
2109 if(!mangle_is_8_3(short_name, True)) {
2110 mangle_map(short_name,True,True,SNUM(conn));
2112 len = srvstr_push(outbuf, pdata+4, short_name, -1, STR_UNICODE);
2113 data_size = 4 + len;
2118 case SMB_QUERY_FILE_NAME_INFO:
2120 this must be *exactly* right for ACLs on mapped drives to work
2122 len = srvstr_push(outbuf, pdata+4, dos_fname, -1, STR_UNICODE);
2123 data_size = 4 + len;
2127 case SMB_FILE_ALLOCATION_INFORMATION:
2128 case SMB_QUERY_FILE_ALLOCATION_INFO:
2130 SOFF_T(pdata,0,allocation_size);
2133 case SMB_FILE_END_OF_FILE_INFORMATION:
2134 case SMB_QUERY_FILE_END_OF_FILEINFO:
2136 SOFF_T(pdata,0,file_size);
2139 case SMB_QUERY_FILE_ALL_INFO:
2140 case SMB_FILE_ALL_INFORMATION:
2141 put_long_date(pdata,c_time);
2142 put_long_date(pdata+8,sbuf.st_atime);
2143 put_long_date(pdata+16,sbuf.st_mtime); /* write time */
2144 put_long_date(pdata+24,sbuf.st_mtime); /* change time */
2145 SIVAL(pdata,32,mode);
2147 SOFF_T(pdata,0,allocation_size);
2148 SOFF_T(pdata,8,file_size);
2149 if (delete_pending && sbuf.st_nlink)
2150 SIVAL(pdata,16,sbuf.st_nlink - 1);
2152 SIVAL(pdata,16,sbuf.st_nlink);
2153 SCVAL(pdata,20,delete_pending);
2154 SCVAL(pdata,21,(mode&aDIR)?1:0);
2156 pdata += 4; /* EA info */
2157 len = srvstr_push(outbuf, pdata+4, dos_fname, -1, STR_UNICODE);
2160 data_size = PTR_DIFF(pdata,(*ppdata));
2163 case SMB_FILE_INTERNAL_INFORMATION:
2164 /* This should be an index number - looks like
2167 I think this causes us to fail the IFSKIT
2168 BasicFileInformationTest. -tpot */
2170 SIVAL(pdata,0,sbuf.st_dev);
2171 SIVAL(pdata,4,sbuf.st_ino);
2175 case SMB_FILE_ACCESS_INFORMATION:
2176 SIVAL(pdata,0,desired_access);
2180 case SMB_FILE_NAME_INFORMATION:
2181 /* Pathname with leading '\'. */
2184 byte_len = dos_PutUniCode(pdata+4,dos_fname,max_data_bytes,False);
2185 SIVAL(pdata,0,byte_len);
2186 data_size = 4 + byte_len;
2190 case SMB_FILE_DISPOSITION_INFORMATION:
2192 SCVAL(pdata,0,delete_pending);
2195 case SMB_FILE_POSITION_INFORMATION:
2197 SOFF_T(pdata,0,pos);
2200 case SMB_FILE_MODE_INFORMATION:
2201 SIVAL(pdata,0,mode);
2205 case SMB_FILE_ALIGNMENT_INFORMATION:
2206 SIVAL(pdata,0,0); /* No alignment needed. */
2212 * NT4 server just returns "invalid query" to this - if we try to answer
2213 * it then NTws gets a BSOD! (tridge).
2214 * W2K seems to want this. JRA.
2216 case SMB_QUERY_FILE_STREAM_INFO:
2218 case SMB_FILE_STREAM_INFORMATION:
2222 size_t byte_len = dos_PutUniCode(pdata+24,"::$DATA", 0xE, False);
2223 SIVAL(pdata,0,0); /* ??? */
2224 SIVAL(pdata,4,byte_len); /* Byte length of unicode string ::$DATA */
2225 SOFF_T(pdata,8,file_size);
2226 SIVAL(pdata,16,allocation_size);
2227 SIVAL(pdata,20,0); /* ??? */
2228 data_size = 24 + byte_len;
2232 case SMB_QUERY_COMPRESSION_INFO:
2233 case SMB_FILE_COMPRESSION_INFORMATION:
2234 SOFF_T(pdata,0,file_size);
2235 SIVAL(pdata,8,0); /* ??? */
2236 SIVAL(pdata,12,0); /* ??? */
2240 case SMB_FILE_NETWORK_OPEN_INFORMATION:
2241 put_long_date(pdata,c_time);
2242 put_long_date(pdata+8,sbuf.st_atime);
2243 put_long_date(pdata+16,sbuf.st_mtime); /* write time */
2244 put_long_date(pdata+24,sbuf.st_mtime); /* change time */
2245 SIVAL(pdata,32,allocation_size);
2246 SOFF_T(pdata,40,file_size);
2247 SIVAL(pdata,48,mode);
2248 SIVAL(pdata,52,0); /* ??? */
2252 case SMB_FILE_ATTRIBUTE_TAG_INFORMATION:
2253 SIVAL(pdata,0,mode);
2259 * CIFS UNIX Extensions.
2262 case SMB_QUERY_FILE_UNIX_BASIC:
2264 DEBUG(4,("call_trans2qfilepathinfo: st_mode=%o\n",(int)sbuf.st_mode));
2266 SOFF_T(pdata,0,get_file_size(sbuf)); /* File size 64 Bit */
2269 SOFF_T(pdata,0,get_allocation_size(fsp,&sbuf)); /* Number of bytes used on disk - 64 Bit */
2272 put_long_date(pdata,sbuf.st_ctime); /* Creation Time 64 Bit */
2273 put_long_date(pdata+8,sbuf.st_atime); /* Last access time 64 Bit */
2274 put_long_date(pdata+16,sbuf.st_mtime); /* Last modification time 64 Bit */
2277 SIVAL(pdata,0,sbuf.st_uid); /* user id for the owner */
2281 SIVAL(pdata,0,sbuf.st_gid); /* group id of owner */
2285 SIVAL(pdata,0,unix_filetype(sbuf.st_mode));
2288 SIVAL(pdata,0,unix_dev_major(sbuf.st_rdev)); /* Major device number if type is device */
2292 SIVAL(pdata,0,unix_dev_minor(sbuf.st_rdev)); /* Minor device number if type is device */
2296 SINO_T(pdata,0,(SMB_INO_T)sbuf.st_ino); /* inode number */
2299 SIVAL(pdata,0, unix_perms_to_wire(sbuf.st_mode)); /* Standard UNIX file permissions */
2303 SIVAL(pdata,0,sbuf.st_nlink); /* number of hard links */
2306 data_size = PTR_DIFF(pdata,(*ppdata));
2310 DEBUG(4,("call_trans2qfilepathinfo: SMB_QUERY_FILE_UNIX_BASIC"));
2312 for (i=0; i<100; i++)
2313 DEBUG(4,("%d=%x, ",i, (*ppdata)[i]));
2319 case SMB_QUERY_FILE_UNIX_LINK:
2324 if(!S_ISLNK(sbuf.st_mode))
2325 return(UNIXERROR(ERRSRV,ERRbadlink));
2327 return(UNIXERROR(ERRDOS,ERRbadlink));
2329 len = SMB_VFS_READLINK(conn,fullpathname, buffer, sizeof(pstring)-1); /* read link */
2331 return(UNIXERROR(ERRDOS,ERRnoaccess));
2333 len = srvstr_push(outbuf, pdata, buffer, -1, STR_TERMINATE);
2335 data_size = PTR_DIFF(pdata,(*ppdata));
2341 return ERROR_DOS(ERRDOS,ERRunknownlevel);
2344 send_trans2_replies(outbuf, bufsize, params, param_size, *ppdata, data_size);
2349 /****************************************************************************
2350 Deal with the internal needs of setting the delete on close flag. Note that
2351 as the tdb locking is recursive, it is safe to call this from within
2352 open_file_shared. JRA.
2353 ****************************************************************************/
2355 NTSTATUS set_delete_on_close_internal(files_struct *fsp, BOOL delete_on_close)
2358 * Only allow delete on close for writable shares.
2361 if (delete_on_close && !CAN_WRITE(fsp->conn)) {
2362 DEBUG(10,("set_delete_on_close_internal: file %s delete on close flag set but write access denied on share.\n",
2364 return NT_STATUS_ACCESS_DENIED;
2367 * Only allow delete on close for files/directories opened with delete intent.
2370 if (delete_on_close && !(fsp->desired_access & DELETE_ACCESS)) {
2371 DEBUG(10,("set_delete_on_close_internal: file %s delete on close flag set but delete access denied.\n",
2373 return NT_STATUS_ACCESS_DENIED;
2376 if(fsp->is_directory) {
2377 fsp->directory_delete_on_close = delete_on_close;
2378 DEBUG(10, ("set_delete_on_close_internal: %s delete on close flag for fnum = %d, directory %s\n",
2379 delete_on_close ? "Added" : "Removed", fsp->fnum, fsp->fsp_name ));
2381 fsp->delete_on_close = delete_on_close;
2382 DEBUG(10, ("set_delete_on_close_internal: %s delete on close flag for fnum = %d, file %s\n",
2383 delete_on_close ? "Added" : "Removed", fsp->fnum, fsp->fsp_name ));
2386 return NT_STATUS_OK;
2389 /****************************************************************************
2390 Sets the delete on close flag over all share modes on this file.
2391 Modify the share mode entry for all files open
2392 on this device and inode to tell other smbds we have
2393 changed the delete on close flag. This will be noticed
2394 in the close code, the last closer will delete the file
2396 ****************************************************************************/
2398 NTSTATUS set_delete_on_close_over_all(files_struct *fsp, BOOL delete_on_close)
2400 DEBUG(10,("set_delete_on_close_over_all: %s delete on close flag for fnum = %d, file %s\n",
2401 delete_on_close ? "Adding" : "Removing", fsp->fnum, fsp->fsp_name ));
2403 if (fsp->is_directory || fsp->is_stat)
2404 return NT_STATUS_OK;
2406 if (lock_share_entry_fsp(fsp) == False)
2407 return NT_STATUS_ACCESS_DENIED;
2409 if (!modify_delete_flag(fsp->dev, fsp->inode, delete_on_close)) {
2410 DEBUG(0,("set_delete_on_close_internal: failed to change delete on close flag for file %s\n",
2412 unlock_share_entry_fsp(fsp);
2413 return NT_STATUS_ACCESS_DENIED;
2416 unlock_share_entry_fsp(fsp);
2417 return NT_STATUS_OK;
2420 /****************************************************************************
2421 Returns true if this pathname is within the share, and thus safe.
2422 ****************************************************************************/
2424 static int ensure_link_is_safe(connection_struct *conn, const char *link_dest_in, char *link_dest_out)
2427 char resolved_name[PATH_MAX+1];
2429 pstring resolved_name;
2431 fstring last_component;
2435 BOOL bad_path = False;
2436 SMB_STRUCT_STAT sbuf;
2438 pstrcpy(link_dest, link_dest_in);
2439 unix_convert(link_dest,conn,0,&bad_path,&sbuf);
2441 /* Store the UNIX converted path. */
2442 pstrcpy(link_dest_out, link_dest);
2444 p = strrchr(link_dest, '/');
2446 fstrcpy(last_component, p+1);
2449 fstrcpy(last_component, link_dest);
2450 pstrcpy(link_dest, "./");
2453 if (SMB_VFS_REALPATH(conn,link_dest,resolved_name) == NULL)
2456 pstrcpy(link_dest, resolved_name);
2457 pstrcat(link_dest, "/");
2458 pstrcat(link_dest, last_component);
2460 if (*link_dest != '/') {
2461 /* Relative path. */
2462 pstrcpy(link_test, conn->connectpath);
2463 pstrcat(link_test, "/");
2464 pstrcat(link_test, link_dest);
2466 pstrcpy(link_test, link_dest);
2470 * Check if the link is within the share.
2473 if (strncmp(conn->connectpath, link_test, strlen(conn->connectpath))) {
2480 /****************************************************************************
2481 Set a hard link (called by UNIX extensions and by NT rename with HARD link
2483 ****************************************************************************/
2485 NTSTATUS hardlink_internals(connection_struct *conn, char *name, char *newname)
2487 BOOL bad_path_src = False;
2488 BOOL bad_path_dest = False;
2489 SMB_STRUCT_STAT sbuf1, sbuf2;
2491 pstring last_component_src;
2492 pstring last_component_dest;
2493 NTSTATUS status = NT_STATUS_OK;
2499 if (ms_has_wild(name) || ms_has_wild(newname)) {
2500 return NT_STATUS_OBJECT_PATH_SYNTAX_BAD;
2503 rc = unix_convert(name,conn,last_component_src,&bad_path_src,&sbuf1);
2504 if (!rc && bad_path_src) {
2505 return NT_STATUS_OBJECT_PATH_NOT_FOUND;
2508 /* Quick check for "." and ".." */
2509 if (last_component_src[0] == '.') {
2510 if (!last_component_src[1] || (last_component_src[1] == '.' && !last_component_src[2])) {
2511 return NT_STATUS_OBJECT_NAME_INVALID;
2515 /* source must already exist. */
2516 if (!VALID_STAT(sbuf1)) {
2517 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2520 rcdest = unix_convert(newname,conn,last_component_dest,&bad_path_dest,&sbuf2);
2521 if (!rcdest && bad_path_dest) {
2522 return NT_STATUS_OBJECT_PATH_NOT_FOUND;
2525 /* Quick check for "." and ".." */
2526 if (last_component_dest[0] == '.') {
2527 if (!last_component_dest[1] || (last_component_dest[1] == '.' && !last_component_dest[2])) {
2528 return NT_STATUS_OBJECT_NAME_INVALID;
2532 /* Disallow if already exists. */
2533 if (VALID_STAT(sbuf2)) {
2534 return NT_STATUS_OBJECT_NAME_COLLISION;
2537 /* No links from a directory. */
2538 if (S_ISDIR(sbuf1.st_mode)) {
2539 return NT_STATUS_FILE_IS_A_DIRECTORY;
2542 if (ensure_link_is_safe(conn, newname, newname) != 0)
2543 return NT_STATUS_ACCESS_DENIED;
2545 DEBUG(10,("hardlink_internals: doing hard link %s -> %s\n", name, newname ));
2547 if (SMB_VFS_LINK(conn,name,newname) != 0) {
2548 status = map_nt_error_from_unix(errno);
2549 DEBUG(3,("hardlink_internals: Error %s link %s -> %s\n",
2550 nt_errstr(status), name,newname));
2556 /****************************************************************************
2557 Reply to a TRANS2_SETFILEINFO (set file info by fileid).
2558 ****************************************************************************/
2560 static int call_trans2setfilepathinfo(connection_struct *conn,
2561 char *inbuf, char *outbuf, int length, int bufsize,
2562 char **pparams, int total_params, char **ppdata, int total_data)
2564 char *params = *pparams;
2565 char *pdata = *ppdata;
2566 uint16 tran_call = SVAL(inbuf, smb_setup0);
2571 SMB_STRUCT_STAT sbuf;
2574 BOOL bad_path = False;
2575 files_struct *fsp = NULL;
2576 uid_t set_owner = (uid_t)SMB_UID_NO_CHANGE;
2577 gid_t set_grp = (uid_t)SMB_GID_NO_CHANGE;
2578 mode_t unixmode = 0;
2579 NTSTATUS status = NT_STATUS_OK;
2582 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
2584 if (tran_call == TRANSACT2_SETFILEINFO) {
2585 if (total_params < 4)
2586 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
2588 fsp = file_fsp(params,0);
2589 info_level = SVAL(params,2);
2591 if(fsp && (fsp->is_directory || fsp->fd == -1)) {
2593 * This is actually a SETFILEINFO on a directory
2594 * handle (returned from an NT SMB). NT5.0 seems
2595 * to do this call. JRA.
2597 pstrcpy(fname, fsp->fsp_name);
2598 unix_convert(fname,conn,0,&bad_path,&sbuf);
2599 if (!check_name(fname,conn) || (!VALID_STAT(sbuf))) {
2600 DEBUG(3,("call_trans2setfilepathinfo: fileinfo of %s failed (%s)\n",fname,strerror(errno)));
2601 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRbadpath);
2603 } else if (fsp && fsp->print_file) {
2605 * Doing a DELETE_ON_CLOSE should cancel a print job.
2607 if ((info_level == SMB_SET_FILE_DISPOSITION_INFO) && CVAL(pdata,0)) {
2608 fsp->share_mode = FILE_DELETE_ON_CLOSE;
2610 DEBUG(3,("call_trans2setfilepathinfo: Cancelling print job (%s)\n", fsp->fsp_name ));
2613 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
2616 return (UNIXERROR(ERRDOS,ERRbadpath));
2619 * Original code - this is an open file.
2621 CHECK_FSP(fsp,conn);
2623 pstrcpy(fname, fsp->fsp_name);
2626 if (SMB_VFS_FSTAT(fsp,fd,&sbuf) != 0) {
2627 DEBUG(3,("call_trans2setfilepathinfo: fstat of fnum %d failed (%s)\n",fsp->fnum, strerror(errno)));
2628 return(UNIXERROR(ERRDOS,ERRbadfid));
2633 if (total_params < 6)
2634 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
2636 info_level = SVAL(params,0);
2637 srvstr_get_path(inbuf, fname, ¶ms[6], sizeof(fname), -1, STR_TERMINATE, &status);
2638 if (!NT_STATUS_IS_OK(status)) {
2639 return ERROR_NT(status);
2641 unix_convert(fname,conn,0,&bad_path,&sbuf);
2644 * For CIFS UNIX extensions the target name may not exist.
2647 if(!VALID_STAT(sbuf) && !INFO_LEVEL_IS_UNIX(info_level)) {
2648 DEBUG(3,("call_trans2setfilepathinfo: stat of %s failed (%s)\n", fname, strerror(errno)));
2649 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRbadpath);
2652 if(!check_name(fname, conn)) {
2653 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRbadpath);
2658 if (!CAN_WRITE(conn))
2659 return ERROR_DOS(ERRSRV,ERRaccess);
2661 if (INFO_LEVEL_IS_UNIX(info_level) && !lp_unix_extensions())
2662 return ERROR_DOS(ERRDOS,ERRunknownlevel);
2664 if (VALID_STAT(sbuf))
2665 unixmode = sbuf.st_mode;
2667 DEBUG(3,("call_trans2setfilepathinfo(%d) %s (fnum %d) info_level=%d totdata=%d\n",
2668 tran_call,fname, fsp ? fsp->fnum : -1, info_level,total_data));
2670 /* Realloc the parameter and data sizes */
2671 params = Realloc(*pparams,2);
2673 return ERROR_DOS(ERRDOS,ERRnomem);
2679 /* the pending modtime overrides the current modtime */
2680 sbuf.st_mtime = fsp->pending_modtime;
2683 size = get_file_size(sbuf);
2684 tvs.modtime = sbuf.st_mtime;
2685 tvs.actime = sbuf.st_atime;
2686 dosmode = dos_mode(conn,fname,&sbuf);
2687 unixmode = sbuf.st_mode;
2689 set_owner = VALID_STAT(sbuf) ? sbuf.st_uid : (uid_t)SMB_UID_NO_CHANGE;
2690 set_grp = VALID_STAT(sbuf) ? sbuf.st_gid : (gid_t)SMB_GID_NO_CHANGE;
2692 switch (info_level) {
2693 case SMB_INFO_STANDARD:
2695 if (total_data < 12)
2696 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
2699 tvs.actime = make_unix_date2(pdata+l1_fdateLastAccess);
2701 tvs.modtime = make_unix_date2(pdata+l1_fdateLastWrite);
2705 case SMB_INFO_SET_EA:
2706 return(ERROR_DOS(ERRDOS,ERReasnotsupported));
2708 /* XXXX um, i don't think this is right.
2709 it's also not in the cifs6.txt spec.
2711 case SMB_INFO_QUERY_EAS_FROM_LIST:
2712 if (total_data < 28)
2713 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
2715 tvs.actime = make_unix_date2(pdata+8);
2716 tvs.modtime = make_unix_date2(pdata+12);
2717 size = IVAL(pdata,16);
2718 dosmode = IVAL(pdata,24);
2721 /* XXXX nor this. not in cifs6.txt, either. */
2722 case SMB_INFO_QUERY_ALL_EAS:
2723 if (total_data < 28)
2724 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
2726 tvs.actime = make_unix_date2(pdata+8);
2727 tvs.modtime = make_unix_date2(pdata+12);
2728 size = IVAL(pdata,16);
2729 dosmode = IVAL(pdata,24);
2732 case SMB_SET_FILE_BASIC_INFO:
2733 case SMB_FILE_BASIC_INFORMATION:
2735 /* Patch to do this correctly from Paul Eggert <eggert@twinsun.com>. */
2737 time_t changed_time;
2739 if (total_data < 36)
2740 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
2742 /* Ignore create time at offset pdata. */
2745 tvs.actime = interpret_long_date(pdata+8);
2747 write_time = interpret_long_date(pdata+16);
2748 changed_time = interpret_long_date(pdata+24);
2750 tvs.modtime = MIN(write_time, changed_time);
2752 if (write_time > tvs.modtime && write_time != 0xffffffff) {
2753 tvs.modtime = write_time;
2755 /* Prefer a defined time to an undefined one. */
2756 if (tvs.modtime == (time_t)0 || tvs.modtime == (time_t)-1)
2757 tvs.modtime = (write_time == (time_t)0 || write_time == (time_t)-1
2758 ? changed_time : write_time);
2761 dosmode = IVAL(pdata,32);
2765 case SMB_FILE_ALLOCATION_INFORMATION:
2766 case SMB_SET_FILE_ALLOCATION_INFO:
2769 SMB_BIG_UINT allocation_size;
2772 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
2774 allocation_size = (SMB_BIG_UINT)IVAL(pdata,0);
2775 #ifdef LARGE_SMB_OFF_T
2776 allocation_size |= (((SMB_BIG_UINT)IVAL(pdata,4)) << 32);
2777 #else /* LARGE_SMB_OFF_T */
2778 if (IVAL(pdata,4) != 0) /* more than 32 bits? */
2779 return ERROR_DOS(ERRDOS,ERRunknownlevel);
2780 #endif /* LARGE_SMB_OFF_T */
2781 DEBUG(10,("call_trans2setfilepathinfo: Set file allocation info for file %s to %.0f\n",
2782 fname, (double)allocation_size ));
2784 if (allocation_size)
2785 allocation_size = SMB_ROUNDUP(allocation_size,SMB_ROUNDUP_ALLOCATION_SIZE);
2787 if(allocation_size != get_file_size(sbuf)) {
2788 SMB_STRUCT_STAT new_sbuf;
2790 DEBUG(10,("call_trans2setfilepathinfo: file %s : setting new allocation size to %.0f\n",
2791 fname, (double)allocation_size ));
2794 files_struct *new_fsp = NULL;
2795 int access_mode = 0;
2798 if(global_oplock_break) {
2799 /* Queue this file modify as we are the process of an oplock break. */
2801 DEBUG(2,("call_trans2setfilepathinfo: queueing message due to being "));
2802 DEBUGADD(2,( "in oplock break state.\n"));
2804 push_oplock_pending_smb_message(inbuf, length);
2808 new_fsp = open_file_shared1(conn, fname, &sbuf,FILE_WRITE_DATA,
2809 SET_OPEN_MODE(DOS_OPEN_RDWR),
2810 (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN),
2811 0, 0, &access_mode, &action);
2813 if (new_fsp == NULL)
2814 return(UNIXERROR(ERRDOS,ERRbadpath));
2815 ret = vfs_allocate_file_space(new_fsp, allocation_size);
2816 if (SMB_VFS_FSTAT(new_fsp,new_fsp->fd,&new_sbuf) != 0) {
2817 DEBUG(3,("call_trans2setfilepathinfo: fstat of fnum %d failed (%s)\n",
2818 new_fsp->fnum, strerror(errno)));
2821 close_file(new_fsp,True);
2823 ret = vfs_allocate_file_space(fsp, allocation_size);
2824 if (SMB_VFS_FSTAT(fsp,fd,&new_sbuf) != 0) {
2825 DEBUG(3,("call_trans2setfilepathinfo: fstat of fnum %d failed (%s)\n",
2826 fsp->fnum, strerror(errno)));
2831 return ERROR_NT(NT_STATUS_DISK_FULL);
2833 /* Allocate can truncate size... */
2834 size = get_file_size(new_sbuf);
2840 case SMB_FILE_END_OF_FILE_INFORMATION:
2841 case SMB_SET_FILE_END_OF_FILE_INFO:
2844 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
2846 size = IVAL(pdata,0);
2847 #ifdef LARGE_SMB_OFF_T
2848 size |= (((SMB_OFF_T)IVAL(pdata,4)) << 32);
2849 #else /* LARGE_SMB_OFF_T */
2850 if (IVAL(pdata,4) != 0) /* more than 32 bits? */
2851 return ERROR_DOS(ERRDOS,ERRunknownlevel);
2852 #endif /* LARGE_SMB_OFF_T */
2853 DEBUG(10,("call_trans2setfilepathinfo: Set end of file info for file %s to %.0f\n", fname, (double)size ));
2857 case SMB_FILE_DISPOSITION_INFORMATION:
2858 case SMB_SET_FILE_DISPOSITION_INFO: /* Set delete on close for open file. */
2860 BOOL delete_on_close;
2863 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
2865 delete_on_close = (CVAL(pdata,0) ? True : False);
2867 /* Just ignore this set on a path. */
2868 if (tran_call != TRANSACT2_SETFILEINFO)
2872 return(UNIXERROR(ERRDOS,ERRbadfid));
2874 status = set_delete_on_close_internal(fsp, delete_on_close);
2876 if (NT_STATUS_V(status) != NT_STATUS_V(NT_STATUS_OK))
2877 return ERROR_NT(status);
2879 /* The set is across all open files on this dev/inode pair. */
2880 status =set_delete_on_close_over_all(fsp, delete_on_close);
2881 if (NT_STATUS_V(status) != NT_STATUS_V(NT_STATUS_OK))
2882 return ERROR_NT(status);
2887 case SMB_FILE_POSITION_INFORMATION:
2889 SMB_BIG_UINT position_information;
2892 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
2894 position_information = (SMB_BIG_UINT)IVAL(pdata,0);
2895 #ifdef LARGE_SMB_OFF_T
2896 position_information |= (((SMB_BIG_UINT)IVAL(pdata,4)) << 32);
2897 #else /* LARGE_SMB_OFF_T */
2898 if (IVAL(pdata,4) != 0) /* more than 32 bits? */
2899 return ERROR_DOS(ERRDOS,ERRunknownlevel);
2900 #endif /* LARGE_SMB_OFF_T */
2901 DEBUG(10,("call_trans2setfilepathinfo: Set file position information for file %s to %.0f\n",
2902 fname, (double)position_information ));
2904 fsp->position_information = position_information;
2909 * CIFS UNIX extensions.
2912 case SMB_SET_FILE_UNIX_BASIC:
2914 uint32 raw_unixmode;
2916 if (total_data < 100)
2917 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
2919 if(IVAL(pdata, 0) != SMB_SIZE_NO_CHANGE_LO &&
2920 IVAL(pdata, 4) != SMB_SIZE_NO_CHANGE_HI) {
2921 size=IVAL(pdata,0); /* first 8 Bytes are size */
2922 #ifdef LARGE_SMB_OFF_T
2923 size |= (((SMB_OFF_T)IVAL(pdata,4)) << 32);
2924 #else /* LARGE_SMB_OFF_T */
2925 if (IVAL(pdata,4) != 0) /* more than 32 bits? */
2926 return ERROR_DOS(ERRDOS,ERRunknownlevel);
2927 #endif /* LARGE_SMB_OFF_T */
2929 pdata+=24; /* ctime & st_blocks are not changed */
2930 tvs.actime = interpret_long_unix_date(pdata); /* access_time */
2931 tvs.modtime = interpret_long_unix_date(pdata+8); /* modification_time */
2933 set_owner = (uid_t)IVAL(pdata,0);
2935 set_grp = (gid_t)IVAL(pdata,0);
2937 raw_unixmode = IVAL(pdata,28);
2938 unixmode = unix_perms_from_wire(conn, &sbuf, raw_unixmode);
2939 dosmode = 0; /* Ensure dos mode change doesn't override this. */
2941 DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_BASIC: name = %s \
2942 size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n",
2943 fname, (double)size, (unsigned int)set_owner, (unsigned int)set_grp, (int)raw_unixmode));
2945 if (!VALID_STAT(sbuf)) {
2948 * The only valid use of this is to create character and block
2949 * devices, and named pipes. This is deprecated (IMHO) and
2950 * a new info level should be used for mknod. JRA.
2953 #if !defined(HAVE_MAKEDEV_FN)
2954 return(ERROR_DOS(ERRDOS,ERRnoaccess));
2955 #else /* HAVE_MAKEDEV_FN */
2956 uint32 file_type = IVAL(pdata,0);
2957 uint32 dev_major = IVAL(pdata,4);
2958 uint32 dev_minor = IVAL(pdata,12);
2960 uid_t myuid = geteuid();
2961 gid_t mygid = getegid();
2964 if (tran_call == TRANSACT2_SETFILEINFO)
2965 return(ERROR_DOS(ERRDOS,ERRnoaccess));
2967 if (raw_unixmode == SMB_MODE_NO_CHANGE)
2968 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
2970 dev = makedev(dev_major, dev_minor);
2972 /* We can only create as the owner/group we are. */
2974 if ((set_owner != myuid) && (set_owner != (uid_t)SMB_UID_NO_CHANGE))
2975 return(ERROR_DOS(ERRDOS,ERRnoaccess));
2976 if ((set_grp != mygid) && (set_grp != (gid_t)SMB_GID_NO_CHANGE))
2977 return(ERROR_DOS(ERRDOS,ERRnoaccess));
2979 if (file_type != UNIX_TYPE_CHARDEV && file_type != UNIX_TYPE_BLKDEV &&
2980 file_type != UNIX_TYPE_FIFO)
2981 return(ERROR_DOS(ERRDOS,ERRnoaccess));
2983 DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_BASIC doing mknod dev %.0f mode \
2984 0%o for file %s\n", (double)dev, unixmode, fname ));
2986 /* Ok - do the mknod. */
2987 if (SMB_VFS_MKNOD(conn,dos_to_unix_static(fname), unixmode, dev) != 0)
2988 return(UNIXERROR(ERRDOS,ERRnoaccess));
2990 inherit_access_acl(conn, fname, unixmode);
2993 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
2995 #endif /* HAVE_MAKEDEV_FN */
3000 * Deal with the UNIX specific mode set.
3003 if (raw_unixmode != SMB_MODE_NO_CHANGE) {
3004 DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_BASIC setting mode 0%o for file %s\n",
3005 (unsigned int)unixmode, fname ));
3006 if (SMB_VFS_CHMOD(conn,fname,unixmode) != 0)
3007 return(UNIXERROR(ERRDOS,ERRnoaccess));
3011 * Deal with the UNIX specific uid set.
3014 if ((set_owner != (uid_t)SMB_UID_NO_CHANGE) && (sbuf.st_uid != set_owner)) {
3015 DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_BASIC changing owner %u for file %s\n",
3016 (unsigned int)set_owner, fname ));
3017 if (SMB_VFS_CHOWN(conn,fname,set_owner, (gid_t)-1) != 0)
3018 return(UNIXERROR(ERRDOS,ERRnoaccess));
3022 * Deal with the UNIX specific gid set.
3025 if ((set_grp != (uid_t)SMB_GID_NO_CHANGE) && (sbuf.st_gid != set_grp)) {
3026 DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_BASIC changing group %u for file %s\n",
3027 (unsigned int)set_owner, fname ));
3028 if (SMB_VFS_CHOWN(conn,fname,(uid_t)-1, set_grp) != 0)
3029 return(UNIXERROR(ERRDOS,ERRnoaccess));
3034 case SMB_SET_FILE_UNIX_LINK:
3037 /* Set a symbolic link. */
3038 /* Don't allow this if follow links is false. */
3040 if (!lp_symlinks(SNUM(conn)))
3041 return(ERROR_DOS(ERRDOS,ERRnoaccess));
3043 srvstr_get_path(inbuf, link_dest, pdata, sizeof(link_dest), -1, STR_TERMINATE, &status);
3044 if (!NT_STATUS_IS_OK(status)) {
3045 return ERROR_NT(status);
3048 if (ensure_link_is_safe(conn, link_dest, link_dest) != 0)
3049 return(UNIXERROR(ERRDOS,ERRnoaccess));
3051 DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_LINK doing symlink %s -> %s\n",
3052 fname, link_dest ));
3054 if (SMB_VFS_SYMLINK(conn,link_dest,fname) != 0)
3055 return(UNIXERROR(ERRDOS,ERRnoaccess));
3057 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
3061 case SMB_SET_FILE_UNIX_HLINK:
3065 /* Set a hard link. */
3066 srvstr_get_path(inbuf, link_dest, pdata, sizeof(link_dest), -1, STR_TERMINATE, &status);
3067 if (!NT_STATUS_IS_OK(status)) {
3068 return ERROR_NT(status);
3071 DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_LINK doing hard link %s -> %s\n",
3072 fname, link_dest ));
3074 status = hardlink_internals(conn, fname, link_dest);
3075 if (!NT_STATUS_IS_OK(status)) {
3076 return ERROR_NT(status);
3080 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
3084 case SMB_FILE_RENAME_INFORMATION:
3093 if (total_data < 12)
3094 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
3096 overwrite = (CVAL(pdata,0) ? True : False);
3097 root_fid = IVAL(pdata,4);
3098 len = IVAL(pdata,8);
3099 srvstr_get_path(inbuf, newname, &pdata[12], sizeof(newname), len, 0, &status);
3100 if (!NT_STATUS_IS_OK(status)) {
3101 return ERROR_NT(status);
3104 /* Check the new name has no '/' characters. */
3105 if (strchr_m(newname, '/'))
3106 return ERROR_NT(NT_STATUS_NOT_SUPPORTED);
3108 RESOLVE_DFSPATH(newname, conn, inbuf, outbuf);
3110 /* Create the base directory. */
3111 pstrcpy(base_name, fname);
3112 p = strrchr_m(base_name, '/');
3115 /* Append the new name. */
3116 pstrcat(base_name, "/");
3117 pstrcat(base_name, newname);
3120 DEBUG(10,("call_trans2setfilepathinfo: SMB_FILE_RENAME_INFORMATION (fnum %d) %s -> %s\n",
3121 fsp->fnum, fsp->fsp_name, base_name ));
3122 status = rename_internals_fsp(conn, fsp, base_name, overwrite);
3124 DEBUG(10,("call_trans2setfilepathinfo: SMB_FILE_RENAME_INFORMATION %s -> %s\n",
3126 status = rename_internals(conn, fname, base_name, 0, overwrite);
3128 if (!NT_STATUS_IS_OK(status)) {
3129 return ERROR_NT(status);
3131 process_pending_change_notify_queue((time_t)0);
3133 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
3137 return ERROR_DOS(ERRDOS,ERRunknownlevel);
3140 /* get some defaults (no modifications) if any info is zero or -1. */
3141 if (tvs.actime == (time_t)0 || tvs.actime == (time_t)-1)
3142 tvs.actime = sbuf.st_atime;
3144 if (tvs.modtime == (time_t)0 || tvs.modtime == (time_t)-1)
3145 tvs.modtime = sbuf.st_mtime;
3147 DEBUG(6,("actime: %s " , ctime(&tvs.actime)));
3148 DEBUG(6,("modtime: %s ", ctime(&tvs.modtime)));
3149 DEBUG(6,("size: %.0f ", (double)size));
3152 if (S_ISDIR(sbuf.st_mode))
3158 DEBUG(6,("dosmode: %x\n" , dosmode));
3160 if(!((info_level == SMB_SET_FILE_END_OF_FILE_INFO) ||
3161 (info_level == SMB_SET_FILE_ALLOCATION_INFO) ||
3162 (info_level == SMB_FILE_ALLOCATION_INFORMATION) ||
3163 (info_level == SMB_FILE_END_OF_FILE_INFORMATION))) {
3166 * Only do this test if we are not explicitly
3167 * changing the size of a file.
3170 size = get_file_size(sbuf);
3174 * Try and set the times, size and mode of this file -
3175 * if they are different from the current values
3177 if (sbuf.st_mtime != tvs.modtime || sbuf.st_atime != tvs.actime) {
3180 * This was a setfileinfo on an open file.
3181 * NT does this a lot. It's actually pointless
3182 * setting the time here, as it will be overwritten
3183 * on the next write, so we save the request
3184 * away and will set it on file close. JRA.
3187 if (tvs.modtime != (time_t)0 && tvs.modtime != (time_t)-1) {
3188 DEBUG(10,("call_trans2setfilepathinfo: setting pending modtime to %s\n", ctime(&tvs.modtime) ));
3189 fsp->pending_modtime = tvs.modtime;
3194 DEBUG(10,("call_trans2setfilepathinfo: setting utimes to modified values.\n"));
3196 if(file_utime(conn, fname, &tvs)!=0)
3197 return(UNIXERROR(ERRDOS,ERRnoaccess));
3201 /* check the mode isn't different, before changing it */
3202 if ((dosmode != 0) && (dosmode != dos_mode(conn, fname, &sbuf))) {
3204 DEBUG(10,("call_trans2setfilepathinfo: file %s : setting dos mode %x\n", fname, dosmode ));
3206 if(file_chmod(conn, fname, dosmode, NULL)) {
3207 DEBUG(2,("chmod of %s failed (%s)\n", fname, strerror(errno)));
3208 return(UNIXERROR(ERRDOS,ERRnoaccess));
3212 if (size != get_file_size(sbuf)) {
3216 DEBUG(10,("call_trans2setfilepathinfo: file %s : setting new size to %.0f\n",
3217 fname, (double)size ));
3220 files_struct *new_fsp = NULL;
3221 int access_mode = 0;
3224 if(global_oplock_break) {
3225 /* Queue this file modify as we are the process of an oplock break. */
3227 DEBUG(2,("call_trans2setfilepathinfo: queueing message due to being "));
3228 DEBUGADD(2,( "in oplock break state.\n"));
3230 push_oplock_pending_smb_message(inbuf, length);
3234 new_fsp = open_file_shared(conn, fname, &sbuf,
3235 SET_OPEN_MODE(DOS_OPEN_RDWR),
3236 (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN),
3237 0, 0, &access_mode, &action);
3239 if (new_fsp == NULL)
3240 return(UNIXERROR(ERRDOS,ERRbadpath));
3241 ret = vfs_set_filelen(new_fsp, size);
3242 close_file(new_fsp,True);
3244 ret = vfs_set_filelen(fsp, size);
3248 return (UNIXERROR(ERRHRD,ERRdiskfull));
3252 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
3257 /****************************************************************************
3258 Reply to a TRANS2_MKDIR (make directory with extended attributes).
3259 ****************************************************************************/
3261 static int call_trans2mkdir(connection_struct *conn,
3262 char *inbuf, char *outbuf, int length, int bufsize,
3263 char **pparams, int total_params, char **ppdata, int total_data)
3265 char *params = *pparams;
3268 SMB_STRUCT_STAT sbuf;
3269 BOOL bad_path = False;
3270 NTSTATUS status = NT_STATUS_OK;
3272 if (!CAN_WRITE(conn))
3273 return ERROR_DOS(ERRSRV,ERRaccess);
3275 if (total_params < 4)
3276 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
3278 srvstr_get_path(inbuf, directory, ¶ms[4], sizeof(directory), -1, STR_TERMINATE, &status);
3279 if (!NT_STATUS_IS_OK(status)) {
3280 return ERROR_NT(status);
3283 DEBUG(3,("call_trans2mkdir : name = %s\n", directory));
3285 unix_convert(directory,conn,0,&bad_path,&sbuf);
3286 if (check_name(directory,conn))
3287 ret = vfs_MkDir(conn,directory,unix_mode(conn,aDIR,directory));
3290 DEBUG(5,("call_trans2mkdir error (%s)\n", strerror(errno)));
3291 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRnoaccess);
3294 /* Realloc the parameter and data sizes */
3295 params = Realloc(*pparams,2);
3297 return ERROR_DOS(ERRDOS,ERRnomem);
3302 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
3307 /****************************************************************************
3308 Reply to a TRANS2_FINDNOTIFYFIRST (start monitoring a directory for changes).
3309 We don't actually do this - we just send a null response.
3310 ****************************************************************************/
3312 static int call_trans2findnotifyfirst(connection_struct *conn,
3313 char *inbuf, char *outbuf, int length, int bufsize,
3314 char **pparams, int total_params, char **ppdata, int total_data)
3316 static uint16 fnf_handle = 257;
3317 char *params = *pparams;
3320 if (total_params < 6)
3321 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
3323 info_level = SVAL(params,4);
3324 DEBUG(3,("call_trans2findnotifyfirst - info_level %d\n", info_level));
3326 switch (info_level) {
3331 return ERROR_DOS(ERRDOS,ERRunknownlevel);
3334 /* Realloc the parameter and data sizes */
3335 params = Realloc(*pparams,6);
3337 return ERROR_DOS(ERRDOS,ERRnomem);
3340 SSVAL(params,0,fnf_handle);
3341 SSVAL(params,2,0); /* No changes */
3342 SSVAL(params,4,0); /* No EA errors */
3349 send_trans2_replies(outbuf, bufsize, params, 6, *ppdata, 0);
3354 /****************************************************************************
3355 Reply to a TRANS2_FINDNOTIFYNEXT (continue monitoring a directory for
3356 changes). Currently this does nothing.
3357 ****************************************************************************/
3359 static int call_trans2findnotifynext(connection_struct *conn,
3360 char *inbuf, char *outbuf, int length, int bufsize,
3361 char **pparams, int total_params, char **ppdata, int total_data)
3363 char *params = *pparams;
3365 DEBUG(3,("call_trans2findnotifynext\n"));
3367 /* Realloc the parameter and data sizes */
3368 params = Realloc(*pparams,4);
3370 return ERROR_DOS(ERRDOS,ERRnomem);
3373 SSVAL(params,0,0); /* No changes */
3374 SSVAL(params,2,0); /* No EA errors */
3376 send_trans2_replies(outbuf, bufsize, params, 4, *ppdata, 0);
3381 /****************************************************************************
3382 Reply to a TRANS2_GET_DFS_REFERRAL - Shirish Kalele <kalele@veritas.com>.
3383 ****************************************************************************/
3385 static int call_trans2getdfsreferral(connection_struct *conn, char* inbuf,
3386 char* outbuf, int length, int bufsize,
3387 char **pparams, int total_params, char **ppdata, int total_data)
3389 char *params = *pparams;
3392 int max_referral_level;
3394 DEBUG(10,("call_trans2getdfsreferral\n"));
3396 if (total_params < 2)
3397 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
3399 max_referral_level = SVAL(params,0);
3401 if(!lp_host_msdfs())
3402 return ERROR_DOS(ERRDOS,ERRbadfunc);
3404 srvstr_pull(inbuf, pathname, ¶ms[2], sizeof(pathname), -1, STR_TERMINATE);
3405 if((reply_size = setup_dfs_referral(conn, pathname,max_referral_level,ppdata)) < 0)
3406 return UNIXERROR(ERRDOS,ERRbadfile);
3408 SSVAL(outbuf,smb_flg2,SVAL(outbuf,smb_flg2) | FLAGS2_DFS_PATHNAMES);
3409 send_trans2_replies(outbuf,bufsize,0,0,*ppdata,reply_size);
3414 #define LMCAT_SPL 0x53
3415 #define LMFUNC_GETJOBID 0x60
3417 /****************************************************************************
3418 Reply to a TRANS2_IOCTL - used for OS/2 printing.
3419 ****************************************************************************/
3421 static int call_trans2ioctl(connection_struct *conn, char* inbuf,
3422 char* outbuf, int length, int bufsize,
3423 char **pparams, int total_params, char **ppdata, int total_data)
3425 char *pdata = *ppdata;
3426 files_struct *fsp = file_fsp(inbuf,smb_vwv15);
3428 /* check for an invalid fid before proceeding */
3431 return(ERROR_DOS(ERRDOS,ERRbadfid));
3433 if ((SVAL(inbuf,(smb_setup+4)) == LMCAT_SPL) &&
3434 (SVAL(inbuf,(smb_setup+6)) == LMFUNC_GETJOBID)) {
3435 pdata = Realloc(*ppdata, 32);
3437 return ERROR_DOS(ERRDOS,ERRnomem);
3440 /* NOTE - THIS IS ASCII ONLY AT THE MOMENT - NOT SURE IF OS/2
3441 CAN ACCEPT THIS IN UNICODE. JRA. */
3443 SSVAL(pdata,0,fsp->rap_print_jobid); /* Job number */
3444 srvstr_push( outbuf, pdata + 2, global_myname(), 15, STR_ASCII|STR_TERMINATE); /* Our NetBIOS name */
3445 srvstr_push( outbuf, pdata+18, lp_servicename(SNUM(conn)), 13, STR_ASCII|STR_TERMINATE); /* Service name */
3446 send_trans2_replies(outbuf,bufsize,*pparams,0,*ppdata,32);
3449 DEBUG(2,("Unknown TRANS2_IOCTL\n"));
3450 return ERROR_DOS(ERRSRV,ERRerror);
3454 /****************************************************************************
3455 Reply to a SMBfindclose (stop trans2 directory search).
3456 ****************************************************************************/
3458 int reply_findclose(connection_struct *conn,
3459 char *inbuf,char *outbuf,int length,int bufsize)
3462 int dptr_num=SVALS(inbuf,smb_vwv0);
3463 START_PROFILE(SMBfindclose);
3465 DEBUG(3,("reply_findclose, dptr_num = %d\n", dptr_num));
3467 dptr_close(&dptr_num);
3469 outsize = set_message(outbuf,0,0,True);
3471 DEBUG(3,("SMBfindclose dptr_num = %d\n", dptr_num));
3473 END_PROFILE(SMBfindclose);
3477 /****************************************************************************
3478 Reply to a SMBfindnclose (stop FINDNOTIFYFIRST directory search).
3479 ****************************************************************************/
3481 int reply_findnclose(connection_struct *conn,
3482 char *inbuf,char *outbuf,int length,int bufsize)
3486 START_PROFILE(SMBfindnclose);
3488 dptr_num = SVAL(inbuf,smb_vwv0);
3490 DEBUG(3,("reply_findnclose, dptr_num = %d\n", dptr_num));
3492 /* We never give out valid handles for a
3493 findnotifyfirst - so any dptr_num is ok here.
3496 outsize = set_message(outbuf,0,0,True);
3498 DEBUG(3,("SMB_findnclose dptr_num = %d\n", dptr_num));
3500 END_PROFILE(SMBfindnclose);
3504 /****************************************************************************
3505 Reply to a SMBtranss2 - just ignore it!
3506 ****************************************************************************/
3508 int reply_transs2(connection_struct *conn,
3509 char *inbuf,char *outbuf,int length,int bufsize)
3511 START_PROFILE(SMBtranss2);
3512 DEBUG(4,("Ignoring transs2 of length %d\n",length));
3513 END_PROFILE(SMBtranss2);
3517 /****************************************************************************
3518 Reply to a SMBtrans2.
3519 ****************************************************************************/
3521 int reply_trans2(connection_struct *conn,
3522 char *inbuf,char *outbuf,int length,int bufsize)
3525 unsigned int total_params = SVAL(inbuf, smb_tpscnt);
3526 unsigned int total_data =SVAL(inbuf, smb_tdscnt);
3528 unsigned int max_param_reply = SVAL(inbuf, smb_mprcnt);
3529 unsigned int max_data_reply = SVAL(inbuf, smb_mdrcnt);
3530 unsigned int max_setup_fields = SVAL(inbuf, smb_msrcnt);
3531 BOOL close_tid = BITSETW(inbuf+smb_flags,0);
3532 BOOL no_final_response = BITSETW(inbuf+smb_flags,1);
3533 int32 timeout = IVALS(inbuf,smb_timeout);
3535 unsigned int suwcnt = SVAL(inbuf, smb_suwcnt);
3536 unsigned int tran_call = SVAL(inbuf, smb_setup0);
3537 char *params = NULL, *data = NULL;
3538 unsigned int num_params, num_params_sofar, num_data, num_data_sofar;
3539 START_PROFILE(SMBtrans2);
3541 if(global_oplock_break && (tran_call == TRANSACT2_OPEN)) {
3542 /* Queue this open message as we are the process of an
3545 DEBUG(2,("reply_trans2: queueing message trans2open due to being "));
3546 DEBUGADD(2,( "in oplock break state.\n"));
3548 push_oplock_pending_smb_message(inbuf, length);
3549 END_PROFILE(SMBtrans2);
3553 if (IS_IPC(conn) && (tran_call != TRANSACT2_OPEN)
3554 && (tran_call != TRANSACT2_GET_DFS_REFERRAL)) {
3555 END_PROFILE(SMBtrans2);
3556 return ERROR_DOS(ERRSRV,ERRaccess);
3559 outsize = set_message(outbuf,0,0,True);
3561 /* All trans2 messages we handle have smb_sucnt == 1 - ensure this
3562 is so as a sanity check */
3565 * Need to have rc=0 for ioctl to get job id for OS/2.
3566 * Network printing will fail if function is not successful.
3567 * Similar function in reply.c will be used if protocol
3568 * is LANMAN1.0 instead of LM1.2X002.
3569 * Until DosPrintSetJobInfo with PRJINFO3 is supported,
3570 * outbuf doesn't have to be set(only job id is used).
3572 if ( (suwcnt == 4) && (tran_call == TRANSACT2_IOCTL) &&
3573 (SVAL(inbuf,(smb_setup+4)) == LMCAT_SPL) &&
3574 (SVAL(inbuf,(smb_setup+6)) == LMFUNC_GETJOBID)) {
3575 DEBUG(2,("Got Trans2 DevIOctl jobid\n"));
3577 DEBUG(2,("Invalid smb_sucnt in trans2 call(%u)\n",suwcnt));
3578 DEBUG(2,("Transaction is %d\n",tran_call));
3579 END_PROFILE(SMBtrans2);
3580 ERROR_DOS(ERRDOS,ERRinvalidparam);
3584 /* Allocate the space for the maximum needed parameters and data */
3585 if (total_params > 0)
3586 params = (char *)malloc(total_params);
3588 data = (char *)malloc(total_data);
3590 if ((total_params && !params) || (total_data && !data)) {
3591 DEBUG(2,("Out of memory in reply_trans2\n"));
3594 END_PROFILE(SMBtrans2);
3595 return ERROR_DOS(ERRDOS,ERRnomem);
3598 /* Copy the param and data bytes sent with this request into
3599 the params buffer */
3600 num_params = num_params_sofar = SVAL(inbuf,smb_pscnt);
3601 num_data = num_data_sofar = SVAL(inbuf, smb_dscnt);
3603 if (num_params > total_params || num_data > total_data)
3604 exit_server("invalid params in reply_trans2");
3607 unsigned int psoff = SVAL(inbuf, smb_psoff);
3608 if ((psoff + num_params < psoff) || (psoff + num_params < num_params))
3610 if ((smb_base(inbuf) + psoff + num_params > inbuf + length) ||
3611 (smb_base(inbuf) + psoff + num_params < smb_base(inbuf)))
3613 memcpy( params, smb_base(inbuf) + psoff, num_params);
3616 unsigned int dsoff = SVAL(inbuf, smb_dsoff);
3617 if ((dsoff + num_data < dsoff) || (dsoff + num_data < num_data))
3619 if ((smb_base(inbuf) + dsoff + num_data > inbuf + length) ||
3620 (smb_base(inbuf) + dsoff + num_data < smb_base(inbuf)))
3622 memcpy( data, smb_base(inbuf) + dsoff, num_data);
3625 srv_signing_trans_start(SVAL(inbuf,smb_mid));
3627 if(num_data_sofar < total_data || num_params_sofar < total_params) {
3628 /* We need to send an interim response then receive the rest
3629 of the parameter/data bytes */
3630 outsize = set_message(outbuf,0,0,True);
3631 srv_signing_trans_stop();
3632 if (!send_smb(smbd_server_fd(),outbuf))
3633 exit_server("reply_trans2: send_smb failed.");
3635 while (num_data_sofar < total_data ||
3636 num_params_sofar < total_params) {
3638 unsigned int param_disp;
3639 unsigned int param_off;
3640 unsigned int data_disp;
3641 unsigned int data_off;
3643 ret = receive_next_smb(inbuf,bufsize,SMB_SECONDARY_WAIT);
3646 * The sequence number for the trans reply is always
3647 * based on the last secondary received.
3650 srv_signing_trans_start(SVAL(inbuf,smb_mid));
3653 (CVAL(inbuf, smb_com) != SMBtranss2)) || !ret) {
3654 outsize = set_message(outbuf,0,0,True);
3656 DEBUG(0,("reply_trans2: Invalid secondary trans2 packet\n"));
3658 DEBUG(0,("reply_trans2: %s in getting secondary trans2 response.\n",
3659 (smb_read_error == READ_ERROR) ? "error" : "timeout" ));
3663 /* Revise total_params and total_data in case
3664 they have changed downwards */
3665 if (SVAL(inbuf, smb_tpscnt) < total_params)
3666 total_params = SVAL(inbuf, smb_tpscnt);
3667 if (SVAL(inbuf, smb_tdscnt) < total_data)
3668 total_data = SVAL(inbuf, smb_tdscnt);
3670 num_params = SVAL(inbuf,smb_spscnt);
3671 param_off = SVAL(inbuf, smb_spsoff);
3672 param_disp = SVAL(inbuf, smb_spsdisp);
3673 num_params_sofar += num_params;
3675 num_data = SVAL(inbuf, smb_sdscnt);
3676 data_off = SVAL(inbuf, smb_sdsoff);
3677 data_disp = SVAL(inbuf, smb_sdsdisp);
3678 num_data_sofar += num_data;
3680 if (num_params_sofar > total_params || num_data_sofar > total_data)
3684 if (param_disp + num_params >= total_params)
3686 if ((param_disp + num_params < param_disp) ||
3687 (param_disp + num_params < num_params))
3689 if (param_disp > total_params)
3691 if ((smb_base(inbuf) + param_off + num_params >= inbuf + bufsize) ||
3692 (smb_base(inbuf) + param_off + num_params < smb_base(inbuf)))
3694 if (params + param_disp < params)
3697 memcpy( ¶ms[param_disp], smb_base(inbuf) + param_off, num_params);
3700 if (data_disp + num_data >= total_data)
3702 if ((data_disp + num_data < data_disp) ||
3703 (data_disp + num_data < num_data))
3705 if (data_disp > total_data)
3707 if ((smb_base(inbuf) + data_off + num_data >= inbuf + bufsize) ||
3708 (smb_base(inbuf) + data_off + num_data < smb_base(inbuf)))
3710 if (data + data_disp < data)
3713 memcpy( &data[data_disp], smb_base(inbuf) + data_off, num_data);
3718 if (Protocol >= PROTOCOL_NT1) {
3719 SSVAL(outbuf,smb_flg2,SVAL(outbuf,smb_flg2) | 0x40); /* IS_LONG_NAME */
3722 /* Now we must call the relevant TRANS2 function */
3724 case TRANSACT2_OPEN:
3725 START_PROFILE_NESTED(Trans2_open);
3726 outsize = call_trans2open(conn, inbuf, outbuf, bufsize,
3727 ¶ms, total_params, &data, total_data);
3728 END_PROFILE_NESTED(Trans2_open);
3731 case TRANSACT2_FINDFIRST:
3732 START_PROFILE_NESTED(Trans2_findfirst);
3733 outsize = call_trans2findfirst(conn, inbuf, outbuf, bufsize,
3734 ¶ms, total_params, &data, total_data);
3735 END_PROFILE_NESTED(Trans2_findfirst);
3738 case TRANSACT2_FINDNEXT:
3739 START_PROFILE_NESTED(Trans2_findnext);
3740 outsize = call_trans2findnext(conn, inbuf, outbuf, length, bufsize,
3741 ¶ms, total_params, &data, total_data);
3742 END_PROFILE_NESTED(Trans2_findnext);
3745 case TRANSACT2_QFSINFO:
3746 START_PROFILE_NESTED(Trans2_qfsinfo);
3747 outsize = call_trans2qfsinfo(conn, inbuf, outbuf, length, bufsize,
3748 ¶ms, total_params, &data, total_data);
3749 END_PROFILE_NESTED(Trans2_qfsinfo);
3752 #ifdef HAVE_SYS_QUOTAS
3753 case TRANSACT2_SETFSINFO:
3754 START_PROFILE_NESTED(Trans2_setfsinfo);
3755 outsize = call_trans2setfsinfo(conn, inbuf, outbuf, length, bufsize,
3756 ¶ms, total_params, &data, total_data);
3757 END_PROFILE_NESTED(Trans2_setfsinfo);
3760 case TRANSACT2_QPATHINFO:
3761 case TRANSACT2_QFILEINFO:
3762 START_PROFILE_NESTED(Trans2_qpathinfo);
3763 outsize = call_trans2qfilepathinfo(conn, inbuf, outbuf, length, bufsize,
3764 ¶ms, total_params, &data, total_data);
3765 END_PROFILE_NESTED(Trans2_qpathinfo);
3767 case TRANSACT2_SETPATHINFO:
3768 case TRANSACT2_SETFILEINFO:
3769 START_PROFILE_NESTED(Trans2_setpathinfo);
3770 outsize = call_trans2setfilepathinfo(conn, inbuf, outbuf, length, bufsize,
3771 ¶ms, total_params, &data, total_data);
3772 END_PROFILE_NESTED(Trans2_setpathinfo);
3775 case TRANSACT2_FINDNOTIFYFIRST:
3776 START_PROFILE_NESTED(Trans2_findnotifyfirst);
3777 outsize = call_trans2findnotifyfirst(conn, inbuf, outbuf, length, bufsize,
3778 ¶ms, total_params, &data, total_data);
3779 END_PROFILE_NESTED(Trans2_findnotifyfirst);
3782 case TRANSACT2_FINDNOTIFYNEXT:
3783 START_PROFILE_NESTED(Trans2_findnotifynext);
3784 outsize = call_trans2findnotifynext(conn, inbuf, outbuf, length, bufsize,
3785 ¶ms, total_params, &data, total_data);
3786 END_PROFILE_NESTED(Trans2_findnotifynext);
3788 case TRANSACT2_MKDIR:
3789 START_PROFILE_NESTED(Trans2_mkdir);
3790 outsize = call_trans2mkdir(conn, inbuf, outbuf, length, bufsize,
3791 ¶ms, total_params, &data, total_data);
3792 END_PROFILE_NESTED(Trans2_mkdir);
3795 case TRANSACT2_GET_DFS_REFERRAL:
3796 START_PROFILE_NESTED(Trans2_get_dfs_referral);
3797 outsize = call_trans2getdfsreferral(conn,inbuf,outbuf,length, bufsize,
3798 ¶ms, total_params, &data, total_data);
3799 END_PROFILE_NESTED(Trans2_get_dfs_referral);
3801 case TRANSACT2_IOCTL:
3802 START_PROFILE_NESTED(Trans2_ioctl);
3803 outsize = call_trans2ioctl(conn,inbuf,outbuf,length, bufsize,
3804 ¶ms, total_params, &data, total_data);
3805 END_PROFILE_NESTED(Trans2_ioctl);
3808 /* Error in request */
3809 DEBUG(2,("Unknown request %d in trans2 call\n", tran_call));
3812 END_PROFILE(SMBtrans2);
3813 srv_signing_trans_stop();
3814 return ERROR_DOS(ERRSRV,ERRerror);
3817 /* As we do not know how many data packets will need to be
3818 returned here the various call_trans2xxxx calls
3819 must send their own. Thus a call_trans2xxx routine only
3820 returns a value other than -1 when it wants to send
3824 srv_signing_trans_stop();
3828 END_PROFILE(SMBtrans2);
3829 return outsize; /* If a correct response was needed the
3830 call_trans2xxx calls have already sent
3831 it. If outsize != -1 then it is returning */
3835 srv_signing_trans_stop();
3838 END_PROFILE(SMBtrans2);
3839 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);