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 int smb_read_error;
28 extern fstring local_machine;
29 extern int global_oplock_break;
30 extern uint32 global_client_caps;
31 extern struct current_user current_user;
33 #define get_file_size(sbuf) ((sbuf).st_size)
34 #define DIR_ENTRY_SAFETY_MARGIN 4096
36 /********************************************************************
37 Roundup a value to the nearest SMB_ROUNDUP_ALLOCATION_SIZE boundary.
38 Only do this for Windows clients.
39 ********************************************************************/
41 SMB_BIG_UINT smb_roundup(SMB_BIG_UINT val)
43 /* Only roundup for Windows clients. */
44 enum remote_arch_types ra_type = get_remote_arch();
45 if ((ra_type != RA_SAMBA) && (ra_type != RA_CIFSFS)) {
46 val = SMB_ROUNDUP(val,SMB_ROUNDUP_ALLOCATION_SIZE);
51 /********************************************************************
52 Given a stat buffer return the allocated size on disk, taking into
54 ********************************************************************/
56 SMB_BIG_UINT get_allocation_size(files_struct *fsp, SMB_STRUCT_STAT *sbuf)
60 #if defined(HAVE_STAT_ST_BLOCKS) && defined(STAT_ST_BLOCKSIZE)
61 ret = (SMB_BIG_UINT)STAT_ST_BLOCKSIZE * (SMB_BIG_UINT)sbuf->st_blocks;
63 ret = (SMB_BIG_UINT)get_file_size(*sbuf);
66 if (!ret && fsp && fsp->initial_allocation_size)
67 ret = fsp->initial_allocation_size;
69 ret = smb_roundup(ret);
74 /****************************************************************************
75 Utility functions for dealing with extended attributes.
76 ****************************************************************************/
78 static const char *prohibited_ea_names[] = {
79 SAMBA_POSIX_INHERITANCE_EA_NAME,
80 SAMBA_XATTR_DOS_ATTRIB,
84 /****************************************************************************
85 Refuse to allow clients to overwrite our private xattrs.
86 ****************************************************************************/
88 static BOOL samba_private_attr_name(const char *unix_ea_name)
92 for (i = 0; prohibited_ea_names[i]; i++) {
93 if (strequal( prohibited_ea_names[i], unix_ea_name))
100 struct ea_list *next, *prev;
104 /****************************************************************************
105 Get one EA value. Fill in a struct ea_struct.
106 ****************************************************************************/
108 static BOOL get_ea_value(TALLOC_CTX *mem_ctx, connection_struct *conn, files_struct *fsp,
109 const char *fname, char *ea_name, struct ea_struct *pea)
111 /* Get the value of this xattr. Max size is 64k. */
112 size_t attr_size = 256;
118 val = talloc_realloc(mem_ctx, val, attr_size);
123 if (fsp && fsp->fd != -1) {
124 sizeret = SMB_VFS_FGETXATTR(fsp, fsp->fd, ea_name, val, attr_size);
126 sizeret = SMB_VFS_GETXATTR(conn, fname, ea_name, val, attr_size);
129 if (sizeret == -1 && errno == ERANGE && attr_size != 65536) {
138 DEBUG(10,("get_ea_value: EA %s is of length %d: ", ea_name, sizeret));
139 dump_data(10, val, sizeret);
142 if (strnequal(ea_name, "user.", 5)) {
143 pea->name = &ea_name[5];
147 pea->value.data = val;
148 pea->value.length = (size_t)sizeret;
152 /****************************************************************************
153 Return a linked list of the total EA's. Plus the total size
154 ****************************************************************************/
156 static struct ea_list *get_ea_list(TALLOC_CTX *mem_ctx, connection_struct *conn, files_struct *fsp, const char *fname, size_t *pea_total_len)
158 /* Get a list of all xattrs. Max namesize is 64k. */
159 size_t ea_namelist_size = 1024;
164 struct ea_list *ea_list_head = NULL;
168 if (!lp_ea_support(SNUM(conn))) {
172 for (i = 0, ea_namelist = talloc(mem_ctx, ea_namelist_size); i < 6;
173 ea_namelist = talloc_realloc(mem_ctx, ea_namelist, ea_namelist_size), i++) {
174 if (fsp && fsp->fd != -1) {
175 sizeret = SMB_VFS_FLISTXATTR(fsp, fsp->fd, ea_namelist, ea_namelist_size);
177 sizeret = SMB_VFS_LISTXATTR(conn, fname, ea_namelist, ea_namelist_size);
180 if (sizeret == -1 && errno == ERANGE) {
181 ea_namelist_size *= 2;
190 DEBUG(10,("get_ea_list: ea_namelist size = %d\n", sizeret ));
193 for (p = ea_namelist; p - ea_namelist < sizeret; p += strlen(p) + 1) {
194 struct ea_list *listp, *tmp;
196 if (strnequal(p, "system.", 7) || samba_private_attr_name(p))
199 listp = talloc(mem_ctx, sizeof(struct ea_list));
203 if (!get_ea_value(mem_ctx, conn, fsp, fname, p, &listp->ea)) {
209 push_ascii_fstring(dos_ea_name, listp->ea.name);
210 *pea_total_len += 4 + strlen(dos_ea_name) + 1 + listp->ea.value.length;
211 DEBUG(10,("get_ea_list: total_len = %u, %s, val len = %u\n",
212 *pea_total_len, dos_ea_name,
213 (unsigned int)listp->ea.value.length ));
215 DLIST_ADD_END(ea_list_head, listp, tmp);
217 /* Add on 4 for total length. */
218 if (*pea_total_len) {
223 DEBUG(10,("get_ea_list: total_len = %u\n", *pea_total_len));
227 /****************************************************************************
228 Fill a qfilepathinfo buffer with EA's. Returns the length of the buffer
230 ****************************************************************************/
232 static unsigned int fill_ea_buffer(char *pdata, unsigned int total_data_size,
233 connection_struct *conn, files_struct *fsp, const char *fname)
235 unsigned int ret_data_size = 4;
239 struct ea_list *ea_list;
241 SMB_ASSERT(total_data_size >= 4);
244 if (!lp_ea_support(SNUM(conn))) {
247 mem_ctx = talloc_init("fill_ea_buffer");
252 ea_list = get_ea_list(mem_ctx, conn, fsp, fname, &total_ea_len);
254 talloc_destroy(mem_ctx);
258 if (total_ea_len > total_data_size) {
259 talloc_destroy(mem_ctx);
263 for (p = pdata + 4; ea_list; ea_list = ea_list->next) {
266 push_ascii_fstring(dos_ea_name, ea_list->ea.name);
267 dos_namelen = strlen(dos_ea_name);
268 if (dos_namelen > 255 || dos_namelen == 0) {
271 if (ea_list->ea.value.length > 65535) {
274 if (4 + dos_namelen + 1 + ea_list->ea.value.length > total_data_size) {
278 /* We know we have room. */
279 SCVAL(p,0,ea_list->ea.flags);
280 SCVAL(p,1,dos_namelen);
281 SSVAL(p,2,ea_list->ea.value.length);
282 fstrcpy(p+4, dos_ea_name);
283 memcpy( p + 4 + dos_namelen + 1, ea_list->ea.value.data, ea_list->ea.value.length);
285 total_data_size -= 4 + dos_namelen + 1 + ea_list->ea.value.length;
286 p += 4 + dos_namelen + 1 + ea_list->ea.value.length;
289 ret_data_size = PTR_DIFF(p, pdata);
290 DEBUG(10,("fill_ea_buffer: data_size = %u, total_ea_len = %u\n",
291 ret_data_size, total_ea_len ));
292 talloc_destroy(mem_ctx);
293 SIVAL(pdata,0,ret_data_size);
294 return ret_data_size;
297 static unsigned int estimate_ea_size(connection_struct *conn, files_struct *fsp, const char *fname)
299 size_t total_ea_len = 0;
300 TALLOC_CTX *mem_ctx = NULL;
302 if (!lp_ea_support(SNUM(conn))) {
305 mem_ctx = talloc_init("estimate_ea_size");
306 (void)get_ea_list(mem_ctx, conn, fsp, fname, &total_ea_len);
307 talloc_destroy(mem_ctx);
311 /****************************************************************************
312 Ensure the EA name is case insensitive by matching any existing EA name.
313 ****************************************************************************/
315 static void canonicalize_ea_name(connection_struct *conn, files_struct *fsp, const char *fname, fstring unix_ea_name)
318 TALLOC_CTX *mem_ctx = talloc_init("canonicalize_ea_name");
319 struct ea_list *ea_list = get_ea_list(mem_ctx, conn, fsp, fname, &total_ea_len);
321 for (; ea_list; ea_list = ea_list->next) {
322 if (strequal(&unix_ea_name[5], ea_list->ea.name)) {
323 DEBUG(10,("canonicalize_ea_name: %s -> %s\n",
324 &unix_ea_name[5], ea_list->ea.name));
325 safe_strcpy(&unix_ea_name[5], ea_list->ea.name, sizeof(fstring)-6);
329 talloc_destroy(mem_ctx);
332 /****************************************************************************
333 Set or delete an extended attribute.
334 ****************************************************************************/
336 static NTSTATUS set_ea(connection_struct *conn, files_struct *fsp, const char *fname,
337 char *pdata, int total_data)
339 unsigned int namelen;
342 fstring unix_ea_name;
344 if (!lp_ea_support(SNUM(conn))) {
345 return NT_STATUS_EAS_NOT_SUPPORTED;
348 if (total_data < 8) {
349 return NT_STATUS_INVALID_PARAMETER;
352 if (IVAL(pdata,0) > total_data) {
353 DEBUG(10,("set_ea: bad total data size (%u) > %u\n", IVAL(pdata,0), (unsigned int)total_data));
354 return NT_STATUS_INVALID_PARAMETER;
358 namelen = CVAL(pdata,1);
359 ealen = SVAL(pdata,2);
361 if (total_data < 8 + namelen + 1 + ealen) {
362 DEBUG(10,("set_ea: bad total data size (%u) < 8 + namelen (%u) + 1 + ealen (%u)\n",
363 (unsigned int)total_data, namelen, ealen));
364 return NT_STATUS_INVALID_PARAMETER;
367 if (pdata[namelen] != '\0') {
368 DEBUG(10,("set_ea: ea name not null terminated\n"));
369 return NT_STATUS_INVALID_PARAMETER;
372 fstrcpy(unix_ea_name, "user."); /* All EA's must start with user. */
373 pull_ascii(&unix_ea_name[5], pdata, sizeof(fstring) - 5, -1, STR_TERMINATE);
374 pdata += (namelen + 1);
376 canonicalize_ea_name(conn, fsp, fname, unix_ea_name);
378 DEBUG(10,("set_ea: ea_name %s ealen = %u\n", unix_ea_name, ealen));
380 DEBUG(10,("set_ea: data :\n"));
381 dump_data(10, pdata, ealen);
384 if (samba_private_attr_name(unix_ea_name)) {
385 DEBUG(10,("set_ea: ea name %s is a private Samba name.\n", unix_ea_name));
386 return NT_STATUS_ACCESS_DENIED;
390 /* Remove the attribute. */
391 if (fsp && (fsp->fd != -1)) {
392 DEBUG(10,("set_ea: deleting ea name %s on file %s by file descriptor.\n",
393 unix_ea_name, fsp->fsp_name));
394 ret = SMB_VFS_FREMOVEXATTR(fsp, fsp->fd, unix_ea_name);
396 DEBUG(10,("set_ea: deleting ea name %s on file %s.\n",
397 unix_ea_name, fname));
398 ret = SMB_VFS_REMOVEXATTR(conn, fname, unix_ea_name);
401 /* Removing a non existent attribute always succeeds. */
402 if (ret == -1 && errno == ENOATTR) {
403 DEBUG(10,("set_ea: deleting ea name %s didn't exist - succeeding by default.\n", unix_ea_name));
408 if (fsp && (fsp->fd != -1)) {
409 DEBUG(10,("set_ea: setting ea name %s on file %s by file descriptor.\n",
410 unix_ea_name, fsp->fsp_name));
411 ret = SMB_VFS_FSETXATTR(fsp, fsp->fd, unix_ea_name, pdata, ealen, 0);
413 DEBUG(10,("set_ea: setting ea name %s on file %s.\n",
414 unix_ea_name, fname));
415 ret = SMB_VFS_SETXATTR(conn, fname, unix_ea_name, pdata, ealen, 0);
421 if (errno == ENOTSUP) {
422 return NT_STATUS_EAS_NOT_SUPPORTED;
425 return map_nt_error_from_unix(errno);
431 /****************************************************************************
432 Send the required number of replies back.
433 We assume all fields other than the data fields are
434 set correctly for the type of call.
435 HACK ! Always assumes smb_setup field is zero.
436 ****************************************************************************/
438 static int send_trans2_replies(char *outbuf,
445 /* As we are using a protocol > LANMAN1 then the max_send
446 variable must have been set in the sessetupX call.
447 This takes precedence over the max_xmit field in the
448 global struct. These different max_xmit variables should
449 be merged as this is now too confusing */
452 int data_to_send = datasize;
453 int params_to_send = paramsize;
457 int params_sent_thistime, data_sent_thistime, total_sent_thistime;
458 int alignment_offset = 1; /* JRA. This used to be 3. Set to 1 to make netmon parse ok. */
459 int data_alignment_offset = 0;
461 /* Initially set the wcnt area to be 10 - this is true for all trans2 replies */
463 set_message(outbuf,10,0,True);
465 /* If there genuinely are no parameters or data to send just send the empty packet */
467 if(params_to_send == 0 && data_to_send == 0) {
468 if (!send_smb(smbd_server_fd(),outbuf))
469 exit_server("send_trans2_replies: send_smb failed.");
473 /* When sending params and data ensure that both are nicely aligned */
474 /* Only do this alignment when there is also data to send - else
475 can cause NT redirector problems. */
477 if (((params_to_send % 4) != 0) && (data_to_send != 0))
478 data_alignment_offset = 4 - (params_to_send % 4);
480 /* Space is bufsize minus Netbios over TCP header minus SMB header */
481 /* The alignment_offset is to align the param bytes on an even byte
482 boundary. NT 4.0 Beta needs this to work correctly. */
484 useable_space = bufsize - ((smb_buf(outbuf)+ alignment_offset+data_alignment_offset) - outbuf);
486 /* useable_space can never be more than max_send minus the alignment offset. */
488 useable_space = MIN(useable_space, max_send - (alignment_offset+data_alignment_offset));
490 while (params_to_send || data_to_send) {
491 /* Calculate whether we will totally or partially fill this packet */
493 total_sent_thistime = params_to_send + data_to_send + alignment_offset + data_alignment_offset;
495 /* We can never send more than useable_space */
497 * Note that 'useable_space' does not include the alignment offsets,
498 * but we must include the alignment offsets in the calculation of
499 * the length of the data we send over the wire, as the alignment offsets
500 * are sent here. Fix from Marc_Jacobsen@hp.com.
503 total_sent_thistime = MIN(total_sent_thistime, useable_space+ alignment_offset + data_alignment_offset);
505 set_message(outbuf, 10, total_sent_thistime, True);
507 /* Set total params and data to be sent */
508 SSVAL(outbuf,smb_tprcnt,paramsize);
509 SSVAL(outbuf,smb_tdrcnt,datasize);
511 /* Calculate how many parameters and data we can fit into
512 * this packet. Parameters get precedence
515 params_sent_thistime = MIN(params_to_send,useable_space);
516 data_sent_thistime = useable_space - params_sent_thistime;
517 data_sent_thistime = MIN(data_sent_thistime,data_to_send);
519 SSVAL(outbuf,smb_prcnt, params_sent_thistime);
521 /* smb_proff is the offset from the start of the SMB header to the
522 parameter bytes, however the first 4 bytes of outbuf are
523 the Netbios over TCP header. Thus use smb_base() to subtract
524 them from the calculation */
526 SSVAL(outbuf,smb_proff,((smb_buf(outbuf)+alignment_offset) - smb_base(outbuf)));
528 if(params_sent_thistime == 0)
529 SSVAL(outbuf,smb_prdisp,0);
531 /* Absolute displacement of param bytes sent in this packet */
532 SSVAL(outbuf,smb_prdisp,pp - params);
534 SSVAL(outbuf,smb_drcnt, data_sent_thistime);
535 if(data_sent_thistime == 0) {
536 SSVAL(outbuf,smb_droff,0);
537 SSVAL(outbuf,smb_drdisp, 0);
539 /* The offset of the data bytes is the offset of the
540 parameter bytes plus the number of parameters being sent this time */
541 SSVAL(outbuf,smb_droff,((smb_buf(outbuf)+alignment_offset) -
542 smb_base(outbuf)) + params_sent_thistime + data_alignment_offset);
543 SSVAL(outbuf,smb_drdisp, pd - pdata);
546 /* Copy the param bytes into the packet */
548 if(params_sent_thistime)
549 memcpy((smb_buf(outbuf)+alignment_offset),pp,params_sent_thistime);
551 /* Copy in the data bytes */
552 if(data_sent_thistime)
553 memcpy(smb_buf(outbuf)+alignment_offset+params_sent_thistime+
554 data_alignment_offset,pd,data_sent_thistime);
556 DEBUG(9,("t2_rep: params_sent_thistime = %d, data_sent_thistime = %d, useable_space = %d\n",
557 params_sent_thistime, data_sent_thistime, useable_space));
558 DEBUG(9,("t2_rep: params_to_send = %d, data_to_send = %d, paramsize = %d, datasize = %d\n",
559 params_to_send, data_to_send, paramsize, datasize));
561 /* Send the packet */
562 if (!send_smb(smbd_server_fd(),outbuf))
563 exit_server("send_trans2_replies: send_smb failed.");
565 pp += params_sent_thistime;
566 pd += data_sent_thistime;
568 params_to_send -= params_sent_thistime;
569 data_to_send -= data_sent_thistime;
572 if(params_to_send < 0 || data_to_send < 0) {
573 DEBUG(0,("send_trans2_replies failed sanity check pts = %d, dts = %d\n!!!",
574 params_to_send, data_to_send));
582 /****************************************************************************
583 Reply to a TRANSACT2_OPEN.
584 ****************************************************************************/
586 static int call_trans2open(connection_struct *conn, char *inbuf, char *outbuf, int bufsize,
587 char **pparams, int total_params, char **ppdata, int total_data)
589 char *params = *pparams;
594 BOOL return_additional_info;
603 int fmode=0,mtime=0,rmode;
605 SMB_STRUCT_STAT sbuf;
607 BOOL bad_path = False;
612 * Ensure we have enough parameters to perform the operation.
615 if (total_params < 29)
616 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
618 open_mode = SVAL(params, 2);
619 open_attr = SVAL(params,6);
620 oplock_request = (((SVAL(params,0)|(1<<1))>>1) | ((SVAL(params,0)|(1<<2))>>1));
622 return_additional_info = BITSETW(params,0);
623 open_sattr = SVAL(params, 4);
624 open_time = make_unix_date3(params+8);
626 open_ofun = SVAL(params,12);
627 open_size = IVAL(params,14);
631 return(ERROR_DOS(ERRSRV,ERRaccess));
633 srvstr_get_path(inbuf, fname, pname, sizeof(fname), -1, STR_TERMINATE, &status, False);
634 if (!NT_STATUS_IS_OK(status)) {
635 return ERROR_NT(status);
638 DEBUG(3,("trans2open %s mode=%d attr=%d ofun=%d size=%d\n",
639 fname,open_mode, open_attr, open_ofun, open_size));
641 /* XXXX we need to handle passed times, sattr and flags */
643 unix_convert(fname,conn,0,&bad_path,&sbuf);
645 return ERROR_NT(NT_STATUS_OBJECT_PATH_NOT_FOUND);
648 if (!check_name(fname,conn)) {
649 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRnoaccess);
652 fsp = open_file_shared(conn,fname,&sbuf,open_mode,open_ofun,(uint32)open_attr,
653 oplock_request, &rmode,&smb_action);
656 if (open_was_deferred(SVAL(inbuf,smb_mid))) {
657 /* We have re-scheduled this call. */
658 clear_cached_errors();
661 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRnoaccess);
664 size = get_file_size(sbuf);
665 fmode = dos_mode(conn,fname,&sbuf);
666 mtime = sbuf.st_mtime;
669 close_file(fsp,False);
670 return(ERROR_DOS(ERRDOS,ERRnoaccess));
673 /* Realloc the size of parameters and data we will return */
674 params = Realloc(*pparams, 28);
676 return(ERROR_DOS(ERRDOS,ERRnomem));
679 memset((char *)params,'\0',28);
680 SSVAL(params,0,fsp->fnum);
681 SSVAL(params,2,fmode);
682 put_dos_date2(params,4, mtime);
683 SIVAL(params,8, (uint32)size);
684 SSVAL(params,12,rmode);
686 if (oplock_request && lp_fake_oplocks(SNUM(conn)))
687 smb_action |= EXTENDED_OPLOCK_GRANTED;
689 SSVAL(params,18,smb_action);
692 * WARNING - this may need to be changed if SMB_INO_T <> 4 bytes.
694 SIVAL(params,20,inode);
696 /* Send the required number of replies */
697 send_trans2_replies(outbuf, bufsize, params, 28, *ppdata, 0);
702 /*********************************************************
703 Routine to check if a given string matches exactly.
704 as a special case a mask of "." does NOT match. That
705 is required for correct wildcard semantics
706 Case can be significant or not.
707 **********************************************************/
709 static BOOL exact_match(char *str,char *mask, BOOL case_sig)
711 if (mask[0] == '.' && mask[1] == 0)
714 return strcmp(str,mask)==0;
715 if (StrCaseCmp(str,mask) != 0) {
718 if (ms_has_wild(str)) {
724 /****************************************************************************
725 Return the filetype for UNIX extensions.
726 ****************************************************************************/
728 static uint32 unix_filetype(mode_t mode)
731 return UNIX_TYPE_FILE;
732 else if(S_ISDIR(mode))
733 return UNIX_TYPE_DIR;
735 else if(S_ISLNK(mode))
736 return UNIX_TYPE_SYMLINK;
739 else if(S_ISCHR(mode))
740 return UNIX_TYPE_CHARDEV;
743 else if(S_ISBLK(mode))
744 return UNIX_TYPE_BLKDEV;
747 else if(S_ISFIFO(mode))
748 return UNIX_TYPE_FIFO;
751 else if(S_ISSOCK(mode))
752 return UNIX_TYPE_SOCKET;
755 DEBUG(0,("unix_filetype: unknown filetype %u", (unsigned)mode));
756 return UNIX_TYPE_UNKNOWN;
759 /****************************************************************************
760 Map wire perms onto standard UNIX permissions. Obey share restrictions.
761 ****************************************************************************/
763 static mode_t unix_perms_from_wire( connection_struct *conn, SMB_STRUCT_STAT *pst, uint32 perms)
767 if (perms == SMB_MODE_NO_CHANGE)
770 ret |= ((perms & UNIX_X_OTH ) ? S_IXOTH : 0);
771 ret |= ((perms & UNIX_W_OTH ) ? S_IWOTH : 0);
772 ret |= ((perms & UNIX_R_OTH ) ? S_IROTH : 0);
773 ret |= ((perms & UNIX_X_GRP ) ? S_IXGRP : 0);
774 ret |= ((perms & UNIX_W_GRP ) ? S_IWGRP : 0);
775 ret |= ((perms & UNIX_R_GRP ) ? S_IRGRP : 0);
776 ret |= ((perms & UNIX_X_USR ) ? S_IXUSR : 0);
777 ret |= ((perms & UNIX_W_USR ) ? S_IWUSR : 0);
778 ret |= ((perms & UNIX_R_USR ) ? S_IRUSR : 0);
780 ret |= ((perms & UNIX_STICKY ) ? S_ISVTX : 0);
783 ret |= ((perms & UNIX_SET_GID ) ? S_ISGID : 0);
786 ret |= ((perms & UNIX_SET_UID ) ? S_ISUID : 0);
789 if (VALID_STAT(*pst) && S_ISDIR(pst->st_mode)) {
790 ret &= lp_dir_mask(SNUM(conn));
791 /* Add in force bits */
792 ret |= lp_force_dir_mode(SNUM(conn));
794 /* Apply mode mask */
795 ret &= lp_create_mask(SNUM(conn));
796 /* Add in force bits */
797 ret |= lp_force_create_mode(SNUM(conn));
803 /****************************************************************************
804 Checks for SMB_TIME_NO_CHANGE and if not found calls interpret_long_date.
805 ****************************************************************************/
807 time_t interpret_long_unix_date(char *p)
809 DEBUG(10,("interpret_long_unix_date\n"));
810 if(IVAL(p,0) == SMB_TIME_NO_CHANGE_LO &&
811 IVAL(p,4) == SMB_TIME_NO_CHANGE_HI) {
814 return interpret_long_date(p);
818 /****************************************************************************
819 Get a level dependent lanman2 dir entry.
820 ****************************************************************************/
822 static BOOL get_lanman2_dir_entry(connection_struct *conn,
823 void *inbuf, void *outbuf,
824 char *path_mask,int dirtype,int info_level,
825 int requires_resume_key,
826 BOOL dont_descend,char **ppdata,
827 char *base_data, int space_remaining,
828 BOOL *out_of_space, BOOL *got_exact_match,
833 SMB_STRUCT_STAT sbuf;
837 char *p, *q, *pdata = *ppdata;
841 SMB_OFF_T file_size = 0;
842 SMB_BIG_UINT allocation_size = 0;
844 time_t mdate=0, adate=0, cdate=0;
847 int nt_extmode; /* Used for NT connections instead of mode */
848 BOOL needslash = ( conn->dirpath[strlen(conn->dirpath) -1] != '/');
851 *out_of_space = False;
852 *got_exact_match = False;
857 p = strrchr_m(path_mask,'/');
864 pstrcpy(mask, path_mask);
869 /* Needed if we run out of space */
870 prev_dirpos = TellDir(conn->dirptr);
871 dname = ReadDirName(conn->dirptr);
874 * Due to bugs in NT client redirectors we are not using
875 * resume keys any more - set them to zero.
876 * Check out the related comments in findfirst/findnext.
882 DEBUG(8,("get_lanman2_dir_entry:readdir on dirptr 0x%lx now at offset %d\n",
883 (long)conn->dirptr,TellDir(conn->dirptr)));
888 pstrcpy(fname,dname);
890 if(!(got_match = *got_exact_match = exact_match(fname, mask, conn->case_sensitive)))
891 got_match = mask_match(fname, mask, conn->case_sensitive);
893 if(!got_match && !mangle_is_8_3(fname, False)) {
896 * It turns out that NT matches wildcards against
897 * both long *and* short names. This may explain some
898 * of the wildcard wierdness from old DOS clients
899 * that some people have been seeing.... JRA.
903 pstrcpy( newname, fname);
904 mangle_map( newname, True, False, SNUM(conn));
905 if(!(got_match = *got_exact_match = exact_match(newname, mask, conn->case_sensitive)))
906 got_match = mask_match(newname, mask, conn->case_sensitive);
910 BOOL isdots = (strequal(fname,"..") || strequal(fname,"."));
911 if (dont_descend && !isdots)
914 pstrcpy(pathreal,conn->dirpath);
916 pstrcat(pathreal,"/");
917 pstrcat(pathreal,dname);
919 if (INFO_LEVEL_IS_UNIX(info_level)) {
920 if (SMB_VFS_LSTAT(conn,pathreal,&sbuf) != 0) {
921 DEBUG(5,("get_lanman2_dir_entry:Couldn't lstat [%s] (%s)\n",
922 pathreal,strerror(errno)));
925 } else if (SMB_VFS_STAT(conn,pathreal,&sbuf) != 0) {
927 /* Needed to show the msdfs symlinks as
930 if(lp_host_msdfs() &&
931 lp_msdfs_root(SNUM(conn)) &&
932 is_msdfs_link(conn, pathreal, NULL, NULL,
935 DEBUG(5,("get_lanman2_dir_entry: Masquerading msdfs link %s as a directory\n", pathreal));
936 sbuf.st_mode = (sbuf.st_mode & 0xFFF) | S_IFDIR;
940 DEBUG(5,("get_lanman2_dir_entry:Couldn't stat [%s] (%s)\n",
941 pathreal,strerror(errno)));
946 mode = dos_mode(conn,pathreal,&sbuf);
948 if (!dir_check_ftype(conn,mode,&sbuf,dirtype)) {
949 DEBUG(5,("[%s] attribs didn't match %x\n",fname,dirtype));
953 file_size = get_file_size(sbuf);
954 allocation_size = get_allocation_size(NULL,&sbuf);
955 mdate = sbuf.st_mtime;
956 adate = sbuf.st_atime;
957 cdate = get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(conn)));
959 if (lp_dos_filetime_resolution(SNUM(conn))) {
968 DEBUG(5,("get_lanman2_dir_entry found %s fname=%s\n",pathreal,fname));
974 mangle_map(fname,False,True,SNUM(conn));
979 nt_extmode = mode ? mode : FILE_ATTRIBUTE_NORMAL;
981 switch (info_level) {
982 case SMB_INFO_STANDARD:
983 DEBUG(10,("get_lanman2_dir_entry: SMB_INFO_STANDARD\n"));
984 if(requires_resume_key) {
988 put_dos_date2(p,l1_fdateCreation,cdate);
989 put_dos_date2(p,l1_fdateLastAccess,adate);
990 put_dos_date2(p,l1_fdateLastWrite,mdate);
991 SIVAL(p,l1_cbFile,(uint32)file_size);
992 SIVAL(p,l1_cbFileAlloc,(uint32)allocation_size);
993 SSVAL(p,l1_attrFile,mode);
996 p += align_string(outbuf, p, 0);
997 len = srvstr_push(outbuf, p, fname, -1, STR_TERMINATE);
998 if (SVAL(outbuf, smb_flg2) & FLAGS2_UNICODE_STRINGS) {
1000 SCVAL(nameptr, -1, len - 2);
1002 SCVAL(nameptr, -1, 0);
1006 SCVAL(nameptr, -1, len - 1);
1008 SCVAL(nameptr, -1, 0);
1014 case SMB_INFO_QUERY_EA_SIZE:
1015 DEBUG(10,("get_lanman2_dir_entry: SMB_INFO_QUERY_EA_SIZE\n"));
1016 if(requires_resume_key) {
1020 put_dos_date2(p,l2_fdateCreation,cdate);
1021 put_dos_date2(p,l2_fdateLastAccess,adate);
1022 put_dos_date2(p,l2_fdateLastWrite,mdate);
1023 SIVAL(p,l2_cbFile,(uint32)file_size);
1024 SIVAL(p,l2_cbFileAlloc,(uint32)allocation_size);
1025 SSVAL(p,l2_attrFile,mode);
1027 unsigned int ea_size = estimate_ea_size(conn, NULL, pathreal);
1028 SIVAL(p,l2_cbList,ea_size); /* Extended attributes */
1032 len = srvstr_push(outbuf, p, fname, -1, STR_TERMINATE | STR_NOALIGN);
1033 if (SVAL(outbuf, smb_flg2) & FLAGS2_UNICODE_STRINGS) {
1046 SCVAL(nameptr,0,len);
1048 SCVAL(p,0,0); p += 1; /* Extra zero byte ? - why.. */
1051 case SMB_FIND_FILE_BOTH_DIRECTORY_INFO:
1052 DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_FILE_BOTH_DIRECTORY_INFO\n"));
1053 was_8_3 = mangle_is_8_3(fname, True);
1055 SIVAL(p,0,reskey); p += 4;
1056 put_long_date(p,cdate); p += 8;
1057 put_long_date(p,adate); p += 8;
1058 put_long_date(p,mdate); p += 8;
1059 put_long_date(p,mdate); p += 8;
1060 SOFF_T(p,0,file_size); p += 8;
1061 SOFF_T(p,0,allocation_size); p += 8;
1062 SIVAL(p,0,nt_extmode); p += 4;
1063 q = p; p += 4; /* q is placeholder for name length. */
1065 unsigned int ea_size = estimate_ea_size(conn, NULL, pathreal);
1066 SIVAL(p,0,ea_size); /* Extended attributes */
1069 /* Clear the short name buffer. This is
1070 * IMPORTANT as not doing so will trigger
1071 * a Win2k client bug. JRA.
1074 if (!was_8_3 && lp_manglednames(SNUM(conn))) {
1075 pstring mangled_name;
1076 pstrcpy(mangled_name, fname);
1077 mangle_map(mangled_name,True,True,SNUM(conn));
1078 mangled_name[12] = 0;
1079 len = srvstr_push(outbuf, p+2, mangled_name, 24, STR_UPPER|STR_UNICODE);
1086 len = srvstr_push(outbuf, p, fname, -1, STR_TERMINATE_ASCII);
1089 len = PTR_DIFF(p, pdata);
1090 len = (len + 3) & ~3;
1095 case SMB_FIND_FILE_DIRECTORY_INFO:
1096 DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_FILE_DIRECTORY_INFO\n"));
1098 SIVAL(p,0,reskey); p += 4;
1099 put_long_date(p,cdate); p += 8;
1100 put_long_date(p,adate); p += 8;
1101 put_long_date(p,mdate); p += 8;
1102 put_long_date(p,mdate); p += 8;
1103 SOFF_T(p,0,file_size); p += 8;
1104 SOFF_T(p,0,allocation_size); p += 8;
1105 SIVAL(p,0,nt_extmode); p += 4;
1106 len = srvstr_push(outbuf, p + 4, fname, -1, STR_TERMINATE_ASCII);
1109 len = PTR_DIFF(p, pdata);
1110 len = (len + 3) & ~3;
1115 case SMB_FIND_FILE_FULL_DIRECTORY_INFO:
1116 DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_FILE_FULL_DIRECTORY_INFO\n"));
1118 SIVAL(p,0,reskey); p += 4;
1119 put_long_date(p,cdate); p += 8;
1120 put_long_date(p,adate); p += 8;
1121 put_long_date(p,mdate); p += 8;
1122 put_long_date(p,mdate); p += 8;
1123 SOFF_T(p,0,file_size); p += 8;
1124 SOFF_T(p,0,allocation_size); p += 8;
1125 SIVAL(p,0,nt_extmode); p += 4;
1126 q = p; p += 4; /* q is placeholder for name length. */
1128 unsigned int ea_size = estimate_ea_size(conn, NULL, pathreal);
1129 SIVAL(p,0,ea_size); /* Extended attributes */
1132 len = srvstr_push(outbuf, p, fname, -1, STR_TERMINATE_ASCII);
1136 len = PTR_DIFF(p, pdata);
1137 len = (len + 3) & ~3;
1142 case SMB_FIND_FILE_NAMES_INFO:
1143 DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_FILE_NAMES_INFO\n"));
1145 SIVAL(p,0,reskey); p += 4;
1147 /* this must *not* be null terminated or w2k gets in a loop trying to set an
1148 acl on a dir (tridge) */
1149 len = srvstr_push(outbuf, p, fname, -1, STR_TERMINATE_ASCII);
1152 len = PTR_DIFF(p, pdata);
1153 len = (len + 3) & ~3;
1158 case SMB_FIND_ID_FULL_DIRECTORY_INFO:
1159 DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_ID_FULL_DIRECTORY_INFO\n"));
1161 SIVAL(p,0,reskey); p += 4;
1162 put_long_date(p,cdate); p += 8;
1163 put_long_date(p,adate); p += 8;
1164 put_long_date(p,mdate); p += 8;
1165 put_long_date(p,mdate); p += 8;
1166 SOFF_T(p,0,file_size); p += 8;
1167 SOFF_T(p,0,allocation_size); p += 8;
1168 SIVAL(p,0,nt_extmode); p += 4;
1169 q = p; p += 4; /* q is placeholder for name length. */
1171 unsigned int ea_size = estimate_ea_size(conn, NULL, pathreal);
1172 SIVAL(p,0,ea_size); /* Extended attributes */
1175 SIVAL(p,0,0); p += 4; /* Unknown - reserved ? */
1176 SIVAL(p,0,sbuf.st_dev); p += 4;
1177 SIVAL(p,0,sbuf.st_ino); p += 4;
1178 len = srvstr_push(outbuf, p, fname, -1, STR_TERMINATE_ASCII);
1181 len = PTR_DIFF(p, pdata);
1182 len = (len + 3) & ~3;
1187 case SMB_FIND_ID_BOTH_DIRECTORY_INFO:
1188 DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_ID_BOTH_DIRECTORY_INFO\n"));
1189 was_8_3 = mangle_is_8_3(fname, True);
1191 SIVAL(p,0,reskey); p += 4;
1192 put_long_date(p,cdate); p += 8;
1193 put_long_date(p,adate); p += 8;
1194 put_long_date(p,mdate); p += 8;
1195 put_long_date(p,mdate); p += 8;
1196 SOFF_T(p,0,file_size); p += 8;
1197 SOFF_T(p,0,allocation_size); p += 8;
1198 SIVAL(p,0,nt_extmode); p += 4;
1199 q = p; p += 4; /* q is placeholder for name length */
1201 unsigned int ea_size = estimate_ea_size(conn, NULL, pathreal);
1202 SIVAL(p,0,ea_size); /* Extended attributes */
1205 /* Clear the short name buffer. This is
1206 * IMPORTANT as not doing so will trigger
1207 * a Win2k client bug. JRA.
1210 if (!was_8_3 && lp_manglednames(SNUM(conn))) {
1211 pstring mangled_name;
1212 pstrcpy(mangled_name, fname);
1213 mangle_map(mangled_name,True,True,SNUM(conn));
1214 mangled_name[12] = 0;
1215 len = srvstr_push(outbuf, p+2, mangled_name, 24, STR_UPPER|STR_UNICODE);
1222 SSVAL(p,0,0); p += 2; /* Reserved ? */
1223 SIVAL(p,0,sbuf.st_dev); p += 4;
1224 SIVAL(p,0,sbuf.st_ino); p += 4;
1225 len = srvstr_push(outbuf, p, fname, -1, STR_TERMINATE_ASCII);
1228 len = PTR_DIFF(p, pdata);
1229 len = (len + 3) & ~3;
1234 /* CIFS UNIX Extension. */
1236 case SMB_FIND_FILE_UNIX:
1237 DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_FILE_UNIX\n"));
1239 SIVAL(p,0,reskey); p+= 4; /* Used for continuing search. */
1241 /* Begin of SMB_QUERY_FILE_UNIX_BASIC */
1242 SOFF_T(p,0,get_file_size(sbuf)); /* File size 64 Bit */
1245 SOFF_T(p,0,get_allocation_size(NULL,&sbuf)); /* Number of bytes used on disk - 64 Bit */
1248 put_long_date(p,sbuf.st_ctime); /* Inode change Time 64 Bit */
1249 put_long_date(p+8,sbuf.st_atime); /* Last access time 64 Bit */
1250 put_long_date(p+16,sbuf.st_mtime); /* Last modification time 64 Bit */
1253 SIVAL(p,0,sbuf.st_uid); /* user id for the owner */
1257 SIVAL(p,0,sbuf.st_gid); /* group id of owner */
1261 SIVAL(p,0,unix_filetype(sbuf.st_mode));
1264 SIVAL(p,0,unix_dev_major(sbuf.st_rdev)); /* Major device number if type is device */
1268 SIVAL(p,0,unix_dev_minor(sbuf.st_rdev)); /* Minor device number if type is device */
1272 SINO_T(p,0,(SMB_INO_T)sbuf.st_ino); /* inode number */
1275 SIVAL(p,0, unix_perms_to_wire(sbuf.st_mode)); /* Standard UNIX file permissions */
1279 SIVAL(p,0,sbuf.st_nlink); /* number of hard links */
1283 len = srvstr_push(outbuf, p, fname, -1, STR_TERMINATE);
1286 len = PTR_DIFF(p, pdata);
1287 len = (len + 3) & ~3;
1288 SIVAL(pdata,0,len); /* Offset from this structure to the beginning of the next one */
1290 /* End of SMB_QUERY_FILE_UNIX_BASIC */
1299 if (PTR_DIFF(p,pdata) > space_remaining) {
1300 /* Move the dirptr back to prev_dirpos */
1301 SeekDir(conn->dirptr, prev_dirpos);
1302 *out_of_space = True;
1303 DEBUG(9,("get_lanman2_dir_entry: out of space\n"));
1304 return False; /* Not finished - just out of space */
1307 /* Setup the last_filename pointer, as an offset from base_data */
1308 *last_name_off = PTR_DIFF(nameptr,base_data);
1309 /* Advance the data pointer to the next slot */
1315 /****************************************************************************
1316 Reply to a TRANS2_FINDFIRST.
1317 ****************************************************************************/
1319 static int call_trans2findfirst(connection_struct *conn, char *inbuf, char *outbuf, int bufsize,
1320 char **pparams, int total_params, char **ppdata, int total_data)
1322 /* We must be careful here that we don't return more than the
1323 allowed number of data bytes. If this means returning fewer than
1324 maxentries then so be it. We assume that the redirector has
1325 enough room for the fixed number of parameter bytes it has
1327 uint32 max_data_bytes = SVAL(inbuf, smb_mdrcnt);
1328 char *params = *pparams;
1329 char *pdata = *ppdata;
1330 int dirtype = SVAL(params,0);
1331 int maxentries = SVAL(params,2);
1332 uint16 findfirst_flags = SVAL(params,4);
1333 BOOL close_after_first = (findfirst_flags & FLAG_TRANS2_FIND_CLOSE);
1334 BOOL close_if_end = (findfirst_flags & FLAG_TRANS2_FIND_CLOSE_IF_END);
1335 BOOL requires_resume_key = (findfirst_flags & FLAG_TRANS2_FIND_REQUIRE_RESUME);
1336 int info_level = SVAL(params,6);
1340 int last_name_off=0;
1344 BOOL finished = False;
1345 BOOL dont_descend = False;
1346 BOOL out_of_space = False;
1347 int space_remaining;
1348 BOOL bad_path = False;
1349 SMB_STRUCT_STAT sbuf;
1350 NTSTATUS ntstatus = NT_STATUS_OK;
1352 if (total_params < 12)
1353 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
1355 *directory = *mask = 0;
1357 DEBUG(3,("call_trans2findfirst: dirtype = %d, maxentries = %d, close_after_first=%d, \
1358 close_if_end = %d requires_resume_key = %d level = 0x%x, max_data_bytes = %d\n",
1359 dirtype, maxentries, close_after_first, close_if_end, requires_resume_key,
1360 info_level, max_data_bytes));
1363 /* W2K3 seems to treat zero as 1. */
1367 switch (info_level) {
1368 case SMB_INFO_STANDARD:
1369 case SMB_INFO_QUERY_EA_SIZE:
1370 case SMB_FIND_FILE_DIRECTORY_INFO:
1371 case SMB_FIND_FILE_FULL_DIRECTORY_INFO:
1372 case SMB_FIND_FILE_NAMES_INFO:
1373 case SMB_FIND_FILE_BOTH_DIRECTORY_INFO:
1374 case SMB_FIND_ID_FULL_DIRECTORY_INFO:
1375 case SMB_FIND_ID_BOTH_DIRECTORY_INFO:
1377 case SMB_FIND_FILE_UNIX:
1378 if (!lp_unix_extensions())
1379 return(ERROR_DOS(ERRDOS,ERRunknownlevel));
1382 return(ERROR_DOS(ERRDOS,ERRunknownlevel));
1385 srvstr_get_path(inbuf, directory, params+12, sizeof(directory), -1, STR_TERMINATE, &ntstatus, True);
1386 if (!NT_STATUS_IS_OK(ntstatus)) {
1387 return ERROR_NT(ntstatus);
1390 RESOLVE_FINDFIRST_DFSPATH(directory, conn, inbuf, outbuf);
1392 unix_convert(directory,conn,0,&bad_path,&sbuf);
1394 return ERROR_NT(NT_STATUS_OBJECT_PATH_NOT_FOUND);
1396 if(!check_name(directory,conn)) {
1397 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRbadpath);
1400 p = strrchr_m(directory,'/');
1402 /* Windows and OS/2 systems treat search on the root '\' as if it were '\*' */
1403 if((directory[0] == '.') && (directory[1] == '\0'))
1406 pstrcpy(mask,directory);
1407 pstrcpy(directory,"./");
1413 DEBUG(5,("dir=%s, mask = %s\n",directory, mask));
1415 pdata = Realloc(*ppdata, max_data_bytes + DIR_ENTRY_SAFETY_MARGIN);
1417 return(ERROR_DOS(ERRDOS,ERRnomem));
1420 memset((char *)pdata,'\0',max_data_bytes + DIR_ENTRY_SAFETY_MARGIN);
1422 /* Realloc the params space */
1423 params = Realloc(*pparams, 10);
1425 return ERROR_DOS(ERRDOS,ERRnomem);
1428 dptr_num = dptr_create(conn,directory, False, True ,SVAL(inbuf,smb_pid));
1430 return(UNIXERROR(ERRDOS,ERRbadfile));
1432 /* Save the wildcard match and attribs we are using on this directory -
1433 needed as lanman2 assumes these are being saved between calls */
1435 if(!(wcard = strdup(mask))) {
1436 dptr_close(&dptr_num);
1437 return ERROR_DOS(ERRDOS,ERRnomem);
1440 dptr_set_wcard(dptr_num, wcard);
1441 dptr_set_attr(dptr_num, dirtype);
1443 DEBUG(4,("dptr_num is %d, wcard = %s, attr = %d\n",dptr_num, wcard, dirtype));
1445 /* We don't need to check for VOL here as this is returned by
1446 a different TRANS2 call. */
1448 DEBUG(8,("dirpath=<%s> dontdescend=<%s>\n", conn->dirpath,lp_dontdescend(SNUM(conn))));
1449 if (in_list(conn->dirpath,lp_dontdescend(SNUM(conn)),conn->case_sensitive))
1450 dont_descend = True;
1453 space_remaining = max_data_bytes;
1454 out_of_space = False;
1456 for (i=0;(i<maxentries) && !finished && !out_of_space;i++) {
1457 BOOL got_exact_match = False;
1459 /* this is a heuristic to avoid seeking the dirptr except when
1460 absolutely necessary. It allows for a filename of about 40 chars */
1461 if (space_remaining < DIRLEN_GUESS && numentries > 0) {
1462 out_of_space = True;
1465 finished = !get_lanman2_dir_entry(conn,
1467 mask,dirtype,info_level,
1468 requires_resume_key,dont_descend,
1469 &p,pdata,space_remaining, &out_of_space, &got_exact_match,
1473 if (finished && out_of_space)
1476 if (!finished && !out_of_space)
1480 * As an optimisation if we know we aren't looking
1481 * for a wildcard name (ie. the name matches the wildcard exactly)
1482 * then we can finish on any (first) match.
1483 * This speeds up large directory searches. JRA.
1489 space_remaining = max_data_bytes - PTR_DIFF(p,pdata);
1492 /* Check if we can close the dirptr */
1493 if(close_after_first || (finished && close_if_end)) {
1494 DEBUG(5,("call_trans2findfirst - (2) closing dptr_num %d\n", dptr_num));
1495 dptr_close(&dptr_num);
1499 * If there are no matching entries we must return ERRDOS/ERRbadfile -
1500 * from observation of NT.
1503 if(numentries == 0) {
1504 dptr_close(&dptr_num);
1505 return ERROR_DOS(ERRDOS,ERRbadfile);
1508 /* At this point pdata points to numentries directory entries. */
1510 /* Set up the return parameter block */
1511 SSVAL(params,0,dptr_num);
1512 SSVAL(params,2,numentries);
1513 SSVAL(params,4,finished);
1514 SSVAL(params,6,0); /* Never an EA error */
1515 SSVAL(params,8,last_name_off);
1517 send_trans2_replies( outbuf, bufsize, params, 10, pdata, PTR_DIFF(p,pdata));
1519 if ((! *directory) && dptr_path(dptr_num))
1520 slprintf(directory,sizeof(directory)-1, "(%s)",dptr_path(dptr_num));
1522 DEBUG( 4, ( "%s mask=%s directory=%s dirtype=%d numentries=%d\n",
1523 smb_fn_name(CVAL(inbuf,smb_com)),
1524 mask, directory, dirtype, numentries ) );
1527 * Force a name mangle here to ensure that the
1528 * mask as an 8.3 name is top of the mangled cache.
1529 * The reasons for this are subtle. Don't remove
1530 * this code unless you know what you are doing
1531 * (see PR#13758). JRA.
1534 if(!mangle_is_8_3_wildcards( mask, False))
1535 mangle_map(mask, True, True, SNUM(conn));
1540 /****************************************************************************
1541 Reply to a TRANS2_FINDNEXT.
1542 ****************************************************************************/
1544 static int call_trans2findnext(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize,
1545 char **pparams, int total_params, char **ppdata, int total_data)
1547 /* We must be careful here that we don't return more than the
1548 allowed number of data bytes. If this means returning fewer than
1549 maxentries then so be it. We assume that the redirector has
1550 enough room for the fixed number of parameter bytes it has
1552 int max_data_bytes = SVAL(inbuf, smb_mdrcnt);
1553 char *params = *pparams;
1554 char *pdata = *ppdata;
1555 int dptr_num = SVAL(params,0);
1556 int maxentries = SVAL(params,2);
1557 uint16 info_level = SVAL(params,4);
1558 uint32 resume_key = IVAL(params,6);
1559 uint16 findnext_flags = SVAL(params,10);
1560 BOOL close_after_request = (findnext_flags & FLAG_TRANS2_FIND_CLOSE);
1561 BOOL close_if_end = (findnext_flags & FLAG_TRANS2_FIND_CLOSE_IF_END);
1562 BOOL requires_resume_key = (findnext_flags & FLAG_TRANS2_FIND_REQUIRE_RESUME);
1563 BOOL continue_bit = (findnext_flags & FLAG_TRANS2_FIND_CONTINUE);
1564 pstring resume_name;
1570 int i, last_name_off=0;
1571 BOOL finished = False;
1572 BOOL dont_descend = False;
1573 BOOL out_of_space = False;
1574 int space_remaining;
1575 NTSTATUS ntstatus = NT_STATUS_OK;
1577 if (total_params < 12)
1578 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
1580 *mask = *directory = *resume_name = 0;
1582 srvstr_get_path(inbuf, resume_name, params+12, sizeof(resume_name), -1, STR_TERMINATE, &ntstatus, True);
1583 if (!NT_STATUS_IS_OK(ntstatus)) {
1584 return ERROR_NT(ntstatus);
1587 DEBUG(3,("call_trans2findnext: dirhandle = %d, max_data_bytes = %d, maxentries = %d, \
1588 close_after_request=%d, close_if_end = %d requires_resume_key = %d \
1589 resume_key = %d resume name = %s continue=%d level = %d\n",
1590 dptr_num, max_data_bytes, maxentries, close_after_request, close_if_end,
1591 requires_resume_key, resume_key, resume_name, continue_bit, info_level));
1594 /* W2K3 seems to treat zero as 1. */
1598 switch (info_level) {
1599 case SMB_INFO_STANDARD:
1600 case SMB_INFO_QUERY_EA_SIZE:
1601 case SMB_FIND_FILE_DIRECTORY_INFO:
1602 case SMB_FIND_FILE_FULL_DIRECTORY_INFO:
1603 case SMB_FIND_FILE_NAMES_INFO:
1604 case SMB_FIND_FILE_BOTH_DIRECTORY_INFO:
1606 case SMB_FIND_FILE_UNIX:
1607 if (!lp_unix_extensions())
1608 return(ERROR_DOS(ERRDOS,ERRunknownlevel));
1611 return ERROR_DOS(ERRDOS,ERRunknownlevel);
1614 pdata = Realloc( *ppdata, max_data_bytes + DIR_ENTRY_SAFETY_MARGIN);
1616 return ERROR_DOS(ERRDOS,ERRnomem);
1619 memset((char *)pdata,'\0',max_data_bytes + DIR_ENTRY_SAFETY_MARGIN);
1621 /* Realloc the params space */
1622 params = Realloc(*pparams, 6*SIZEOFWORD);
1623 if( params == NULL )
1624 return ERROR_DOS(ERRDOS,ERRnomem);
1628 /* Check that the dptr is valid */
1629 if(!(conn->dirptr = dptr_fetch_lanman2(dptr_num)))
1630 return ERROR_DOS(ERRDOS,ERRnofiles);
1632 string_set(&conn->dirpath,dptr_path(dptr_num));
1634 /* Get the wildcard mask from the dptr */
1635 if((p = dptr_wcard(dptr_num))== NULL) {
1636 DEBUG(2,("dptr_num %d has no wildcard\n", dptr_num));
1637 return ERROR_DOS(ERRDOS,ERRnofiles);
1641 pstrcpy(directory,conn->dirpath);
1643 /* Get the attr mask from the dptr */
1644 dirtype = dptr_attr(dptr_num);
1646 DEBUG(3,("dptr_num is %d, mask = %s, attr = %x, dirptr=(0x%lX,%d)\n",
1647 dptr_num, mask, dirtype,
1649 TellDir(conn->dirptr)));
1651 /* We don't need to check for VOL here as this is returned by
1652 a different TRANS2 call. */
1654 DEBUG(8,("dirpath=<%s> dontdescend=<%s>\n",conn->dirpath,lp_dontdescend(SNUM(conn))));
1655 if (in_list(conn->dirpath,lp_dontdescend(SNUM(conn)),conn->case_sensitive))
1656 dont_descend = True;
1659 space_remaining = max_data_bytes;
1660 out_of_space = False;
1663 * Seek to the correct position. We no longer use the resume key but
1664 * depend on the last file name instead.
1667 if(*resume_name && !continue_bit) {
1670 * Fix for NT redirector problem triggered by resume key indexes
1671 * changing between directory scans. We now return a resume key of 0
1672 * and instead look for the filename to continue from (also given
1673 * to us by NT/95/smbfs/smbclient). If no other scans have been done between the
1674 * findfirst/findnext (as is usual) then the directory pointer
1675 * should already be at the correct place. Check this by scanning
1676 * backwards looking for an exact (ie. case sensitive) filename match.
1677 * If we get to the beginning of the directory and haven't found it then scan
1678 * forwards again looking for a match. JRA.
1681 int current_pos, start_pos;
1682 const char *dname = NULL;
1683 pstring dname_pstring;
1684 void *dirptr = conn->dirptr;
1685 start_pos = TellDir(dirptr);
1686 for(current_pos = start_pos; current_pos >= 0; current_pos--) {
1687 DEBUG(7,("call_trans2findnext: seeking to pos %d\n", current_pos));
1689 SeekDir(dirptr, current_pos);
1690 dname = ReadDirName(dirptr);
1693 * Remember, mangle_map is called by
1694 * get_lanman2_dir_entry(), so the resume name
1695 * could be mangled. Ensure we do the same
1699 /* make sure we get a copy that mangle_map can modify */
1701 pstrcpy(dname_pstring, dname);
1702 mangle_map( dname_pstring, False, True, SNUM(conn));
1704 if(strcsequal( resume_name, dname_pstring)) {
1705 SeekDir(dirptr, current_pos+1);
1706 DEBUG(7,("call_trans2findnext: got match at pos %d\n", current_pos+1 ));
1713 * Scan forward from start if not found going backwards.
1716 if(current_pos < 0) {
1717 DEBUG(7,("call_trans2findnext: notfound: seeking to pos %d\n", start_pos));
1718 SeekDir(dirptr, start_pos);
1719 for(current_pos = start_pos; (dname = ReadDirName(dirptr)) != NULL; ++current_pos) {
1722 * Remember, mangle_map is called by
1723 * get_lanman2_dir_entry(), so the resume name
1724 * could be mangled. Ensure we do the same
1729 /* make sure we get a copy that mangle_map can modify */
1731 pstrcpy(dname_pstring, dname);
1732 mangle_map(dname_pstring, False, True, SNUM(conn));
1734 if(strcsequal( resume_name, dname_pstring)) {
1735 SeekDir(dirptr, current_pos+1);
1736 DEBUG(7,("call_trans2findnext: got match at pos %d\n", current_pos+1 ));
1741 } /* end if current_pos */
1742 /* Can't find the name. Just resume from where we were... */
1744 SeekDir(dirptr, start_pos);
1746 } /* end if resume_name && !continue_bit */
1748 for (i=0;(i<(int)maxentries) && !finished && !out_of_space ;i++) {
1749 BOOL got_exact_match = False;
1751 /* this is a heuristic to avoid seeking the dirptr except when
1752 absolutely necessary. It allows for a filename of about 40 chars */
1753 if (space_remaining < DIRLEN_GUESS && numentries > 0) {
1754 out_of_space = True;
1757 finished = !get_lanman2_dir_entry(conn,
1759 mask,dirtype,info_level,
1760 requires_resume_key,dont_descend,
1761 &p,pdata,space_remaining, &out_of_space, &got_exact_match,
1765 if (finished && out_of_space)
1768 if (!finished && !out_of_space)
1772 * As an optimisation if we know we aren't looking
1773 * for a wildcard name (ie. the name matches the wildcard exactly)
1774 * then we can finish on any (first) match.
1775 * This speeds up large directory searches. JRA.
1781 space_remaining = max_data_bytes - PTR_DIFF(p,pdata);
1784 /* Check if we can close the dirptr */
1785 if(close_after_request || (finished && close_if_end)) {
1786 DEBUG(5,("call_trans2findnext: closing dptr_num = %d\n", dptr_num));
1787 dptr_close(&dptr_num); /* This frees up the saved mask */
1790 /* Set up the return parameter block */
1791 SSVAL(params,0,numentries);
1792 SSVAL(params,2,finished);
1793 SSVAL(params,4,0); /* Never an EA error */
1794 SSVAL(params,6,last_name_off);
1796 send_trans2_replies( outbuf, bufsize, params, 8, pdata, PTR_DIFF(p,pdata));
1798 if ((! *directory) && dptr_path(dptr_num))
1799 slprintf(directory,sizeof(directory)-1, "(%s)",dptr_path(dptr_num));
1801 DEBUG( 3, ( "%s mask=%s directory=%s dirtype=%d numentries=%d\n",
1802 smb_fn_name(CVAL(inbuf,smb_com)),
1803 mask, directory, dirtype, numentries ) );
1808 /****************************************************************************
1809 Reply to a TRANS2_QFSINFO (query filesystem info).
1810 ****************************************************************************/
1812 static int call_trans2qfsinfo(connection_struct *conn, char *inbuf, char *outbuf,
1813 int length, int bufsize,
1814 char **pparams, int total_params, char **ppdata, int total_data)
1816 int max_data_bytes = SVAL(inbuf, smb_mdrcnt);
1817 char *pdata = *ppdata;
1818 char *params = *pparams;
1819 uint16 info_level = SVAL(params,0);
1822 char *vname = volume_label(SNUM(conn));
1823 int snum = SNUM(conn);
1824 char *fstype = lp_fstype(SNUM(conn));
1827 DEBUG(3,("call_trans2qfsinfo: level = %d\n", info_level));
1829 if(SMB_VFS_STAT(conn,".",&st)!=0) {
1830 DEBUG(2,("call_trans2qfsinfo: stat of . failed (%s)\n", strerror(errno)));
1831 return ERROR_DOS(ERRSRV,ERRinvdevice);
1834 pdata = Realloc(*ppdata, max_data_bytes + DIR_ENTRY_SAFETY_MARGIN);
1835 if ( pdata == NULL )
1836 return ERROR_DOS(ERRDOS,ERRnomem);
1839 memset((char *)pdata,'\0',max_data_bytes + DIR_ENTRY_SAFETY_MARGIN);
1841 switch (info_level) {
1842 case SMB_INFO_ALLOCATION:
1844 SMB_BIG_UINT dfree,dsize,bsize,block_size,sectors_per_unit,bytes_per_sector;
1846 SMB_VFS_DISK_FREE(conn,".",False,&bsize,&dfree,&dsize);
1847 block_size = lp_block_size(snum);
1848 if (bsize < block_size) {
1849 SMB_BIG_UINT factor = block_size/bsize;
1854 if (bsize > block_size) {
1855 SMB_BIG_UINT factor = bsize/block_size;
1860 bytes_per_sector = 512;
1861 sectors_per_unit = bsize/bytes_per_sector;
1863 DEBUG(5,("call_trans2qfsinfo : SMB_INFO_ALLOCATION id=%x, bsize=%u, cSectorUnit=%u, \
1864 cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)st.st_dev, (unsigned int)bsize, (unsigned int)sectors_per_unit,
1865 (unsigned int)bytes_per_sector, (unsigned int)dsize, (unsigned int)dfree));
1867 SIVAL(pdata,l1_idFileSystem,st.st_dev);
1868 SIVAL(pdata,l1_cSectorUnit,sectors_per_unit);
1869 SIVAL(pdata,l1_cUnit,dsize);
1870 SIVAL(pdata,l1_cUnitAvail,dfree);
1871 SSVAL(pdata,l1_cbSector,bytes_per_sector);
1875 case SMB_INFO_VOLUME:
1876 /* Return volume name */
1878 * Add volume serial number - hash of a combination of
1879 * the called hostname and the service name.
1881 SIVAL(pdata,0,str_checksum(lp_servicename(snum)) ^ (str_checksum(local_machine)<<16) );
1882 len = srvstr_push(outbuf, pdata+l2_vol_szVolLabel, vname, -1, STR_NOALIGN);
1883 SCVAL(pdata,l2_vol_cch,len);
1884 data_len = l2_vol_szVolLabel + len;
1885 DEBUG(5,("call_trans2qfsinfo : time = %x, namelen = %d, name = %s\n",
1886 (unsigned)st.st_ctime, len, vname));
1889 case SMB_QUERY_FS_ATTRIBUTE_INFO:
1890 case SMB_FS_ATTRIBUTE_INFORMATION:
1893 #if defined(HAVE_SYS_QUOTAS)
1894 quota_flag = FILE_VOLUME_QUOTAS;
1897 SIVAL(pdata,0,FILE_CASE_PRESERVED_NAMES|FILE_CASE_SENSITIVE_SEARCH|
1898 (lp_nt_acl_support(SNUM(conn)) ? FILE_PERSISTENT_ACLS : 0)|
1899 quota_flag); /* FS ATTRIBUTES */
1901 SIVAL(pdata,4,255); /* Max filename component length */
1902 /* NOTE! the fstype must *not* be null terminated or win98 won't recognise it
1903 and will think we can't do long filenames */
1904 len = srvstr_push(outbuf, pdata+12, fstype, -1, STR_UNICODE);
1906 data_len = 12 + len;
1909 case SMB_QUERY_FS_LABEL_INFO:
1910 case SMB_FS_LABEL_INFORMATION:
1911 len = srvstr_push(outbuf, pdata+4, vname, -1, 0);
1916 case SMB_QUERY_FS_VOLUME_INFO:
1917 case SMB_FS_VOLUME_INFORMATION:
1920 * Add volume serial number - hash of a combination of
1921 * the called hostname and the service name.
1923 SIVAL(pdata,8,str_checksum(lp_servicename(snum)) ^
1924 (str_checksum(local_machine)<<16));
1926 len = srvstr_push(outbuf, pdata+18, vname, -1, STR_UNICODE);
1927 SIVAL(pdata,12,len);
1929 DEBUG(5,("call_trans2qfsinfo : SMB_QUERY_FS_VOLUME_INFO namelen = %d, vol=%s serv=%s\n",
1930 (int)strlen(vname),vname, lp_servicename(snum)));
1933 case SMB_QUERY_FS_SIZE_INFO:
1934 case SMB_FS_SIZE_INFORMATION:
1936 SMB_BIG_UINT dfree,dsize,bsize,block_size,sectors_per_unit,bytes_per_sector;
1938 SMB_VFS_DISK_FREE(conn,".",False,&bsize,&dfree,&dsize);
1939 block_size = lp_block_size(snum);
1940 if (bsize < block_size) {
1941 SMB_BIG_UINT factor = block_size/bsize;
1946 if (bsize > block_size) {
1947 SMB_BIG_UINT factor = bsize/block_size;
1952 bytes_per_sector = 512;
1953 sectors_per_unit = bsize/bytes_per_sector;
1954 DEBUG(5,("call_trans2qfsinfo : SMB_QUERY_FS_SIZE_INFO bsize=%u, cSectorUnit=%u, \
1955 cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize, (unsigned int)sectors_per_unit,
1956 (unsigned int)bytes_per_sector, (unsigned int)dsize, (unsigned int)dfree));
1957 SBIG_UINT(pdata,0,dsize);
1958 SBIG_UINT(pdata,8,dfree);
1959 SIVAL(pdata,16,sectors_per_unit);
1960 SIVAL(pdata,20,bytes_per_sector);
1964 case SMB_FS_FULL_SIZE_INFORMATION:
1966 SMB_BIG_UINT dfree,dsize,bsize,block_size,sectors_per_unit,bytes_per_sector;
1968 SMB_VFS_DISK_FREE(conn,".",False,&bsize,&dfree,&dsize);
1969 block_size = lp_block_size(snum);
1970 if (bsize < block_size) {
1971 SMB_BIG_UINT factor = block_size/bsize;
1976 if (bsize > block_size) {
1977 SMB_BIG_UINT factor = bsize/block_size;
1982 bytes_per_sector = 512;
1983 sectors_per_unit = bsize/bytes_per_sector;
1984 DEBUG(5,("call_trans2qfsinfo : SMB_QUERY_FS_FULL_SIZE_INFO bsize=%u, cSectorUnit=%u, \
1985 cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize, (unsigned int)sectors_per_unit,
1986 (unsigned int)bytes_per_sector, (unsigned int)dsize, (unsigned int)dfree));
1987 SBIG_UINT(pdata,0,dsize); /* Total Allocation units. */
1988 SBIG_UINT(pdata,8,dfree); /* Caller available allocation units. */
1989 SBIG_UINT(pdata,16,dfree); /* Actual available allocation units. */
1990 SIVAL(pdata,24,sectors_per_unit); /* Sectors per allocation unit. */
1991 SIVAL(pdata,28,bytes_per_sector); /* Bytes per sector. */
1995 case SMB_QUERY_FS_DEVICE_INFO:
1996 case SMB_FS_DEVICE_INFORMATION:
1998 SIVAL(pdata,0,0); /* dev type */
1999 SIVAL(pdata,4,0); /* characteristics */
2002 #ifdef HAVE_SYS_QUOTAS
2003 case SMB_FS_QUOTA_INFORMATION:
2005 * what we have to send --metze:
2007 * Unknown1: 24 NULL bytes
2008 * Soft Quota Treshold: 8 bytes seems like SMB_BIG_UINT or so
2009 * Hard Quota Limit: 8 bytes seems like SMB_BIG_UINT or so
2010 * Quota Flags: 2 byte :
2011 * Unknown3: 6 NULL bytes
2015 * details for Quota Flags:
2017 * 0x0020 Log Limit: log if the user exceeds his Hard Quota
2018 * 0x0010 Log Warn: log if the user exceeds his Soft Quota
2019 * 0x0002 Deny Disk: deny disk access when the user exceeds his Hard Quota
2020 * 0x0001 Enable Quotas: enable quota for this fs
2024 /* we need to fake up a fsp here,
2025 * because its not send in this call
2028 SMB_NTQUOTA_STRUCT quotas;
2031 ZERO_STRUCT(quotas);
2038 if (current_user.uid != 0) {
2039 DEBUG(0,("set_user_quota: access_denied service [%s] user [%s]\n",
2040 lp_servicename(SNUM(conn)),conn->user));
2041 return ERROR_DOS(ERRDOS,ERRnoaccess);
2044 if (vfs_get_ntquota(&fsp, SMB_USER_FS_QUOTA_TYPE, NULL, "as)!=0) {
2045 DEBUG(0,("vfs_get_ntquota() failed for service [%s]\n",lp_servicename(SNUM(conn))));
2046 return ERROR_DOS(ERRSRV,ERRerror);
2051 DEBUG(10,("SMB_FS_QUOTA_INFORMATION: for service [%s]\n",lp_servicename(SNUM(conn))));
2053 /* Unknown1 24 NULL bytes*/
2054 SBIG_UINT(pdata,0,(SMB_BIG_UINT)0);
2055 SBIG_UINT(pdata,8,(SMB_BIG_UINT)0);
2056 SBIG_UINT(pdata,16,(SMB_BIG_UINT)0);
2058 /* Default Soft Quota 8 bytes */
2059 SBIG_UINT(pdata,24,quotas.softlim);
2061 /* Default Hard Quota 8 bytes */
2062 SBIG_UINT(pdata,32,quotas.hardlim);
2064 /* Quota flag 2 bytes */
2065 SSVAL(pdata,40,quotas.qflags);
2067 /* Unknown3 6 NULL bytes */
2073 #endif /* HAVE_SYS_QUOTAS */
2074 case SMB_FS_OBJECTID_INFORMATION:
2079 * Query the version and capabilities of the CIFS UNIX extensions
2083 case SMB_QUERY_CIFS_UNIX_INFO:
2084 if (!lp_unix_extensions())
2085 return ERROR_DOS(ERRDOS,ERRunknownlevel);
2087 SSVAL(pdata,0,CIFS_UNIX_MAJOR_VERSION);
2088 SSVAL(pdata,2,CIFS_UNIX_MINOR_VERSION);
2089 SBIG_UINT(pdata,4,((SMB_BIG_UINT)0)); /* No capabilities for now... */
2092 case SMB_MAC_QUERY_FS_INFO:
2094 * Thursby MAC extension... ONLY on NTFS filesystems
2095 * once we do streams then we don't need this
2097 if (strequal(lp_fstype(SNUM(conn)),"NTFS")) {
2099 SIVAL(pdata,84,0x100); /* Don't support mac... */
2104 return ERROR_DOS(ERRDOS,ERRunknownlevel);
2108 send_trans2_replies( outbuf, bufsize, params, 0, pdata, data_len);
2110 DEBUG( 4, ( "%s info_level = %d\n", smb_fn_name(CVAL(inbuf,smb_com)), info_level) );
2115 #ifdef HAVE_SYS_QUOTAS
2116 /****************************************************************************
2117 Reply to a TRANS2_SETFSINFO (set filesystem info).
2118 ****************************************************************************/
2120 static int call_trans2setfsinfo(connection_struct *conn,
2121 char *inbuf, char *outbuf, int length, int bufsize,
2122 char **pparams, int total_params, char **ppdata, int total_data)
2124 char *pdata = *ppdata;
2125 char *params = *pparams;
2126 files_struct *fsp = NULL;
2129 SMB_NTQUOTA_STRUCT quotas;
2131 ZERO_STRUCT(quotas);
2133 DEBUG(10,("call_trans2setfsinfo: SET_FS_QUOTA: for service [%s]\n",lp_servicename(SNUM(conn))));
2136 if ((current_user.uid != 0)||!CAN_WRITE(conn)) {
2137 DEBUG(0,("set_user_quota: access_denied service [%s] user [%s]\n",
2138 lp_servicename(SNUM(conn)),conn->user));
2139 return ERROR_DOS(ERRSRV,ERRaccess);
2143 if (total_params < 4) {
2144 DEBUG(0,("call_trans2setfsinfo: requires total_params(%d) >= 4 bytes!\n",
2146 return ERROR_DOS(ERRDOS,ERRinvalidparam);
2149 fsp = file_fsp(params,0);
2151 if (!CHECK_NTQUOTA_HANDLE_OK(fsp,conn)) {
2152 DEBUG(3,("TRANSACT_GET_USER_QUOTA: no valid QUOTA HANDLE\n"));
2153 return ERROR_NT(NT_STATUS_INVALID_HANDLE);
2156 info_level = SVAL(params,2);
2158 switch(info_level) {
2159 case SMB_FS_QUOTA_INFORMATION:
2160 /* note: normaly there're 48 bytes,
2161 * but we didn't use the last 6 bytes for now
2164 if (total_data < 42) {
2165 DEBUG(0,("call_trans2setfsinfo: SET_FS_QUOTA: requires total_data(%d) >= 42 bytes!\n",
2167 return ERROR_DOS(ERRDOS,ERRunknownlevel);
2170 /* unknown_1 24 NULL bytes in pdata*/
2172 /* the soft quotas 8 bytes (SMB_BIG_UINT)*/
2173 quotas.softlim = (SMB_BIG_UINT)IVAL(pdata,24);
2174 #ifdef LARGE_SMB_OFF_T
2175 quotas.softlim |= (((SMB_BIG_UINT)IVAL(pdata,28)) << 32);
2176 #else /* LARGE_SMB_OFF_T */
2177 if ((IVAL(pdata,28) != 0)&&
2178 ((quotas.softlim != 0xFFFFFFFF)||
2179 (IVAL(pdata,28)!=0xFFFFFFFF))) {
2180 /* more than 32 bits? */
2181 return ERROR_DOS(ERRDOS,ERRunknownlevel);
2183 #endif /* LARGE_SMB_OFF_T */
2185 /* the hard quotas 8 bytes (SMB_BIG_UINT)*/
2186 quotas.hardlim = (SMB_BIG_UINT)IVAL(pdata,32);
2187 #ifdef LARGE_SMB_OFF_T
2188 quotas.hardlim |= (((SMB_BIG_UINT)IVAL(pdata,36)) << 32);
2189 #else /* LARGE_SMB_OFF_T */
2190 if ((IVAL(pdata,36) != 0)&&
2191 ((quotas.hardlim != 0xFFFFFFFF)||
2192 (IVAL(pdata,36)!=0xFFFFFFFF))) {
2193 /* more than 32 bits? */
2194 return ERROR_DOS(ERRDOS,ERRunknownlevel);
2196 #endif /* LARGE_SMB_OFF_T */
2198 /* quota_flags 2 bytes **/
2199 quotas.qflags = SVAL(pdata,40);
2201 /* unknown_2 6 NULL bytes follow*/
2203 /* now set the quotas */
2204 if (vfs_set_ntquota(fsp, SMB_USER_FS_QUOTA_TYPE, NULL, "as)!=0) {
2205 DEBUG(0,("vfs_set_ntquota() failed for service [%s]\n",lp_servicename(SNUM(conn))));
2206 return ERROR_DOS(ERRSRV,ERRerror);
2211 DEBUG(3,("call_trans2setfsinfo: unknown level (0x%X) not implemented yet.\n",
2213 return ERROR_DOS(ERRDOS,ERRunknownlevel);
2218 * sending this reply works fine,
2219 * but I'm not sure it's the same
2220 * like windows do...
2223 outsize = set_message(outbuf,10,0,True);
2227 #endif /* HAVE_SYS_QUOTAS */
2229 /****************************************************************************
2230 * Utility function to set bad path error.
2231 ****************************************************************************/
2233 int set_bad_path_error(int err, BOOL bad_path, char *outbuf, int def_class, uint32 def_code)
2235 DEBUG(10,("set_bad_path_error: err = %d bad_path = %d\n",
2236 err, (int)bad_path ));
2240 return ERROR_NT(NT_STATUS_OBJECT_PATH_NOT_FOUND);
2242 return ERROR_NT(NT_STATUS_OBJECT_NAME_NOT_FOUND);
2245 return UNIXERROR(def_class,def_code);
2248 /****************************************************************************
2249 Reply to a TRANS2_QFILEPATHINFO or TRANSACT2_QFILEINFO (query file info by
2250 file name or file id).
2251 ****************************************************************************/
2253 static int call_trans2qfilepathinfo(connection_struct *conn,
2254 char *inbuf, char *outbuf, int length,
2256 char **pparams, int total_params, char **ppdata, int total_data)
2258 int max_data_bytes = SVAL(inbuf, smb_mdrcnt);
2259 char *params = *pparams;
2260 char *pdata = *ppdata;
2261 uint16 tran_call = SVAL(inbuf, smb_setup0);
2264 SMB_OFF_T file_size=0;
2265 SMB_BIG_UINT allocation_size=0;
2266 unsigned int data_size;
2267 unsigned int param_size = 2;
2268 SMB_STRUCT_STAT sbuf;
2269 pstring fname, dos_fname;
2274 BOOL bad_path = False;
2275 BOOL delete_pending = False;
2278 files_struct *fsp = NULL;
2279 uint32 desired_access = 0x12019F; /* Default - GENERIC_EXECUTE mapping from Windows */
2282 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
2286 if (tran_call == TRANSACT2_QFILEINFO) {
2287 if (total_params < 4)
2288 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
2290 fsp = file_fsp(params,0);
2291 info_level = SVAL(params,2);
2293 DEBUG(3,("call_trans2qfilepathinfo: TRANSACT2_QFILEINFO: level = %d\n", info_level));
2295 if(fsp && (fsp->fake_file_handle)) {
2297 * This is actually for the QUOTA_FAKE_FILE --metze
2300 pstrcpy(fname, fsp->fsp_name);
2301 /* We know this name is ok, it's already passed the checks. */
2303 } else if(fsp && (fsp->is_directory || fsp->fd == -1)) {
2305 * This is actually a QFILEINFO on a directory
2306 * handle (returned from an NT SMB). NT5.0 seems
2307 * to do this call. JRA.
2309 /* We know this name is ok, it's already passed the checks. */
2310 pstrcpy(fname, fsp->fsp_name);
2312 if (INFO_LEVEL_IS_UNIX(info_level)) {
2313 /* Always do lstat for UNIX calls. */
2314 if (SMB_VFS_LSTAT(conn,fname,&sbuf)) {
2315 DEBUG(3,("call_trans2qfilepathinfo: SMB_VFS_LSTAT of %s failed (%s)\n",fname,strerror(errno)));
2316 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRbadpath);
2318 } else if (SMB_VFS_STAT(conn,fname,&sbuf)) {
2319 DEBUG(3,("call_trans2qfilepathinfo: SMB_VFS_STAT of %s failed (%s)\n",fname,strerror(errno)));
2320 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRbadpath);
2323 delete_pending = fsp->is_directory ? fsp->directory_delete_on_close : 0;
2326 * Original code - this is an open file.
2328 CHECK_FSP(fsp,conn);
2330 pstrcpy(fname, fsp->fsp_name);
2331 if (SMB_VFS_FSTAT(fsp,fsp->fd,&sbuf) != 0) {
2332 DEBUG(3,("fstat of fnum %d failed (%s)\n", fsp->fnum, strerror(errno)));
2333 return(UNIXERROR(ERRDOS,ERRbadfid));
2335 pos = fsp->position_information;
2336 delete_pending = fsp->delete_on_close;
2337 desired_access = fsp->desired_access;
2340 NTSTATUS status = NT_STATUS_OK;
2343 if (total_params < 6)
2344 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
2346 info_level = SVAL(params,0);
2348 DEBUG(3,("call_trans2qfilepathinfo: TRANSACT2_QPATHINFO: level = %d\n", info_level));
2350 srvstr_get_path(inbuf, fname, ¶ms[6], sizeof(fname), -1, STR_TERMINATE, &status, False);
2351 if (!NT_STATUS_IS_OK(status)) {
2352 return ERROR_NT(status);
2355 RESOLVE_DFSPATH(fname, conn, inbuf, outbuf);
2357 unix_convert(fname,conn,0,&bad_path,&sbuf);
2359 return ERROR_NT(NT_STATUS_OBJECT_PATH_NOT_FOUND);
2361 if (!check_name(fname,conn)) {
2362 DEBUG(3,("call_trans2qfilepathinfo: fileinfo of %s failed (%s)\n",fname,strerror(errno)));
2363 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRbadpath);
2366 if (INFO_LEVEL_IS_UNIX(info_level)) {
2367 /* Always do lstat for UNIX calls. */
2368 if (SMB_VFS_LSTAT(conn,fname,&sbuf)) {
2369 DEBUG(3,("call_trans2qfilepathinfo: SMB_VFS_LSTAT of %s failed (%s)\n",fname,strerror(errno)));
2370 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRbadpath);
2372 } else if (!VALID_STAT(sbuf) && SMB_VFS_STAT(conn,fname,&sbuf) && (info_level != SMB_INFO_IS_NAME_VALID)) {
2373 DEBUG(3,("call_trans2qfilepathinfo: SMB_VFS_STAT of %s failed (%s)\n",fname,strerror(errno)));
2374 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRbadpath);
2378 if (INFO_LEVEL_IS_UNIX(info_level) && !lp_unix_extensions())
2379 return ERROR_DOS(ERRDOS,ERRunknownlevel);
2381 DEBUG(3,("call_trans2qfilepathinfo %s (fnum = %d) level=%d call=%d total_data=%d\n",
2382 fname,fsp ? fsp->fnum : -1, info_level,tran_call,total_data));
2384 p = strrchr_m(fname,'/');
2390 mode = dos_mode(conn,fname,&sbuf);
2392 mode = FILE_ATTRIBUTE_NORMAL;
2394 fullpathname = fname;
2395 file_size = get_file_size(sbuf);
2396 allocation_size = get_allocation_size(fsp,&sbuf);
2400 params = Realloc(*pparams,2);
2402 return ERROR_DOS(ERRDOS,ERRnomem);
2404 memset((char *)params,'\0',2);
2405 data_size = max_data_bytes + DIR_ENTRY_SAFETY_MARGIN;
2406 pdata = Realloc(*ppdata, data_size);
2407 if ( pdata == NULL )
2408 return ERROR_DOS(ERRDOS,ERRnomem);
2411 if (total_data > 0 && IVAL(pdata,0) == total_data) {
2412 /* uggh, EAs for OS2 */
2413 DEBUG(4,("Rejecting EA request with total_data=%d\n",total_data));
2414 return ERROR_DOS(ERRDOS,ERReasnotsupported);
2417 memset((char *)pdata,'\0',data_size);
2419 c_time = get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(conn)));
2421 if (lp_dos_filetime_resolution(SNUM(conn))) {
2423 sbuf.st_atime &= ~1;
2424 sbuf.st_ctime &= ~1;
2425 sbuf.st_mtime &= ~1;
2428 /* NT expects the name to be in an exact form of the *full*
2429 filename. See the trans2 torture test */
2430 if (strequal(base_name,".")) {
2431 pstrcpy(dos_fname, "\\");
2433 pstr_sprintf(dos_fname, "\\%s", fname);
2434 string_replace(dos_fname, '/', '\\');
2437 switch (info_level) {
2438 case SMB_INFO_STANDARD:
2439 DEBUG(10,("call_trans2qfilepathinfo: SMB_INFO_STANDARD\n"));
2441 put_dos_date2(pdata,l1_fdateCreation,c_time);
2442 put_dos_date2(pdata,l1_fdateLastAccess,sbuf.st_atime);
2443 put_dos_date2(pdata,l1_fdateLastWrite,sbuf.st_mtime); /* write time */
2444 SIVAL(pdata,l1_cbFile,(uint32)file_size);
2445 SIVAL(pdata,l1_cbFileAlloc,(uint32)allocation_size);
2446 SSVAL(pdata,l1_attrFile,mode);
2449 case SMB_INFO_QUERY_EA_SIZE:
2451 unsigned int ea_size = estimate_ea_size(conn, fsp, fname);
2452 DEBUG(10,("call_trans2qfilepathinfo: SMB_INFO_QUERY_EA_SIZE\n"));
2454 put_dos_date2(pdata,l1_fdateCreation,c_time);
2455 put_dos_date2(pdata,l1_fdateLastAccess,sbuf.st_atime);
2456 put_dos_date2(pdata,l1_fdateLastWrite,sbuf.st_mtime); /* write time */
2457 SIVAL(pdata,l1_cbFile,(uint32)file_size);
2458 SIVAL(pdata,l1_cbFileAlloc,(uint32)allocation_size);
2459 SSVAL(pdata,l1_attrFile,mode);
2460 SIVAL(pdata,l1_attrFile+2,ea_size);
2464 case SMB_INFO_IS_NAME_VALID:
2465 DEBUG(10,("call_trans2qfilepathinfo: SMB_INFO_IS_NAME_VALID\n"));
2466 if (tran_call == TRANSACT2_QFILEINFO) {
2467 /* os/2 needs this ? really ?*/
2468 return ERROR_DOS(ERRDOS,ERRbadfunc);
2474 case SMB_INFO_QUERY_EAS_FROM_LIST:
2475 DEBUG(10,("call_trans2qfilepathinfo: SMB_INFO_QUERY_EAS_FROM_LIST\n"));
2477 put_dos_date2(pdata,0,c_time);
2478 put_dos_date2(pdata,4,sbuf.st_atime);
2479 put_dos_date2(pdata,8,sbuf.st_mtime);
2480 SIVAL(pdata,12,(uint32)file_size);
2481 SIVAL(pdata,16,(uint32)allocation_size);
2482 SIVAL(pdata,20,mode);
2485 case SMB_INFO_QUERY_ALL_EAS:
2486 DEBUG(10,("call_trans2qfilepathinfo: SMB_INFO_QUERY_ALL_EAS\n"));
2487 /* We have data_size bytes to put EA's into. */
2488 data_size = fill_ea_buffer(pdata, data_size, conn, fsp, fname);
2491 case SMB_FILE_BASIC_INFORMATION:
2492 case SMB_QUERY_FILE_BASIC_INFO:
2494 if (info_level == SMB_QUERY_FILE_BASIC_INFO) {
2495 DEBUG(10,("call_trans2qfilepathinfo: SMB_QUERY_FILE_BASIC_INFO\n"));
2496 data_size = 36; /* w95 returns 40 bytes not 36 - why ?. */
2498 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_BASIC_INFORMATION\n"));
2502 put_long_date(pdata,c_time);
2503 put_long_date(pdata+8,sbuf.st_atime);
2504 put_long_date(pdata+16,sbuf.st_mtime); /* write time */
2505 put_long_date(pdata+24,sbuf.st_mtime); /* change time */
2506 SIVAL(pdata,32,mode);
2508 DEBUG(5,("SMB_QFBI - "));
2510 time_t create_time = c_time;
2511 DEBUG(5,("create: %s ", ctime(&create_time)));
2513 DEBUG(5,("access: %s ", ctime(&sbuf.st_atime)));
2514 DEBUG(5,("write: %s ", ctime(&sbuf.st_mtime)));
2515 DEBUG(5,("change: %s ", ctime(&sbuf.st_mtime)));
2516 DEBUG(5,("mode: %x\n", mode));
2520 case SMB_FILE_STANDARD_INFORMATION:
2521 case SMB_QUERY_FILE_STANDARD_INFO:
2523 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_STANDARD_INFORMATION\n"));
2525 SOFF_T(pdata,0,allocation_size);
2526 SOFF_T(pdata,8,file_size);
2527 if (delete_pending & sbuf.st_nlink)
2528 SIVAL(pdata,16,sbuf.st_nlink - 1);
2530 SIVAL(pdata,16,sbuf.st_nlink);
2532 SCVAL(pdata,21,(mode&aDIR)?1:0);
2535 case SMB_FILE_EA_INFORMATION:
2536 case SMB_QUERY_FILE_EA_INFO:
2538 unsigned int ea_size = estimate_ea_size(conn, fsp, fname);
2539 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_EA_INFORMATION\n"));
2541 SIVAL(pdata,0,ea_size);
2545 /* Get the 8.3 name - used if NT SMB was negotiated. */
2546 case SMB_QUERY_FILE_ALT_NAME_INFO:
2547 case SMB_FILE_ALTERNATE_NAME_INFORMATION:
2551 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_ALTERNATE_NAME_INFORMATION\n"));
2552 pstrcpy(short_name,base_name);
2553 /* Mangle if not already 8.3 */
2554 if(!mangle_is_8_3(short_name, True)) {
2555 mangle_map(short_name,True,True,SNUM(conn));
2557 len = srvstr_push(outbuf, pdata+4, short_name, -1, STR_UNICODE);
2558 data_size = 4 + len;
2563 case SMB_QUERY_FILE_NAME_INFO:
2565 this must be *exactly* right for ACLs on mapped drives to work
2567 len = srvstr_push(outbuf, pdata+4, dos_fname, -1, STR_UNICODE);
2568 DEBUG(10,("call_trans2qfilepathinfo: SMB_QUERY_FILE_NAME_INFO\n"));
2569 data_size = 4 + len;
2573 case SMB_FILE_ALLOCATION_INFORMATION:
2574 case SMB_QUERY_FILE_ALLOCATION_INFO:
2575 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_ALLOCATION_INFORMATION\n"));
2577 SOFF_T(pdata,0,allocation_size);
2580 case SMB_FILE_END_OF_FILE_INFORMATION:
2581 case SMB_QUERY_FILE_END_OF_FILEINFO:
2582 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_END_OF_FILE_INFORMATION\n"));
2584 SOFF_T(pdata,0,file_size);
2587 case SMB_QUERY_FILE_ALL_INFO:
2588 case SMB_FILE_ALL_INFORMATION:
2590 unsigned int ea_size = estimate_ea_size(conn, fsp, fname);
2591 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_ALL_INFORMATION\n"));
2592 put_long_date(pdata,c_time);
2593 put_long_date(pdata+8,sbuf.st_atime);
2594 put_long_date(pdata+16,sbuf.st_mtime); /* write time */
2595 put_long_date(pdata+24,sbuf.st_mtime); /* change time */
2596 SIVAL(pdata,32,mode);
2598 SOFF_T(pdata,0,allocation_size);
2599 SOFF_T(pdata,8,file_size);
2600 if (delete_pending && sbuf.st_nlink)
2601 SIVAL(pdata,16,sbuf.st_nlink - 1);
2603 SIVAL(pdata,16,sbuf.st_nlink);
2604 SCVAL(pdata,20,delete_pending);
2605 SCVAL(pdata,21,(mode&aDIR)?1:0);
2607 SIVAL(pdata,0,ea_size);
2608 pdata += 4; /* EA info */
2609 len = srvstr_push(outbuf, pdata+4, dos_fname, -1, STR_UNICODE);
2612 data_size = PTR_DIFF(pdata,(*ppdata));
2615 case SMB_FILE_INTERNAL_INFORMATION:
2616 /* This should be an index number - looks like
2619 I think this causes us to fail the IFSKIT
2620 BasicFileInformationTest. -tpot */
2622 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_INTERNAL_INFORMATION\n"));
2623 SIVAL(pdata,0,sbuf.st_dev);
2624 SIVAL(pdata,4,sbuf.st_ino);
2628 case SMB_FILE_ACCESS_INFORMATION:
2629 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_ACCESS_INFORMATION\n"));
2630 SIVAL(pdata,0,desired_access);
2634 case SMB_FILE_NAME_INFORMATION:
2635 /* Pathname with leading '\'. */
2638 byte_len = dos_PutUniCode(pdata+4,dos_fname,max_data_bytes,False);
2639 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_NAME_INFORMATION\n"));
2640 SIVAL(pdata,0,byte_len);
2641 data_size = 4 + byte_len;
2645 case SMB_FILE_DISPOSITION_INFORMATION:
2646 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_DISPOSITION_INFORMATION\n"));
2648 SCVAL(pdata,0,delete_pending);
2651 case SMB_FILE_POSITION_INFORMATION:
2652 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_POSITION_INFORMATION\n"));
2654 SOFF_T(pdata,0,pos);
2657 case SMB_FILE_MODE_INFORMATION:
2658 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_MODE_INFORMATION\n"));
2659 SIVAL(pdata,0,mode);
2663 case SMB_FILE_ALIGNMENT_INFORMATION:
2664 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_ALIGNMENT_INFORMATION\n"));
2665 SIVAL(pdata,0,0); /* No alignment needed. */
2671 * NT4 server just returns "invalid query" to this - if we try to answer
2672 * it then NTws gets a BSOD! (tridge).
2673 * W2K seems to want this. JRA.
2675 case SMB_QUERY_FILE_STREAM_INFO:
2677 case SMB_FILE_STREAM_INFORMATION:
2678 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_STREAM_INFORMATION\n"));
2682 size_t byte_len = dos_PutUniCode(pdata+24,"::$DATA", 0xE, False);
2683 SIVAL(pdata,0,0); /* ??? */
2684 SIVAL(pdata,4,byte_len); /* Byte length of unicode string ::$DATA */
2685 SOFF_T(pdata,8,file_size);
2686 SIVAL(pdata,16,allocation_size);
2687 SIVAL(pdata,20,0); /* ??? */
2688 data_size = 24 + byte_len;
2692 case SMB_QUERY_COMPRESSION_INFO:
2693 case SMB_FILE_COMPRESSION_INFORMATION:
2694 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_COMPRESSION_INFORMATION\n"));
2695 SOFF_T(pdata,0,file_size);
2696 SIVAL(pdata,8,0); /* ??? */
2697 SIVAL(pdata,12,0); /* ??? */
2701 case SMB_FILE_NETWORK_OPEN_INFORMATION:
2702 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_NETWORK_OPEN_INFORMATION\n"));
2703 put_long_date(pdata,c_time);
2704 put_long_date(pdata+8,sbuf.st_atime);
2705 put_long_date(pdata+16,sbuf.st_mtime); /* write time */
2706 put_long_date(pdata+24,sbuf.st_mtime); /* change time */
2707 SIVAL(pdata,32,allocation_size);
2708 SOFF_T(pdata,40,file_size);
2709 SIVAL(pdata,48,mode);
2710 SIVAL(pdata,52,0); /* ??? */
2714 case SMB_FILE_ATTRIBUTE_TAG_INFORMATION:
2715 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_ATTRIBUTE_TAG_INFORMATION\n"));
2716 SIVAL(pdata,0,mode);
2722 * CIFS UNIX Extensions.
2725 case SMB_QUERY_FILE_UNIX_BASIC:
2727 DEBUG(10,("call_trans2qfilepathinfo: SMB_QUERY_FILE_UNIX_BASIC\n"));
2728 DEBUG(4,("call_trans2qfilepathinfo: st_mode=%o\n",(int)sbuf.st_mode));
2730 SOFF_T(pdata,0,get_file_size(sbuf)); /* File size 64 Bit */
2733 SOFF_T(pdata,0,get_allocation_size(fsp,&sbuf)); /* Number of bytes used on disk - 64 Bit */
2736 put_long_date(pdata,sbuf.st_ctime); /* Creation Time 64 Bit */
2737 put_long_date(pdata+8,sbuf.st_atime); /* Last access time 64 Bit */
2738 put_long_date(pdata+16,sbuf.st_mtime); /* Last modification time 64 Bit */
2741 SIVAL(pdata,0,sbuf.st_uid); /* user id for the owner */
2745 SIVAL(pdata,0,sbuf.st_gid); /* group id of owner */
2749 SIVAL(pdata,0,unix_filetype(sbuf.st_mode));
2752 SIVAL(pdata,0,unix_dev_major(sbuf.st_rdev)); /* Major device number if type is device */
2756 SIVAL(pdata,0,unix_dev_minor(sbuf.st_rdev)); /* Minor device number if type is device */
2760 SINO_T(pdata,0,(SMB_INO_T)sbuf.st_ino); /* inode number */
2763 SIVAL(pdata,0, unix_perms_to_wire(sbuf.st_mode)); /* Standard UNIX file permissions */
2767 SIVAL(pdata,0,sbuf.st_nlink); /* number of hard links */
2770 data_size = PTR_DIFF(pdata,(*ppdata));
2774 DEBUG(4,("call_trans2qfilepathinfo: SMB_QUERY_FILE_UNIX_BASIC"));
2776 for (i=0; i<100; i++)
2777 DEBUG(4,("%d=%x, ",i, (*ppdata)[i]));
2783 case SMB_QUERY_FILE_UNIX_LINK:
2787 DEBUG(10,("call_trans2qfilepathinfo: SMB_QUERY_FILE_UNIX_LINK\n"));
2789 if(!S_ISLNK(sbuf.st_mode))
2790 return(UNIXERROR(ERRSRV,ERRbadlink));
2792 return(UNIXERROR(ERRDOS,ERRbadlink));
2794 len = SMB_VFS_READLINK(conn,fullpathname, buffer, sizeof(pstring)-1); /* read link */
2796 return(UNIXERROR(ERRDOS,ERRnoaccess));
2798 len = srvstr_push(outbuf, pdata, buffer, -1, STR_TERMINATE);
2800 data_size = PTR_DIFF(pdata,(*ppdata));
2806 return ERROR_DOS(ERRDOS,ERRunknownlevel);
2809 send_trans2_replies(outbuf, bufsize, params, param_size, *ppdata, data_size);
2814 /****************************************************************************
2815 Deal with the internal needs of setting the delete on close flag. Note that
2816 as the tdb locking is recursive, it is safe to call this from within
2817 open_file_shared. JRA.
2818 ****************************************************************************/
2820 NTSTATUS set_delete_on_close_internal(files_struct *fsp, BOOL delete_on_close, uint32 dosmode)
2822 if (delete_on_close) {
2824 * Only allow delete on close for writable files.
2827 if (dosmode & aRONLY) {
2828 DEBUG(10,("set_delete_on_close_internal: file %s delete on close flag set but file attribute is readonly.\n",
2830 return NT_STATUS_CANNOT_DELETE;
2834 * Only allow delete on close for writable shares.
2837 if (!CAN_WRITE(fsp->conn)) {
2838 DEBUG(10,("set_delete_on_close_internal: file %s delete on close flag set but write access denied on share.\n",
2840 return NT_STATUS_ACCESS_DENIED;
2844 * Only allow delete on close for files/directories opened with delete intent.
2847 if (!(fsp->desired_access & DELETE_ACCESS)) {
2848 DEBUG(10,("set_delete_on_close_internal: file %s delete on close flag set but delete access denied.\n",
2850 return NT_STATUS_ACCESS_DENIED;
2854 if(fsp->is_directory) {
2855 fsp->directory_delete_on_close = delete_on_close;
2856 DEBUG(10, ("set_delete_on_close_internal: %s delete on close flag for fnum = %d, directory %s\n",
2857 delete_on_close ? "Added" : "Removed", fsp->fnum, fsp->fsp_name ));
2859 fsp->delete_on_close = delete_on_close;
2860 DEBUG(10, ("set_delete_on_close_internal: %s delete on close flag for fnum = %d, file %s\n",
2861 delete_on_close ? "Added" : "Removed", fsp->fnum, fsp->fsp_name ));
2864 return NT_STATUS_OK;
2867 /****************************************************************************
2868 Sets the delete on close flag over all share modes on this file.
2869 Modify the share mode entry for all files open
2870 on this device and inode to tell other smbds we have
2871 changed the delete on close flag. This will be noticed
2872 in the close code, the last closer will delete the file
2874 ****************************************************************************/
2876 NTSTATUS set_delete_on_close_over_all(files_struct *fsp, BOOL delete_on_close)
2878 DEBUG(10,("set_delete_on_close_over_all: %s delete on close flag for fnum = %d, file %s\n",
2879 delete_on_close ? "Adding" : "Removing", fsp->fnum, fsp->fsp_name ));
2881 if (fsp->is_directory || fsp->is_stat)
2882 return NT_STATUS_OK;
2884 if (lock_share_entry_fsp(fsp) == False)
2885 return NT_STATUS_ACCESS_DENIED;
2887 if (!modify_delete_flag(fsp->dev, fsp->inode, delete_on_close)) {
2888 DEBUG(0,("set_delete_on_close_over_all: failed to change delete on close flag for file %s\n",
2890 unlock_share_entry_fsp(fsp);
2891 return NT_STATUS_ACCESS_DENIED;
2894 unlock_share_entry_fsp(fsp);
2895 return NT_STATUS_OK;
2898 /****************************************************************************
2899 Set a hard link (called by UNIX extensions and by NT rename with HARD link
2901 ****************************************************************************/
2903 NTSTATUS hardlink_internals(connection_struct *conn, char *oldname, char *newname)
2905 BOOL bad_path_oldname = False;
2906 BOOL bad_path_newname = False;
2907 SMB_STRUCT_STAT sbuf1, sbuf2;
2908 pstring last_component_oldname;
2909 pstring last_component_newname;
2910 NTSTATUS status = NT_STATUS_OK;
2916 if (ms_has_wild(newname) || ms_has_wild(oldname)) {
2917 return NT_STATUS_OBJECT_PATH_SYNTAX_BAD;
2920 unix_convert(oldname,conn,last_component_oldname,&bad_path_oldname,&sbuf1);
2921 if (bad_path_oldname) {
2922 return NT_STATUS_OBJECT_PATH_NOT_FOUND;
2925 /* Quick check for "." and ".." */
2926 if (last_component_oldname[0] == '.') {
2927 if (!last_component_oldname[1] || (last_component_oldname[1] == '.' && !last_component_oldname[2])) {
2928 return NT_STATUS_OBJECT_NAME_INVALID;
2932 /* source must already exist. */
2933 if (!VALID_STAT(sbuf1)) {
2934 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2937 if (!check_name(oldname,conn)) {
2938 return NT_STATUS_ACCESS_DENIED;
2941 unix_convert(newname,conn,last_component_newname,&bad_path_newname,&sbuf2);
2942 if (bad_path_newname) {
2943 return NT_STATUS_OBJECT_PATH_NOT_FOUND;
2946 /* Quick check for "." and ".." */
2947 if (last_component_newname[0] == '.') {
2948 if (!last_component_newname[1] || (last_component_newname[1] == '.' && !last_component_newname[2])) {
2949 return NT_STATUS_OBJECT_NAME_INVALID;
2953 /* Disallow if newname already exists. */
2954 if (VALID_STAT(sbuf2)) {
2955 return NT_STATUS_OBJECT_NAME_COLLISION;
2958 if (!check_name(newname,conn)) {
2959 return NT_STATUS_ACCESS_DENIED;
2962 /* No links from a directory. */
2963 if (S_ISDIR(sbuf1.st_mode)) {
2964 return NT_STATUS_FILE_IS_A_DIRECTORY;
2967 /* Ensure this is within the share. */
2968 if (!reduce_name(conn, oldname) != 0)
2969 return NT_STATUS_ACCESS_DENIED;
2971 DEBUG(10,("hardlink_internals: doing hard link %s -> %s\n", newname, oldname ));
2973 if (SMB_VFS_LINK(conn,oldname,newname) != 0) {
2974 status = map_nt_error_from_unix(errno);
2975 DEBUG(3,("hardlink_internals: Error %s hard link %s -> %s\n",
2976 nt_errstr(status), newname, oldname));
2982 /****************************************************************************
2983 Reply to a TRANS2_SETFILEINFO (set file info by fileid).
2984 ****************************************************************************/
2986 static int call_trans2setfilepathinfo(connection_struct *conn,
2987 char *inbuf, char *outbuf, int length, int bufsize,
2988 char **pparams, int total_params, char **ppdata, int total_data)
2990 char *params = *pparams;
2991 char *pdata = *ppdata;
2992 uint16 tran_call = SVAL(inbuf, smb_setup0);
2997 SMB_STRUCT_STAT sbuf;
3000 BOOL bad_path = False;
3001 files_struct *fsp = NULL;
3002 uid_t set_owner = (uid_t)SMB_UID_NO_CHANGE;
3003 gid_t set_grp = (uid_t)SMB_GID_NO_CHANGE;
3004 mode_t unixmode = 0;
3005 NTSTATUS status = NT_STATUS_OK;
3008 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
3012 if (tran_call == TRANSACT2_SETFILEINFO) {
3013 if (total_params < 4)
3014 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
3016 fsp = file_fsp(params,0);
3017 info_level = SVAL(params,2);
3019 if(fsp && (fsp->is_directory || fsp->fd == -1)) {
3021 * This is actually a SETFILEINFO on a directory
3022 * handle (returned from an NT SMB). NT5.0 seems
3023 * to do this call. JRA.
3025 pstrcpy(fname, fsp->fsp_name);
3026 if (SMB_VFS_STAT(conn,fname,&sbuf) != 0) {
3027 DEBUG(3,("call_trans2setfilepathinfo: fileinfo of %s failed (%s)\n",fname,strerror(errno)));
3028 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRbadpath);
3030 } else if (fsp && fsp->print_file) {
3032 * Doing a DELETE_ON_CLOSE should cancel a print job.
3034 if ((info_level == SMB_SET_FILE_DISPOSITION_INFO) && CVAL(pdata,0)) {
3035 fsp->share_mode = FILE_DELETE_ON_CLOSE;
3037 DEBUG(3,("call_trans2setfilepathinfo: Cancelling print job (%s)\n", fsp->fsp_name ));
3040 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
3043 return (UNIXERROR(ERRDOS,ERRbadpath));
3046 * Original code - this is an open file.
3048 CHECK_FSP(fsp,conn);
3050 pstrcpy(fname, fsp->fsp_name);
3053 if (SMB_VFS_FSTAT(fsp,fd,&sbuf) != 0) {
3054 DEBUG(3,("call_trans2setfilepathinfo: fstat of fnum %d failed (%s)\n",fsp->fnum, strerror(errno)));
3055 return(UNIXERROR(ERRDOS,ERRbadfid));
3060 if (total_params < 6)
3061 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
3063 info_level = SVAL(params,0);
3064 srvstr_get_path(inbuf, fname, ¶ms[6], sizeof(fname), -1, STR_TERMINATE, &status, False);
3065 if (!NT_STATUS_IS_OK(status)) {
3066 return ERROR_NT(status);
3068 unix_convert(fname,conn,0,&bad_path,&sbuf);
3070 return ERROR_NT(NT_STATUS_OBJECT_PATH_NOT_FOUND);
3074 * For CIFS UNIX extensions the target name may not exist.
3077 if(!VALID_STAT(sbuf) && !INFO_LEVEL_IS_UNIX(info_level)) {
3078 DEBUG(3,("call_trans2setfilepathinfo: stat of %s failed (%s)\n", fname, strerror(errno)));
3079 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRbadpath);
3082 if(!check_name(fname, conn)) {
3083 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRbadpath);
3088 if (!CAN_WRITE(conn))
3089 return ERROR_DOS(ERRSRV,ERRaccess);
3091 if (INFO_LEVEL_IS_UNIX(info_level) && !lp_unix_extensions())
3092 return ERROR_DOS(ERRDOS,ERRunknownlevel);
3094 if (VALID_STAT(sbuf))
3095 unixmode = sbuf.st_mode;
3097 DEBUG(3,("call_trans2setfilepathinfo(%d) %s (fnum %d) info_level=%d totdata=%d\n",
3098 tran_call,fname, fsp ? fsp->fnum : -1, info_level,total_data));
3100 /* Realloc the parameter and data sizes */
3101 params = Realloc(*pparams,2);
3103 return ERROR_DOS(ERRDOS,ERRnomem);
3109 /* the pending modtime overrides the current modtime */
3110 sbuf.st_mtime = fsp->pending_modtime;
3113 size = get_file_size(sbuf);
3114 tvs.modtime = sbuf.st_mtime;
3115 tvs.actime = sbuf.st_atime;
3116 dosmode = dos_mode(conn,fname,&sbuf);
3117 unixmode = sbuf.st_mode;
3119 set_owner = VALID_STAT(sbuf) ? sbuf.st_uid : (uid_t)SMB_UID_NO_CHANGE;
3120 set_grp = VALID_STAT(sbuf) ? sbuf.st_gid : (gid_t)SMB_GID_NO_CHANGE;
3122 switch (info_level) {
3123 case SMB_INFO_STANDARD:
3125 if (total_data < 12)
3126 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
3129 tvs.actime = make_unix_date2(pdata+l1_fdateLastAccess);
3131 tvs.modtime = make_unix_date2(pdata+l1_fdateLastWrite);
3135 case SMB_INFO_SET_EA:
3136 status = set_ea(conn, fsp, fname, pdata, total_data);
3137 if (NT_STATUS_V(status) != NT_STATUS_V(NT_STATUS_OK))
3138 return ERROR_NT(status);
3141 /* XXXX um, i don't think this is right.
3142 it's also not in the cifs6.txt spec.
3144 case SMB_INFO_QUERY_EAS_FROM_LIST:
3145 if (total_data < 28)
3146 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
3148 tvs.actime = make_unix_date2(pdata+8);
3149 tvs.modtime = make_unix_date2(pdata+12);
3150 size = IVAL(pdata,16);
3151 dosmode = IVAL(pdata,24);
3154 /* XXXX nor this. not in cifs6.txt, either. */
3155 case SMB_INFO_QUERY_ALL_EAS:
3156 if (total_data < 28)
3157 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
3159 tvs.actime = make_unix_date2(pdata+8);
3160 tvs.modtime = make_unix_date2(pdata+12);
3161 size = IVAL(pdata,16);
3162 dosmode = IVAL(pdata,24);
3165 case SMB_SET_FILE_BASIC_INFO:
3166 case SMB_FILE_BASIC_INFORMATION:
3168 /* Patch to do this correctly from Paul Eggert <eggert@twinsun.com>. */
3170 time_t changed_time;
3172 if (total_data < 36)
3173 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
3175 /* Ignore create time at offset pdata. */
3178 tvs.actime = interpret_long_date(pdata+8);
3180 write_time = interpret_long_date(pdata+16);
3181 changed_time = interpret_long_date(pdata+24);
3183 tvs.modtime = MIN(write_time, changed_time);
3185 if (write_time > tvs.modtime && write_time != 0xffffffff) {
3186 tvs.modtime = write_time;
3188 /* Prefer a defined time to an undefined one. */
3189 if (tvs.modtime == (time_t)0 || tvs.modtime == (time_t)-1)
3190 tvs.modtime = (write_time == (time_t)0 || write_time == (time_t)-1
3191 ? changed_time : write_time);
3194 dosmode = IVAL(pdata,32);
3198 case SMB_FILE_ALLOCATION_INFORMATION:
3199 case SMB_SET_FILE_ALLOCATION_INFO:
3202 SMB_BIG_UINT allocation_size;
3205 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
3207 allocation_size = (SMB_BIG_UINT)IVAL(pdata,0);
3208 #ifdef LARGE_SMB_OFF_T
3209 allocation_size |= (((SMB_BIG_UINT)IVAL(pdata,4)) << 32);
3210 #else /* LARGE_SMB_OFF_T */
3211 if (IVAL(pdata,4) != 0) /* more than 32 bits? */
3212 return ERROR_DOS(ERRDOS,ERRunknownlevel);
3213 #endif /* LARGE_SMB_OFF_T */
3214 DEBUG(10,("call_trans2setfilepathinfo: Set file allocation info for file %s to %.0f\n",
3215 fname, (double)allocation_size ));
3217 if (allocation_size)
3218 allocation_size = smb_roundup(allocation_size);
3220 if(allocation_size != get_file_size(sbuf)) {
3221 SMB_STRUCT_STAT new_sbuf;
3223 DEBUG(10,("call_trans2setfilepathinfo: file %s : setting new allocation size to %.0f\n",
3224 fname, (double)allocation_size ));
3227 files_struct *new_fsp = NULL;
3228 int access_mode = 0;
3231 if(global_oplock_break) {
3232 /* Queue this file modify as we are the process of an oplock break. */
3234 DEBUG(2,("call_trans2setfilepathinfo: queueing message due to being "));
3235 DEBUGADD(2,( "in oplock break state.\n"));
3237 push_oplock_pending_smb_message(inbuf, length);
3241 new_fsp = open_file_shared1(conn, fname, &sbuf,FILE_WRITE_DATA,
3242 SET_OPEN_MODE(DOS_OPEN_RDWR),
3243 (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN),
3244 FILE_ATTRIBUTE_NORMAL,
3245 INTERNAL_OPEN_ONLY, &access_mode, &action);
3247 if (new_fsp == NULL)
3248 return(UNIXERROR(ERRDOS,ERRbadpath));
3249 ret = vfs_allocate_file_space(new_fsp, allocation_size);
3250 if (SMB_VFS_FSTAT(new_fsp,new_fsp->fd,&new_sbuf) != 0) {
3251 DEBUG(3,("call_trans2setfilepathinfo: fstat of fnum %d failed (%s)\n",
3252 new_fsp->fnum, strerror(errno)));
3255 close_file(new_fsp,True);
3257 ret = vfs_allocate_file_space(fsp, allocation_size);
3258 if (SMB_VFS_FSTAT(fsp,fd,&new_sbuf) != 0) {
3259 DEBUG(3,("call_trans2setfilepathinfo: fstat of fnum %d failed (%s)\n",
3260 fsp->fnum, strerror(errno)));
3265 return ERROR_NT(NT_STATUS_DISK_FULL);
3267 /* Allocate can truncate size... */
3268 size = get_file_size(new_sbuf);
3274 case SMB_FILE_END_OF_FILE_INFORMATION:
3275 case SMB_SET_FILE_END_OF_FILE_INFO:
3278 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
3280 size = IVAL(pdata,0);
3281 #ifdef LARGE_SMB_OFF_T
3282 size |= (((SMB_OFF_T)IVAL(pdata,4)) << 32);
3283 #else /* LARGE_SMB_OFF_T */
3284 if (IVAL(pdata,4) != 0) /* more than 32 bits? */
3285 return ERROR_DOS(ERRDOS,ERRunknownlevel);
3286 #endif /* LARGE_SMB_OFF_T */
3287 DEBUG(10,("call_trans2setfilepathinfo: Set end of file info for file %s to %.0f\n", fname, (double)size ));
3291 case SMB_FILE_DISPOSITION_INFORMATION:
3292 case SMB_SET_FILE_DISPOSITION_INFO: /* Set delete on close for open file. */
3294 BOOL delete_on_close;
3297 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
3299 delete_on_close = (CVAL(pdata,0) ? True : False);
3301 /* Just ignore this set on a path. */
3302 if (tran_call != TRANSACT2_SETFILEINFO)
3306 return(UNIXERROR(ERRDOS,ERRbadfid));
3308 status = set_delete_on_close_internal(fsp, delete_on_close, dosmode);
3310 if (NT_STATUS_V(status) != NT_STATUS_V(NT_STATUS_OK))
3311 return ERROR_NT(status);
3313 /* The set is across all open files on this dev/inode pair. */
3314 status =set_delete_on_close_over_all(fsp, delete_on_close);
3315 if (NT_STATUS_V(status) != NT_STATUS_V(NT_STATUS_OK))
3316 return ERROR_NT(status);
3321 case SMB_FILE_POSITION_INFORMATION:
3323 SMB_BIG_UINT position_information;
3326 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
3328 position_information = (SMB_BIG_UINT)IVAL(pdata,0);
3329 #ifdef LARGE_SMB_OFF_T
3330 position_information |= (((SMB_BIG_UINT)IVAL(pdata,4)) << 32);
3331 #else /* LARGE_SMB_OFF_T */
3332 if (IVAL(pdata,4) != 0) /* more than 32 bits? */
3333 return ERROR_DOS(ERRDOS,ERRunknownlevel);
3334 #endif /* LARGE_SMB_OFF_T */
3335 DEBUG(10,("call_trans2setfilepathinfo: Set file position information for file %s to %.0f\n",
3336 fname, (double)position_information ));
3338 fsp->position_information = position_information;
3343 * CIFS UNIX extensions.
3346 case SMB_SET_FILE_UNIX_BASIC:
3348 uint32 raw_unixmode;
3350 if (total_data < 100)
3351 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
3353 if(IVAL(pdata, 0) != SMB_SIZE_NO_CHANGE_LO &&
3354 IVAL(pdata, 4) != SMB_SIZE_NO_CHANGE_HI) {
3355 size=IVAL(pdata,0); /* first 8 Bytes are size */
3356 #ifdef LARGE_SMB_OFF_T
3357 size |= (((SMB_OFF_T)IVAL(pdata,4)) << 32);
3358 #else /* LARGE_SMB_OFF_T */
3359 if (IVAL(pdata,4) != 0) /* more than 32 bits? */
3360 return ERROR_DOS(ERRDOS,ERRunknownlevel);
3361 #endif /* LARGE_SMB_OFF_T */
3363 pdata+=24; /* ctime & st_blocks are not changed */
3364 tvs.actime = interpret_long_unix_date(pdata); /* access_time */
3365 tvs.modtime = interpret_long_unix_date(pdata+8); /* modification_time */
3367 set_owner = (uid_t)IVAL(pdata,0);
3369 set_grp = (gid_t)IVAL(pdata,0);
3371 raw_unixmode = IVAL(pdata,28);
3372 unixmode = unix_perms_from_wire(conn, &sbuf, raw_unixmode);
3373 dosmode = 0; /* Ensure dos mode change doesn't override this. */
3375 DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_BASIC: name = %s \
3376 size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n",
3377 fname, (double)size, (unsigned int)set_owner, (unsigned int)set_grp, (int)raw_unixmode));
3379 if (!VALID_STAT(sbuf)) {
3382 * The only valid use of this is to create character and block
3383 * devices, and named pipes. This is deprecated (IMHO) and
3384 * a new info level should be used for mknod. JRA.
3387 uint32 file_type = IVAL(pdata,0);
3388 #if defined(HAVE_MAKEDEV)
3389 uint32 dev_major = IVAL(pdata,4);
3390 uint32 dev_minor = IVAL(pdata,12);
3393 uid_t myuid = geteuid();
3394 gid_t mygid = getegid();
3395 SMB_DEV_T dev = (SMB_DEV_T)0;
3397 if (tran_call == TRANSACT2_SETFILEINFO)
3398 return(ERROR_DOS(ERRDOS,ERRnoaccess));
3400 if (raw_unixmode == SMB_MODE_NO_CHANGE)
3401 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
3403 #if defined(HAVE_MAKEDEV)
3404 dev = makedev(dev_major, dev_minor);
3407 /* We can only create as the owner/group we are. */
3409 if ((set_owner != myuid) && (set_owner != (uid_t)SMB_UID_NO_CHANGE))
3410 return(ERROR_DOS(ERRDOS,ERRnoaccess));
3411 if ((set_grp != mygid) && (set_grp != (gid_t)SMB_GID_NO_CHANGE))
3412 return(ERROR_DOS(ERRDOS,ERRnoaccess));
3414 switch (file_type) {
3415 #if defined(S_IFIFO)
3416 case UNIX_TYPE_FIFO:
3417 unixmode |= S_IFIFO;
3420 #if defined(S_IFSOCK)
3421 case UNIX_TYPE_SOCKET:
3422 unixmode |= S_IFSOCK;
3425 #if defined(S_IFCHR)
3426 case UNIX_TYPE_CHARDEV:
3427 unixmode |= S_IFCHR;
3430 #if defined(S_IFBLK)
3431 case UNIX_TYPE_BLKDEV:
3432 unixmode |= S_IFBLK;
3436 return(ERROR_DOS(ERRDOS,ERRnoaccess));
3439 DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_BASIC doing mknod dev %.0f mode \
3440 0%o for file %s\n", (double)dev, unixmode, fname ));
3442 /* Ok - do the mknod. */
3443 if (SMB_VFS_MKNOD(conn,fname, unixmode, dev) != 0)
3444 return(UNIXERROR(ERRDOS,ERRnoaccess));
3446 inherit_access_acl(conn, fname, unixmode);
3449 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
3454 * Deal with the UNIX specific mode set.
3457 if (raw_unixmode != SMB_MODE_NO_CHANGE) {
3458 DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_BASIC setting mode 0%o for file %s\n",
3459 (unsigned int)unixmode, fname ));
3460 if (SMB_VFS_CHMOD(conn,fname,unixmode) != 0)
3461 return(UNIXERROR(ERRDOS,ERRnoaccess));
3465 * Deal with the UNIX specific uid set.
3468 if ((set_owner != (uid_t)SMB_UID_NO_CHANGE) && (sbuf.st_uid != set_owner)) {
3469 DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_BASIC changing owner %u for file %s\n",
3470 (unsigned int)set_owner, fname ));
3471 if (SMB_VFS_CHOWN(conn,fname,set_owner, (gid_t)-1) != 0)
3472 return(UNIXERROR(ERRDOS,ERRnoaccess));
3476 * Deal with the UNIX specific gid set.
3479 if ((set_grp != (uid_t)SMB_GID_NO_CHANGE) && (sbuf.st_gid != set_grp)) {
3480 DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_BASIC changing group %u for file %s\n",
3481 (unsigned int)set_owner, fname ));
3482 if (SMB_VFS_CHOWN(conn,fname,(uid_t)-1, set_grp) != 0)
3483 return(UNIXERROR(ERRDOS,ERRnoaccess));
3488 case SMB_SET_FILE_UNIX_LINK:
3490 pstring link_target;
3491 char *newname = fname;
3493 /* Set a symbolic link. */
3494 /* Don't allow this if follow links is false. */
3496 if (!lp_symlinks(SNUM(conn)))
3497 return(ERROR_DOS(ERRDOS,ERRnoaccess));
3499 srvstr_pull(inbuf, link_target, pdata, sizeof(link_target), -1, STR_TERMINATE);
3501 /* !widelinks forces the target path to be within the share. */
3502 /* This means we can interpret the target as a pathname. */
3503 if (!lp_widelinks(SNUM(conn))) {
3505 char *last_dirp = NULL;
3507 unix_format(link_target);
3508 if (*link_target == '/') {
3509 /* No absolute paths allowed. */
3510 return(UNIXERROR(ERRDOS,ERRnoaccess));
3512 pstrcpy(rel_name, newname);
3513 last_dirp = strrchr_m(rel_name, '/');
3515 last_dirp[1] = '\0';
3517 pstrcpy(rel_name, "./");
3519 pstrcat(rel_name, link_target);
3521 if (!check_name(rel_name, conn)) {
3522 return(UNIXERROR(ERRDOS,ERRnoaccess));
3526 DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_LINK doing symlink %s -> %s\n",
3527 fname, link_target ));
3529 if (SMB_VFS_SYMLINK(conn,link_target,newname) != 0)
3530 return(UNIXERROR(ERRDOS,ERRnoaccess));
3532 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
3536 case SMB_SET_FILE_UNIX_HLINK:
3539 char *newname = fname;
3541 /* Set a hard link. */
3542 srvstr_get_path(inbuf, oldname, pdata, sizeof(oldname), -1, STR_TERMINATE, &status, False);
3543 if (!NT_STATUS_IS_OK(status)) {
3544 return ERROR_NT(status);
3547 DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_LINK doing hard link %s -> %s\n",
3550 status = hardlink_internals(conn, oldname, newname);
3551 if (!NT_STATUS_IS_OK(status)) {
3552 return ERROR_NT(status);
3556 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
3560 case SMB_FILE_RENAME_INFORMATION:
3569 if (total_data < 12)
3570 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
3572 overwrite = (CVAL(pdata,0) ? True : False);
3573 root_fid = IVAL(pdata,4);
3574 len = IVAL(pdata,8);
3575 srvstr_get_path(inbuf, newname, &pdata[12], sizeof(newname), len, 0, &status, False);
3576 if (!NT_STATUS_IS_OK(status)) {
3577 return ERROR_NT(status);
3580 /* Check the new name has no '/' characters. */
3581 if (strchr_m(newname, '/'))
3582 return ERROR_NT(NT_STATUS_NOT_SUPPORTED);
3584 RESOLVE_DFSPATH(newname, conn, inbuf, outbuf);
3586 /* Create the base directory. */
3587 pstrcpy(base_name, fname);
3588 p = strrchr_m(base_name, '/');
3591 /* Append the new name. */
3592 pstrcat(base_name, "/");
3593 pstrcat(base_name, newname);
3596 DEBUG(10,("call_trans2setfilepathinfo: SMB_FILE_RENAME_INFORMATION (fnum %d) %s -> %s\n",
3597 fsp->fnum, fsp->fsp_name, base_name ));
3598 status = rename_internals_fsp(conn, fsp, base_name, 0, overwrite);
3600 DEBUG(10,("call_trans2setfilepathinfo: SMB_FILE_RENAME_INFORMATION %s -> %s\n",
3602 status = rename_internals(conn, fname, base_name, 0, overwrite);
3604 if (!NT_STATUS_IS_OK(status)) {
3605 return ERROR_NT(status);
3607 process_pending_change_notify_queue((time_t)0);
3609 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
3613 return ERROR_DOS(ERRDOS,ERRunknownlevel);
3616 /* get some defaults (no modifications) if any info is zero or -1. */
3617 if (tvs.actime == (time_t)0 || tvs.actime == (time_t)-1)
3618 tvs.actime = sbuf.st_atime;
3620 if (tvs.modtime == (time_t)0 || tvs.modtime == (time_t)-1)
3621 tvs.modtime = sbuf.st_mtime;
3623 DEBUG(6,("actime: %s " , ctime(&tvs.actime)));
3624 DEBUG(6,("modtime: %s ", ctime(&tvs.modtime)));
3625 DEBUG(6,("size: %.0f ", (double)size));
3628 if (S_ISDIR(sbuf.st_mode))
3634 DEBUG(6,("dosmode: %x\n" , dosmode));
3636 if(!((info_level == SMB_SET_FILE_END_OF_FILE_INFO) ||
3637 (info_level == SMB_SET_FILE_ALLOCATION_INFO) ||
3638 (info_level == SMB_FILE_ALLOCATION_INFORMATION) ||
3639 (info_level == SMB_FILE_END_OF_FILE_INFORMATION))) {
3642 * Only do this test if we are not explicitly
3643 * changing the size of a file.
3646 size = get_file_size(sbuf);
3650 * Try and set the times, size and mode of this file -
3651 * if they are different from the current values
3653 if (sbuf.st_mtime != tvs.modtime || sbuf.st_atime != tvs.actime) {
3656 * This was a setfileinfo on an open file.
3657 * NT does this a lot. It's actually pointless
3658 * setting the time here, as it will be overwritten
3659 * on the next write, so we save the request
3660 * away and will set it on file close. JRA.
3663 if (tvs.modtime != (time_t)0 && tvs.modtime != (time_t)-1) {
3664 DEBUG(10,("call_trans2setfilepathinfo: setting pending modtime to %s\n", ctime(&tvs.modtime) ));
3665 fsp->pending_modtime = tvs.modtime;
3670 DEBUG(10,("call_trans2setfilepathinfo: setting utimes to modified values.\n"));
3672 if(file_utime(conn, fname, &tvs)!=0)
3673 return(UNIXERROR(ERRDOS,ERRnoaccess));
3677 /* check the mode isn't different, before changing it */
3678 if ((dosmode != 0) && (dosmode != dos_mode(conn, fname, &sbuf))) {
3680 DEBUG(10,("call_trans2setfilepathinfo: file %s : setting dos mode %x\n", fname, dosmode ));
3682 if(file_set_dosmode(conn, fname, dosmode, NULL)) {
3683 DEBUG(2,("file_set_dosmode of %s failed (%s)\n", fname, strerror(errno)));
3684 return(UNIXERROR(ERRDOS,ERRnoaccess));
3688 if (size != get_file_size(sbuf)) {
3692 DEBUG(10,("call_trans2setfilepathinfo: file %s : setting new size to %.0f\n",
3693 fname, (double)size ));
3696 files_struct *new_fsp = NULL;
3697 int access_mode = 0;
3700 if(global_oplock_break) {
3701 /* Queue this file modify as we are the process of an oplock break. */
3703 DEBUG(2,("call_trans2setfilepathinfo: queueing message due to being "));
3704 DEBUGADD(2,( "in oplock break state.\n"));
3706 push_oplock_pending_smb_message(inbuf, length);
3710 new_fsp = open_file_shared(conn, fname, &sbuf,
3711 SET_OPEN_MODE(DOS_OPEN_RDWR),
3712 (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN),
3713 FILE_ATTRIBUTE_NORMAL,
3714 INTERNAL_OPEN_ONLY, &access_mode, &action);
3716 if (new_fsp == NULL)
3717 return(UNIXERROR(ERRDOS,ERRbadpath));
3718 ret = vfs_set_filelen(new_fsp, size);
3719 close_file(new_fsp,True);
3721 ret = vfs_set_filelen(fsp, size);
3725 return (UNIXERROR(ERRHRD,ERRdiskfull));
3729 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
3734 /****************************************************************************
3735 Reply to a TRANS2_MKDIR (make directory with extended attributes).
3736 ****************************************************************************/
3738 static int call_trans2mkdir(connection_struct *conn,
3739 char *inbuf, char *outbuf, int length, int bufsize,
3740 char **pparams, int total_params, char **ppdata, int total_data)
3742 char *params = *pparams;
3745 SMB_STRUCT_STAT sbuf;
3746 BOOL bad_path = False;
3747 NTSTATUS status = NT_STATUS_OK;
3749 if (!CAN_WRITE(conn))
3750 return ERROR_DOS(ERRSRV,ERRaccess);
3752 if (total_params < 4)
3753 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
3755 srvstr_get_path(inbuf, directory, ¶ms[4], sizeof(directory), -1, STR_TERMINATE, &status, False);
3756 if (!NT_STATUS_IS_OK(status)) {
3757 return ERROR_NT(status);
3760 DEBUG(3,("call_trans2mkdir : name = %s\n", directory));
3762 unix_convert(directory,conn,0,&bad_path,&sbuf);
3764 return ERROR_NT(NT_STATUS_OBJECT_PATH_NOT_FOUND);
3766 if (check_name(directory,conn))
3767 ret = vfs_MkDir(conn,directory,unix_mode(conn,aDIR,directory));
3770 DEBUG(5,("call_trans2mkdir error (%s)\n", strerror(errno)));
3771 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRnoaccess);
3774 /* Realloc the parameter and data sizes */
3775 params = Realloc(*pparams,2);
3777 return ERROR_DOS(ERRDOS,ERRnomem);
3782 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
3787 /****************************************************************************
3788 Reply to a TRANS2_FINDNOTIFYFIRST (start monitoring a directory for changes).
3789 We don't actually do this - we just send a null response.
3790 ****************************************************************************/
3792 static int call_trans2findnotifyfirst(connection_struct *conn,
3793 char *inbuf, char *outbuf, int length, int bufsize,
3794 char **pparams, int total_params, char **ppdata, int total_data)
3796 static uint16 fnf_handle = 257;
3797 char *params = *pparams;
3800 if (total_params < 6)
3801 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
3803 info_level = SVAL(params,4);
3804 DEBUG(3,("call_trans2findnotifyfirst - info_level %d\n", info_level));
3806 switch (info_level) {
3811 return ERROR_DOS(ERRDOS,ERRunknownlevel);
3814 /* Realloc the parameter and data sizes */
3815 params = Realloc(*pparams,6);
3817 return ERROR_DOS(ERRDOS,ERRnomem);
3820 SSVAL(params,0,fnf_handle);
3821 SSVAL(params,2,0); /* No changes */
3822 SSVAL(params,4,0); /* No EA errors */
3829 send_trans2_replies(outbuf, bufsize, params, 6, *ppdata, 0);
3834 /****************************************************************************
3835 Reply to a TRANS2_FINDNOTIFYNEXT (continue monitoring a directory for
3836 changes). Currently this does nothing.
3837 ****************************************************************************/
3839 static int call_trans2findnotifynext(connection_struct *conn,
3840 char *inbuf, char *outbuf, int length, int bufsize,
3841 char **pparams, int total_params, char **ppdata, int total_data)
3843 char *params = *pparams;
3845 DEBUG(3,("call_trans2findnotifynext\n"));
3847 /* Realloc the parameter and data sizes */
3848 params = Realloc(*pparams,4);
3850 return ERROR_DOS(ERRDOS,ERRnomem);
3853 SSVAL(params,0,0); /* No changes */
3854 SSVAL(params,2,0); /* No EA errors */
3856 send_trans2_replies(outbuf, bufsize, params, 4, *ppdata, 0);
3861 /****************************************************************************
3862 Reply to a TRANS2_GET_DFS_REFERRAL - Shirish Kalele <kalele@veritas.com>.
3863 ****************************************************************************/
3865 static int call_trans2getdfsreferral(connection_struct *conn, char* inbuf,
3866 char* outbuf, int length, int bufsize,
3867 char **pparams, int total_params, char **ppdata, int total_data)
3869 char *params = *pparams;
3872 int max_referral_level;
3874 DEBUG(10,("call_trans2getdfsreferral\n"));
3876 if (total_params < 2)
3877 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
3879 max_referral_level = SVAL(params,0);
3881 if(!lp_host_msdfs())
3882 return ERROR_DOS(ERRDOS,ERRbadfunc);
3884 srvstr_pull(inbuf, pathname, ¶ms[2], sizeof(pathname), -1, STR_TERMINATE);
3885 if((reply_size = setup_dfs_referral(conn, pathname,max_referral_level,ppdata)) < 0)
3886 return UNIXERROR(ERRDOS,ERRbadfile);
3888 SSVAL(outbuf,smb_flg2,SVAL(outbuf,smb_flg2) | FLAGS2_DFS_PATHNAMES);
3889 send_trans2_replies(outbuf,bufsize,0,0,*ppdata,reply_size);
3894 #define LMCAT_SPL 0x53
3895 #define LMFUNC_GETJOBID 0x60
3897 /****************************************************************************
3898 Reply to a TRANS2_IOCTL - used for OS/2 printing.
3899 ****************************************************************************/
3901 static int call_trans2ioctl(connection_struct *conn, char* inbuf,
3902 char* outbuf, int length, int bufsize,
3903 char **pparams, int total_params, char **ppdata, int total_data)
3905 char *pdata = *ppdata;
3906 files_struct *fsp = file_fsp(inbuf,smb_vwv15);
3908 /* check for an invalid fid before proceeding */
3911 return(ERROR_DOS(ERRDOS,ERRbadfid));
3913 if ((SVAL(inbuf,(smb_setup+4)) == LMCAT_SPL) &&
3914 (SVAL(inbuf,(smb_setup+6)) == LMFUNC_GETJOBID)) {
3915 pdata = Realloc(*ppdata, 32);
3917 return ERROR_DOS(ERRDOS,ERRnomem);
3920 /* NOTE - THIS IS ASCII ONLY AT THE MOMENT - NOT SURE IF OS/2
3921 CAN ACCEPT THIS IN UNICODE. JRA. */
3923 SSVAL(pdata,0,fsp->rap_print_jobid); /* Job number */
3924 srvstr_push( outbuf, pdata + 2, global_myname(), 15, STR_ASCII|STR_TERMINATE); /* Our NetBIOS name */
3925 srvstr_push( outbuf, pdata+18, lp_servicename(SNUM(conn)), 13, STR_ASCII|STR_TERMINATE); /* Service name */
3926 send_trans2_replies(outbuf,bufsize,*pparams,0,*ppdata,32);
3929 DEBUG(2,("Unknown TRANS2_IOCTL\n"));
3930 return ERROR_DOS(ERRSRV,ERRerror);
3934 /****************************************************************************
3935 Reply to a SMBfindclose (stop trans2 directory search).
3936 ****************************************************************************/
3938 int reply_findclose(connection_struct *conn,
3939 char *inbuf,char *outbuf,int length,int bufsize)
3942 int dptr_num=SVALS(inbuf,smb_vwv0);
3943 START_PROFILE(SMBfindclose);
3945 DEBUG(3,("reply_findclose, dptr_num = %d\n", dptr_num));
3947 dptr_close(&dptr_num);
3949 outsize = set_message(outbuf,0,0,True);
3951 DEBUG(3,("SMBfindclose dptr_num = %d\n", dptr_num));
3953 END_PROFILE(SMBfindclose);
3957 /****************************************************************************
3958 Reply to a SMBfindnclose (stop FINDNOTIFYFIRST directory search).
3959 ****************************************************************************/
3961 int reply_findnclose(connection_struct *conn,
3962 char *inbuf,char *outbuf,int length,int bufsize)
3966 START_PROFILE(SMBfindnclose);
3968 dptr_num = SVAL(inbuf,smb_vwv0);
3970 DEBUG(3,("reply_findnclose, dptr_num = %d\n", dptr_num));
3972 /* We never give out valid handles for a
3973 findnotifyfirst - so any dptr_num is ok here.
3976 outsize = set_message(outbuf,0,0,True);
3978 DEBUG(3,("SMB_findnclose dptr_num = %d\n", dptr_num));
3980 END_PROFILE(SMBfindnclose);
3984 /****************************************************************************
3985 Reply to a SMBtranss2 - just ignore it!
3986 ****************************************************************************/
3988 int reply_transs2(connection_struct *conn,
3989 char *inbuf,char *outbuf,int length,int bufsize)
3991 START_PROFILE(SMBtranss2);
3992 DEBUG(4,("Ignoring transs2 of length %d\n",length));
3993 END_PROFILE(SMBtranss2);
3997 /****************************************************************************
3998 Reply to a SMBtrans2.
3999 ****************************************************************************/
4001 int reply_trans2(connection_struct *conn,
4002 char *inbuf,char *outbuf,int length,int bufsize)
4005 unsigned int total_params = SVAL(inbuf, smb_tpscnt);
4006 unsigned int total_data =SVAL(inbuf, smb_tdscnt);
4008 unsigned int max_param_reply = SVAL(inbuf, smb_mprcnt);
4009 unsigned int max_data_reply = SVAL(inbuf, smb_mdrcnt);
4010 unsigned int max_setup_fields = SVAL(inbuf, smb_msrcnt);
4011 BOOL close_tid = BITSETW(inbuf+smb_flags,0);
4012 BOOL no_final_response = BITSETW(inbuf+smb_flags,1);
4013 int32 timeout = IVALS(inbuf,smb_timeout);
4015 unsigned int suwcnt = SVAL(inbuf, smb_suwcnt);
4016 unsigned int tran_call = SVAL(inbuf, smb_setup0);
4017 char *params = NULL, *data = NULL;
4018 unsigned int num_params, num_params_sofar, num_data, num_data_sofar;
4019 START_PROFILE(SMBtrans2);
4021 if(global_oplock_break && (tran_call == TRANSACT2_OPEN)) {
4022 /* Queue this open message as we are the process of an
4025 DEBUG(2,("reply_trans2: queueing message trans2open due to being "));
4026 DEBUGADD(2,( "in oplock break state.\n"));
4028 push_oplock_pending_smb_message(inbuf, length);
4029 END_PROFILE(SMBtrans2);
4033 if (IS_IPC(conn) && (tran_call != TRANSACT2_OPEN)
4034 && (tran_call != TRANSACT2_GET_DFS_REFERRAL)) {
4035 END_PROFILE(SMBtrans2);
4036 return ERROR_DOS(ERRSRV,ERRaccess);
4039 outsize = set_message(outbuf,0,0,True);
4041 /* All trans2 messages we handle have smb_sucnt == 1 - ensure this
4042 is so as a sanity check */
4045 * Need to have rc=0 for ioctl to get job id for OS/2.
4046 * Network printing will fail if function is not successful.
4047 * Similar function in reply.c will be used if protocol
4048 * is LANMAN1.0 instead of LM1.2X002.
4049 * Until DosPrintSetJobInfo with PRJINFO3 is supported,
4050 * outbuf doesn't have to be set(only job id is used).
4052 if ( (suwcnt == 4) && (tran_call == TRANSACT2_IOCTL) &&
4053 (SVAL(inbuf,(smb_setup+4)) == LMCAT_SPL) &&
4054 (SVAL(inbuf,(smb_setup+6)) == LMFUNC_GETJOBID)) {
4055 DEBUG(2,("Got Trans2 DevIOctl jobid\n"));
4057 DEBUG(2,("Invalid smb_sucnt in trans2 call(%u)\n",suwcnt));
4058 DEBUG(2,("Transaction is %d\n",tran_call));
4059 END_PROFILE(SMBtrans2);
4060 ERROR_DOS(ERRDOS,ERRinvalidparam);
4064 /* Allocate the space for the maximum needed parameters and data */
4065 if (total_params > 0)
4066 params = (char *)malloc(total_params);
4068 data = (char *)malloc(total_data);
4070 if ((total_params && !params) || (total_data && !data)) {
4071 DEBUG(2,("Out of memory in reply_trans2\n"));
4074 END_PROFILE(SMBtrans2);
4075 return ERROR_DOS(ERRDOS,ERRnomem);
4078 /* Copy the param and data bytes sent with this request into
4079 the params buffer */
4080 num_params = num_params_sofar = SVAL(inbuf,smb_pscnt);
4081 num_data = num_data_sofar = SVAL(inbuf, smb_dscnt);
4083 if (num_params > total_params || num_data > total_data)
4084 exit_server("invalid params in reply_trans2");
4087 unsigned int psoff = SVAL(inbuf, smb_psoff);
4088 if ((psoff + num_params < psoff) || (psoff + num_params < num_params))
4090 if ((smb_base(inbuf) + psoff + num_params > inbuf + length) ||
4091 (smb_base(inbuf) + psoff + num_params < smb_base(inbuf)))
4093 memcpy( params, smb_base(inbuf) + psoff, num_params);
4096 unsigned int dsoff = SVAL(inbuf, smb_dsoff);
4097 if ((dsoff + num_data < dsoff) || (dsoff + num_data < num_data))
4099 if ((smb_base(inbuf) + dsoff + num_data > inbuf + length) ||
4100 (smb_base(inbuf) + dsoff + num_data < smb_base(inbuf)))
4102 memcpy( data, smb_base(inbuf) + dsoff, num_data);
4105 srv_signing_trans_start(SVAL(inbuf,smb_mid));
4107 if(num_data_sofar < total_data || num_params_sofar < total_params) {
4108 /* We need to send an interim response then receive the rest
4109 of the parameter/data bytes */
4110 outsize = set_message(outbuf,0,0,True);
4111 srv_signing_trans_stop();
4112 if (!send_smb(smbd_server_fd(),outbuf))
4113 exit_server("reply_trans2: send_smb failed.");
4115 while (num_data_sofar < total_data ||
4116 num_params_sofar < total_params) {
4118 unsigned int param_disp;
4119 unsigned int param_off;
4120 unsigned int data_disp;
4121 unsigned int data_off;
4123 ret = receive_next_smb(inbuf,bufsize,SMB_SECONDARY_WAIT);
4126 * The sequence number for the trans reply is always
4127 * based on the last secondary received.
4130 srv_signing_trans_start(SVAL(inbuf,smb_mid));
4133 (CVAL(inbuf, smb_com) != SMBtranss2)) || !ret) {
4134 outsize = set_message(outbuf,0,0,True);
4136 DEBUG(0,("reply_trans2: Invalid secondary trans2 packet\n"));
4138 DEBUG(0,("reply_trans2: %s in getting secondary trans2 response.\n",
4139 (smb_read_error == READ_ERROR) ? "error" : "timeout" ));
4143 /* Revise total_params and total_data in case
4144 they have changed downwards */
4145 if (SVAL(inbuf, smb_tpscnt) < total_params)
4146 total_params = SVAL(inbuf, smb_tpscnt);
4147 if (SVAL(inbuf, smb_tdscnt) < total_data)
4148 total_data = SVAL(inbuf, smb_tdscnt);
4150 num_params = SVAL(inbuf,smb_spscnt);
4151 param_off = SVAL(inbuf, smb_spsoff);
4152 param_disp = SVAL(inbuf, smb_spsdisp);
4153 num_params_sofar += num_params;
4155 num_data = SVAL(inbuf, smb_sdscnt);
4156 data_off = SVAL(inbuf, smb_sdsoff);
4157 data_disp = SVAL(inbuf, smb_sdsdisp);
4158 num_data_sofar += num_data;
4160 if (num_params_sofar > total_params || num_data_sofar > total_data)
4164 if (param_disp + num_params >= total_params)
4166 if ((param_disp + num_params < param_disp) ||
4167 (param_disp + num_params < num_params))
4169 if (param_disp > total_params)
4171 if ((smb_base(inbuf) + param_off + num_params >= inbuf + bufsize) ||
4172 (smb_base(inbuf) + param_off + num_params < smb_base(inbuf)))
4174 if (params + param_disp < params)
4177 memcpy( ¶ms[param_disp], smb_base(inbuf) + param_off, num_params);
4180 if (data_disp + num_data >= total_data)
4182 if ((data_disp + num_data < data_disp) ||
4183 (data_disp + num_data < num_data))
4185 if (data_disp > total_data)
4187 if ((smb_base(inbuf) + data_off + num_data >= inbuf + bufsize) ||
4188 (smb_base(inbuf) + data_off + num_data < smb_base(inbuf)))
4190 if (data + data_disp < data)
4193 memcpy( &data[data_disp], smb_base(inbuf) + data_off, num_data);
4198 if (Protocol >= PROTOCOL_NT1) {
4199 SSVAL(outbuf,smb_flg2,SVAL(outbuf,smb_flg2) | 0x40); /* IS_LONG_NAME */
4202 /* Now we must call the relevant TRANS2 function */
4204 case TRANSACT2_OPEN:
4205 START_PROFILE_NESTED(Trans2_open);
4206 outsize = call_trans2open(conn, inbuf, outbuf, bufsize,
4207 ¶ms, total_params, &data, total_data);
4208 END_PROFILE_NESTED(Trans2_open);
4211 case TRANSACT2_FINDFIRST:
4212 START_PROFILE_NESTED(Trans2_findfirst);
4213 outsize = call_trans2findfirst(conn, inbuf, outbuf, bufsize,
4214 ¶ms, total_params, &data, total_data);
4215 END_PROFILE_NESTED(Trans2_findfirst);
4218 case TRANSACT2_FINDNEXT:
4219 START_PROFILE_NESTED(Trans2_findnext);
4220 outsize = call_trans2findnext(conn, inbuf, outbuf, length, bufsize,
4221 ¶ms, total_params, &data, total_data);
4222 END_PROFILE_NESTED(Trans2_findnext);
4225 case TRANSACT2_QFSINFO:
4226 START_PROFILE_NESTED(Trans2_qfsinfo);
4227 outsize = call_trans2qfsinfo(conn, inbuf, outbuf, length, bufsize,
4228 ¶ms, total_params, &data, total_data);
4229 END_PROFILE_NESTED(Trans2_qfsinfo);
4232 #ifdef HAVE_SYS_QUOTAS
4233 case TRANSACT2_SETFSINFO:
4234 START_PROFILE_NESTED(Trans2_setfsinfo);
4235 outsize = call_trans2setfsinfo(conn, inbuf, outbuf, length, bufsize,
4236 ¶ms, total_params, &data, total_data);
4237 END_PROFILE_NESTED(Trans2_setfsinfo);
4240 case TRANSACT2_QPATHINFO:
4241 case TRANSACT2_QFILEINFO:
4242 START_PROFILE_NESTED(Trans2_qpathinfo);
4243 outsize = call_trans2qfilepathinfo(conn, inbuf, outbuf, length, bufsize,
4244 ¶ms, total_params, &data, total_data);
4245 END_PROFILE_NESTED(Trans2_qpathinfo);
4247 case TRANSACT2_SETPATHINFO:
4248 case TRANSACT2_SETFILEINFO:
4249 START_PROFILE_NESTED(Trans2_setpathinfo);
4250 outsize = call_trans2setfilepathinfo(conn, inbuf, outbuf, length, bufsize,
4251 ¶ms, total_params, &data, total_data);
4252 END_PROFILE_NESTED(Trans2_setpathinfo);
4255 case TRANSACT2_FINDNOTIFYFIRST:
4256 START_PROFILE_NESTED(Trans2_findnotifyfirst);
4257 outsize = call_trans2findnotifyfirst(conn, inbuf, outbuf, length, bufsize,
4258 ¶ms, total_params, &data, total_data);
4259 END_PROFILE_NESTED(Trans2_findnotifyfirst);
4262 case TRANSACT2_FINDNOTIFYNEXT:
4263 START_PROFILE_NESTED(Trans2_findnotifynext);
4264 outsize = call_trans2findnotifynext(conn, inbuf, outbuf, length, bufsize,
4265 ¶ms, total_params, &data, total_data);
4266 END_PROFILE_NESTED(Trans2_findnotifynext);
4268 case TRANSACT2_MKDIR:
4269 START_PROFILE_NESTED(Trans2_mkdir);
4270 outsize = call_trans2mkdir(conn, inbuf, outbuf, length, bufsize,
4271 ¶ms, total_params, &data, total_data);
4272 END_PROFILE_NESTED(Trans2_mkdir);
4275 case TRANSACT2_GET_DFS_REFERRAL:
4276 START_PROFILE_NESTED(Trans2_get_dfs_referral);
4277 outsize = call_trans2getdfsreferral(conn,inbuf,outbuf,length, bufsize,
4278 ¶ms, total_params, &data, total_data);
4279 END_PROFILE_NESTED(Trans2_get_dfs_referral);
4281 case TRANSACT2_IOCTL:
4282 START_PROFILE_NESTED(Trans2_ioctl);
4283 outsize = call_trans2ioctl(conn,inbuf,outbuf,length, bufsize,
4284 ¶ms, total_params, &data, total_data);
4285 END_PROFILE_NESTED(Trans2_ioctl);
4288 /* Error in request */
4289 DEBUG(2,("Unknown request %d in trans2 call\n", tran_call));
4292 END_PROFILE(SMBtrans2);
4293 srv_signing_trans_stop();
4294 return ERROR_DOS(ERRSRV,ERRerror);
4297 /* As we do not know how many data packets will need to be
4298 returned here the various call_trans2xxxx calls
4299 must send their own. Thus a call_trans2xxx routine only
4300 returns a value other than -1 when it wants to send
4304 srv_signing_trans_stop();
4308 END_PROFILE(SMBtrans2);
4309 return outsize; /* If a correct response was needed the
4310 call_trans2xxx calls have already sent
4311 it. If outsize != -1 then it is returning */
4315 srv_signing_trans_stop();
4318 END_PROFILE(SMBtrans2);
4319 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);