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)
35 /* given a stat buffer return the allocated size on disk, taking into
36 account sparse files */
37 SMB_BIG_UINT get_allocation_size(files_struct *fsp, SMB_STRUCT_STAT *sbuf)
40 #if defined(HAVE_STAT_ST_BLOCKS) && defined(STAT_ST_BLOCKSIZE)
41 ret = (SMB_BIG_UINT)STAT_ST_BLOCKSIZE * (SMB_BIG_UINT)sbuf->st_blocks;
43 ret = (SMB_BIG_UINT)get_file_size(*sbuf);
45 if (!ret && fsp && fsp->initial_allocation_size)
46 ret = fsp->initial_allocation_size;
47 ret = SMB_ROUNDUP(ret,SMB_ROUNDUP_ALLOCATION_SIZE);
51 /****************************************************************************
52 Utility functions for dealing with extended attributes.
53 ****************************************************************************/
55 static const char *prohibited_ea_names[] = {
56 SAMBA_POSIX_INHERITANCE_EA_NAME,
57 SAMBA_XATTR_DOS_ATTRIB,
61 /****************************************************************************
62 Refuse to allow clients to overwrite our private xattrs.
63 ****************************************************************************/
65 static BOOL samba_private_attr_name(const char *unix_ea_name)
69 for (i = 0; prohibited_ea_names[i]; i++) {
70 if (strequal( prohibited_ea_names[i], unix_ea_name))
77 struct ea_list *next, *prev;
81 /****************************************************************************
82 Get one EA value. Fill in a struct ea_struct.
83 ****************************************************************************/
85 static BOOL get_ea_value(TALLOC_CTX *mem_ctx, connection_struct *conn, files_struct *fsp,
86 const char *fname, char *ea_name, struct ea_struct *pea)
88 /* Get the value of this xattr. Max size is 64k. */
89 size_t attr_size = 256;
95 val = talloc_realloc(mem_ctx, val, attr_size);
100 if (fsp && fsp->fd != -1) {
101 sizeret = SMB_VFS_FGETXATTR(fsp, fsp->fd, ea_name, val, attr_size);
103 sizeret = SMB_VFS_GETXATTR(conn, fname, ea_name, val, attr_size);
106 if (sizeret == -1 && errno == ERANGE && attr_size != 65536) {
115 DEBUG(10,("get_ea_value: EA %s is of length %d: ", ea_name, sizeret));
116 dump_data(10, val, sizeret);
119 if (strnequal(ea_name, "user.", 5)) {
120 pea->name = &ea_name[5];
124 pea->value.data = val;
125 pea->value.length = (size_t)sizeret;
129 /****************************************************************************
130 Return a linked list of the total EA's. Plus the total size
131 ****************************************************************************/
133 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)
135 /* Get a list of all xattrs. Max namesize is 64k. */
136 size_t ea_namelist_size = 1024;
141 struct ea_list *ea_list_head = NULL;
145 if (!lp_ea_support(SNUM(conn))) {
149 for (i = 0, ea_namelist = talloc(mem_ctx, ea_namelist_size); i < 6;
150 ea_namelist = talloc_realloc(mem_ctx, ea_namelist, ea_namelist_size), i++) {
151 if (fsp && fsp->fd != -1) {
152 sizeret = SMB_VFS_FLISTXATTR(fsp, fsp->fd, ea_namelist, ea_namelist_size);
154 sizeret = SMB_VFS_LISTXATTR(conn, fname, ea_namelist, ea_namelist_size);
157 if (sizeret == -1 && errno == ERANGE) {
158 ea_namelist_size *= 2;
167 DEBUG(10,("get_ea_list: ea_namelist size = %d\n", sizeret ));
170 for (p = ea_namelist; p - ea_namelist < sizeret; p += strlen(p) + 1) {
171 struct ea_list *listp, *tmp;
173 if (strnequal(p, "system.", 7) || samba_private_attr_name(p))
176 listp = talloc(mem_ctx, sizeof(struct ea_list));
180 if (!get_ea_value(mem_ctx, conn, fsp, fname, p, &listp->ea)) {
186 push_ascii_fstring(dos_ea_name, listp->ea.name);
187 *pea_total_len += 4 + strlen(dos_ea_name) + 1 + listp->ea.value.length;
188 DEBUG(10,("get_ea_list: total_len = %u, %s, val len = %u\n",
189 *pea_total_len, dos_ea_name,
190 (unsigned int)listp->ea.value.length ));
192 DLIST_ADD_END(ea_list_head, listp, tmp);
194 /* Add on 4 for total length. */
195 if (*pea_total_len) {
200 DEBUG(10,("get_ea_list: total_len = %u\n", *pea_total_len));
204 /****************************************************************************
205 Fill a qfilepathinfo buffer with EA's. Returns the length of the buffer
207 ****************************************************************************/
209 static unsigned int fill_ea_buffer(char *pdata, unsigned int total_data_size,
210 connection_struct *conn, files_struct *fsp, const char *fname)
212 unsigned int ret_data_size = 4;
216 struct ea_list *ea_list;
218 SMB_ASSERT(total_data_size >= 4);
221 if (!lp_ea_support(SNUM(conn))) {
224 mem_ctx = talloc_init("fill_ea_buffer");
229 ea_list = get_ea_list(mem_ctx, conn, fsp, fname, &total_ea_len);
231 talloc_destroy(mem_ctx);
235 if (total_ea_len > total_data_size) {
236 talloc_destroy(mem_ctx);
240 for (p = pdata + 4; ea_list; ea_list = ea_list->next) {
243 push_ascii_fstring(dos_ea_name, ea_list->ea.name);
244 dos_namelen = strlen(dos_ea_name);
245 if (dos_namelen > 255 || dos_namelen == 0) {
248 if (ea_list->ea.value.length > 65535) {
251 if (4 + dos_namelen + 1 + ea_list->ea.value.length > total_data_size) {
255 /* We know we have room. */
256 SCVAL(p,0,ea_list->ea.flags);
257 SCVAL(p,1,dos_namelen);
258 SSVAL(p,2,ea_list->ea.value.length);
259 fstrcpy(p+4, dos_ea_name);
260 memcpy( p + 4 + dos_namelen + 1, ea_list->ea.value.data, ea_list->ea.value.length);
262 total_data_size -= 4 + dos_namelen + 1 + ea_list->ea.value.length;
263 p += 4 + dos_namelen + 1 + ea_list->ea.value.length;
266 ret_data_size = PTR_DIFF(p, pdata);
267 DEBUG(10,("fill_ea_buffer: data_size = %u, total_ea_len = %u\n",
268 ret_data_size, total_ea_len ));
269 talloc_destroy(mem_ctx);
270 SIVAL(pdata,0,ret_data_size);
271 return ret_data_size;
274 static unsigned int estimate_ea_size(connection_struct *conn, files_struct *fsp, const char *fname)
276 size_t total_ea_len = 0;
277 TALLOC_CTX *mem_ctx = NULL;
279 if (!lp_ea_support(SNUM(conn))) {
282 mem_ctx = talloc_init("estimate_ea_size");
283 (void)get_ea_list(mem_ctx, conn, fsp, fname, &total_ea_len);
284 talloc_destroy(mem_ctx);
288 /****************************************************************************
289 Ensure the EA name is case insensitive by matching any existing EA name.
290 ****************************************************************************/
292 static void canonicalize_ea_name(connection_struct *conn, files_struct *fsp, const char *fname, fstring unix_ea_name)
295 TALLOC_CTX *mem_ctx = talloc_init("canonicalize_ea_name");
296 struct ea_list *ea_list = get_ea_list(mem_ctx, conn, fsp, fname, &total_ea_len);
298 for (; ea_list; ea_list = ea_list->next) {
299 if (strequal(&unix_ea_name[5], ea_list->ea.name)) {
300 DEBUG(10,("canonicalize_ea_name: %s -> %s\n",
301 &unix_ea_name[5], ea_list->ea.name));
302 safe_strcpy(&unix_ea_name[5], ea_list->ea.name, sizeof(fstring)-6);
306 talloc_destroy(mem_ctx);
309 /****************************************************************************
310 Set or delete an extended attribute.
311 ****************************************************************************/
313 static NTSTATUS set_ea(connection_struct *conn, files_struct *fsp, const char *fname,
314 char *pdata, int total_data)
316 unsigned int namelen;
319 fstring unix_ea_name;
321 if (!lp_ea_support(SNUM(conn))) {
322 return NT_STATUS_EAS_NOT_SUPPORTED;
325 if (total_data < 8) {
326 return NT_STATUS_INVALID_PARAMETER;
329 if (IVAL(pdata,0) > total_data) {
330 DEBUG(10,("set_ea: bad total data size (%u) > %u\n", IVAL(pdata,0), (unsigned int)total_data));
331 return NT_STATUS_INVALID_PARAMETER;
335 namelen = CVAL(pdata,1);
336 ealen = SVAL(pdata,2);
338 if (total_data < 8 + namelen + 1 + ealen) {
339 DEBUG(10,("set_ea: bad total data size (%u) < 8 + namelen (%u) + 1 + ealen (%u)\n",
340 (unsigned int)total_data, namelen, ealen));
341 return NT_STATUS_INVALID_PARAMETER;
344 if (pdata[namelen] != '\0') {
345 DEBUG(10,("set_ea: ea name not null terminated\n"));
346 return NT_STATUS_INVALID_PARAMETER;
349 fstrcpy(unix_ea_name, "user."); /* All EA's must start with user. */
350 pull_ascii(&unix_ea_name[5], pdata, sizeof(fstring) - 5, -1, STR_TERMINATE);
351 pdata += (namelen + 1);
353 canonicalize_ea_name(conn, fsp, fname, unix_ea_name);
355 DEBUG(10,("set_ea: ea_name %s ealen = %u\n", unix_ea_name, ealen));
357 DEBUG(10,("set_ea: data :\n"));
358 dump_data(10, pdata, ealen);
361 if (samba_private_attr_name(unix_ea_name)) {
362 DEBUG(10,("set_ea: ea name %s is a private Samba name.\n", unix_ea_name));
363 return NT_STATUS_ACCESS_DENIED;
367 /* Remove the attribute. */
368 if (fsp && (fsp->fd != -1)) {
369 DEBUG(10,("set_ea: deleting ea name %s on file %s by file descriptor.\n",
370 unix_ea_name, fsp->fsp_name));
371 ret = SMB_VFS_FREMOVEXATTR(fsp, fsp->fd, unix_ea_name);
373 DEBUG(10,("set_ea: deleting ea name %s on file %s.\n",
374 unix_ea_name, fname));
375 ret = SMB_VFS_REMOVEXATTR(conn, fname, unix_ea_name);
378 /* Removing a non existent attribute always succeeds. */
379 if (ret == -1 && errno == ENOATTR) {
380 DEBUG(10,("set_ea: deleting ea name %s didn't exist - succeeding by default.\n", unix_ea_name));
385 if (fsp && (fsp->fd != -1)) {
386 DEBUG(10,("set_ea: setting ea name %s on file %s by file descriptor.\n",
387 unix_ea_name, fsp->fsp_name));
388 ret = SMB_VFS_FSETXATTR(fsp, fsp->fd, unix_ea_name, pdata, ealen, 0);
390 DEBUG(10,("set_ea: setting ea name %s on file %s.\n",
391 unix_ea_name, fname));
392 ret = SMB_VFS_SETXATTR(conn, fname, unix_ea_name, pdata, ealen, 0);
398 if (errno == ENOTSUP) {
399 return NT_STATUS_EAS_NOT_SUPPORTED;
402 return map_nt_error_from_unix(errno);
408 /****************************************************************************
409 Send the required number of replies back.
410 We assume all fields other than the data fields are
411 set correctly for the type of call.
412 HACK ! Always assumes smb_setup field is zero.
413 ****************************************************************************/
415 static int send_trans2_replies(char *outbuf,
422 /* As we are using a protocol > LANMAN1 then the max_send
423 variable must have been set in the sessetupX call.
424 This takes precedence over the max_xmit field in the
425 global struct. These different max_xmit variables should
426 be merged as this is now too confusing */
429 int data_to_send = datasize;
430 int params_to_send = paramsize;
434 int params_sent_thistime, data_sent_thistime, total_sent_thistime;
435 int alignment_offset = 1; /* JRA. This used to be 3. Set to 1 to make netmon parse ok. */
436 int data_alignment_offset = 0;
438 /* Initially set the wcnt area to be 10 - this is true for all trans2 replies */
440 set_message(outbuf,10,0,True);
442 /* If there genuinely are no parameters or data to send just send the empty packet */
444 if(params_to_send == 0 && data_to_send == 0) {
445 if (!send_smb(smbd_server_fd(),outbuf))
446 exit_server("send_trans2_replies: send_smb failed.");
450 /* When sending params and data ensure that both are nicely aligned */
451 /* Only do this alignment when there is also data to send - else
452 can cause NT redirector problems. */
454 if (((params_to_send % 4) != 0) && (data_to_send != 0))
455 data_alignment_offset = 4 - (params_to_send % 4);
457 /* Space is bufsize minus Netbios over TCP header minus SMB header */
458 /* The alignment_offset is to align the param bytes on an even byte
459 boundary. NT 4.0 Beta needs this to work correctly. */
461 useable_space = bufsize - ((smb_buf(outbuf)+ alignment_offset+data_alignment_offset) - outbuf);
463 /* useable_space can never be more than max_send minus the alignment offset. */
465 useable_space = MIN(useable_space, max_send - (alignment_offset+data_alignment_offset));
467 while (params_to_send || data_to_send) {
468 /* Calculate whether we will totally or partially fill this packet */
470 total_sent_thistime = params_to_send + data_to_send + alignment_offset + data_alignment_offset;
472 /* We can never send more than useable_space */
474 * Note that 'useable_space' does not include the alignment offsets,
475 * but we must include the alignment offsets in the calculation of
476 * the length of the data we send over the wire, as the alignment offsets
477 * are sent here. Fix from Marc_Jacobsen@hp.com.
480 total_sent_thistime = MIN(total_sent_thistime, useable_space+ alignment_offset + data_alignment_offset);
482 set_message(outbuf, 10, total_sent_thistime, True);
484 /* Set total params and data to be sent */
485 SSVAL(outbuf,smb_tprcnt,paramsize);
486 SSVAL(outbuf,smb_tdrcnt,datasize);
488 /* Calculate how many parameters and data we can fit into
489 * this packet. Parameters get precedence
492 params_sent_thistime = MIN(params_to_send,useable_space);
493 data_sent_thistime = useable_space - params_sent_thistime;
494 data_sent_thistime = MIN(data_sent_thistime,data_to_send);
496 SSVAL(outbuf,smb_prcnt, params_sent_thistime);
498 /* smb_proff is the offset from the start of the SMB header to the
499 parameter bytes, however the first 4 bytes of outbuf are
500 the Netbios over TCP header. Thus use smb_base() to subtract
501 them from the calculation */
503 SSVAL(outbuf,smb_proff,((smb_buf(outbuf)+alignment_offset) - smb_base(outbuf)));
505 if(params_sent_thistime == 0)
506 SSVAL(outbuf,smb_prdisp,0);
508 /* Absolute displacement of param bytes sent in this packet */
509 SSVAL(outbuf,smb_prdisp,pp - params);
511 SSVAL(outbuf,smb_drcnt, data_sent_thistime);
512 if(data_sent_thistime == 0) {
513 SSVAL(outbuf,smb_droff,0);
514 SSVAL(outbuf,smb_drdisp, 0);
516 /* The offset of the data bytes is the offset of the
517 parameter bytes plus the number of parameters being sent this time */
518 SSVAL(outbuf,smb_droff,((smb_buf(outbuf)+alignment_offset) -
519 smb_base(outbuf)) + params_sent_thistime + data_alignment_offset);
520 SSVAL(outbuf,smb_drdisp, pd - pdata);
523 /* Copy the param bytes into the packet */
525 if(params_sent_thistime)
526 memcpy((smb_buf(outbuf)+alignment_offset),pp,params_sent_thistime);
528 /* Copy in the data bytes */
529 if(data_sent_thistime)
530 memcpy(smb_buf(outbuf)+alignment_offset+params_sent_thistime+
531 data_alignment_offset,pd,data_sent_thistime);
533 DEBUG(9,("t2_rep: params_sent_thistime = %d, data_sent_thistime = %d, useable_space = %d\n",
534 params_sent_thistime, data_sent_thistime, useable_space));
535 DEBUG(9,("t2_rep: params_to_send = %d, data_to_send = %d, paramsize = %d, datasize = %d\n",
536 params_to_send, data_to_send, paramsize, datasize));
538 /* Send the packet */
539 if (!send_smb(smbd_server_fd(),outbuf))
540 exit_server("send_trans2_replies: send_smb failed.");
542 pp += params_sent_thistime;
543 pd += data_sent_thistime;
545 params_to_send -= params_sent_thistime;
546 data_to_send -= data_sent_thistime;
549 if(params_to_send < 0 || data_to_send < 0) {
550 DEBUG(0,("send_trans2_replies failed sanity check pts = %d, dts = %d\n!!!",
551 params_to_send, data_to_send));
559 /****************************************************************************
560 Reply to a TRANSACT2_OPEN.
561 ****************************************************************************/
563 static int call_trans2open(connection_struct *conn, char *inbuf, char *outbuf, int bufsize,
564 char **pparams, int total_params, char **ppdata, int total_data)
566 char *params = *pparams;
571 BOOL return_additional_info;
580 int fmode=0,mtime=0,rmode;
582 SMB_STRUCT_STAT sbuf;
584 BOOL bad_path = False;
589 * Ensure we have enough parameters to perform the operation.
592 if (total_params < 29)
593 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
595 open_mode = SVAL(params, 2);
596 open_attr = SVAL(params,6);
597 oplock_request = (((SVAL(params,0)|(1<<1))>>1) | ((SVAL(params,0)|(1<<2))>>1));
599 return_additional_info = BITSETW(params,0);
600 open_sattr = SVAL(params, 4);
601 open_time = make_unix_date3(params+8);
603 open_ofun = SVAL(params,12);
604 open_size = IVAL(params,14);
608 return(ERROR_DOS(ERRSRV,ERRaccess));
610 srvstr_get_path(inbuf, fname, pname, sizeof(fname), -1, STR_TERMINATE, &status);
611 if (!NT_STATUS_IS_OK(status)) {
612 return ERROR_NT(status);
615 DEBUG(3,("trans2open %s mode=%d attr=%d ofun=%d size=%d\n",
616 fname,open_mode, open_attr, open_ofun, open_size));
618 /* XXXX we need to handle passed times, sattr and flags */
620 unix_convert(fname,conn,0,&bad_path,&sbuf);
622 if (!check_name(fname,conn)) {
623 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRnoaccess);
626 fsp = open_file_shared(conn,fname,&sbuf,open_mode,open_ofun,(uint32)open_attr,
627 oplock_request, &rmode,&smb_action);
630 if (open_was_deferred(SVAL(inbuf,smb_mid))) {
631 /* We have re-scheduled this call. */
632 clear_cached_errors();
635 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRnoaccess);
638 size = get_file_size(sbuf);
639 fmode = dos_mode(conn,fname,&sbuf);
640 mtime = sbuf.st_mtime;
643 close_file(fsp,False);
644 return(ERROR_DOS(ERRDOS,ERRnoaccess));
647 /* Realloc the size of parameters and data we will return */
648 params = Realloc(*pparams, 28);
650 return(ERROR_DOS(ERRDOS,ERRnomem));
653 memset((char *)params,'\0',28);
654 SSVAL(params,0,fsp->fnum);
655 SSVAL(params,2,fmode);
656 put_dos_date2(params,4, mtime);
657 SIVAL(params,8, (uint32)size);
658 SSVAL(params,12,rmode);
660 if (oplock_request && lp_fake_oplocks(SNUM(conn)))
661 smb_action |= EXTENDED_OPLOCK_GRANTED;
663 SSVAL(params,18,smb_action);
666 * WARNING - this may need to be changed if SMB_INO_T <> 4 bytes.
668 SIVAL(params,20,inode);
670 /* Send the required number of replies */
671 send_trans2_replies(outbuf, bufsize, params, 28, *ppdata, 0);
676 /*********************************************************
677 Routine to check if a given string matches exactly.
678 as a special case a mask of "." does NOT match. That
679 is required for correct wildcard semantics
680 Case can be significant or not.
681 **********************************************************/
683 static BOOL exact_match(char *str,char *mask, BOOL case_sig)
685 if (mask[0] == '.' && mask[1] == 0)
688 return strcmp(str,mask)==0;
689 if (StrCaseCmp(str,mask) != 0) {
692 if (ms_has_wild(str)) {
698 /****************************************************************************
699 Return the filetype for UNIX extensions.
700 ****************************************************************************/
702 static uint32 unix_filetype(mode_t mode)
705 return UNIX_TYPE_FILE;
706 else if(S_ISDIR(mode))
707 return UNIX_TYPE_DIR;
709 else if(S_ISLNK(mode))
710 return UNIX_TYPE_SYMLINK;
713 else if(S_ISCHR(mode))
714 return UNIX_TYPE_CHARDEV;
717 else if(S_ISBLK(mode))
718 return UNIX_TYPE_BLKDEV;
721 else if(S_ISFIFO(mode))
722 return UNIX_TYPE_FIFO;
725 else if(S_ISSOCK(mode))
726 return UNIX_TYPE_SOCKET;
729 DEBUG(0,("unix_filetype: unknown filetype %u", (unsigned)mode));
730 return UNIX_TYPE_UNKNOWN;
733 /****************************************************************************
734 Return the major devicenumber for UNIX extensions.
735 ****************************************************************************/
737 static uint32 unix_dev_major(SMB_DEV_T dev)
739 #if defined(HAVE_DEVICE_MAJOR_FN)
740 return (uint32)major(dev);
742 return (uint32)(dev >> 8);
746 /****************************************************************************
747 Return the minor devicenumber for UNIX extensions.
748 ****************************************************************************/
750 static uint32 unix_dev_minor(SMB_DEV_T dev)
752 #if defined(HAVE_DEVICE_MINOR_FN)
753 return (uint32)minor(dev);
755 return (uint32)(dev & 0xff);
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 BOOL close_after_first = BITSETW(params+4,0);
1333 BOOL close_if_end = BITSETW(params+4,1);
1334 BOOL requires_resume_key = BITSETW(params+4,2);
1335 int info_level = SVAL(params,6);
1339 int last_name_off=0;
1343 BOOL finished = False;
1344 BOOL dont_descend = False;
1345 BOOL out_of_space = False;
1346 int space_remaining;
1347 BOOL bad_path = False;
1348 SMB_STRUCT_STAT sbuf;
1349 NTSTATUS ntstatus = NT_STATUS_OK;
1351 if (total_params < 12)
1352 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
1354 *directory = *mask = 0;
1356 DEBUG(3,("call_trans2findfirst: dirtype = %d, maxentries = %d, close_after_first=%d, \
1357 close_if_end = %d requires_resume_key = %d level = 0x%x, max_data_bytes = %d\n",
1358 dirtype, maxentries, close_after_first, close_if_end, requires_resume_key,
1359 info_level, max_data_bytes));
1361 switch (info_level) {
1362 case SMB_INFO_STANDARD:
1363 case SMB_INFO_QUERY_EA_SIZE:
1364 case SMB_FIND_FILE_DIRECTORY_INFO:
1365 case SMB_FIND_FILE_FULL_DIRECTORY_INFO:
1366 case SMB_FIND_FILE_NAMES_INFO:
1367 case SMB_FIND_FILE_BOTH_DIRECTORY_INFO:
1368 case SMB_FIND_ID_FULL_DIRECTORY_INFO:
1369 case SMB_FIND_ID_BOTH_DIRECTORY_INFO:
1371 case SMB_FIND_FILE_UNIX:
1372 if (!lp_unix_extensions())
1373 return(ERROR_DOS(ERRDOS,ERRunknownlevel));
1376 return(ERROR_DOS(ERRDOS,ERRunknownlevel));
1379 srvstr_get_path(inbuf, directory, params+12, sizeof(directory), -1, STR_TERMINATE, &ntstatus);
1380 if (!NT_STATUS_IS_OK(ntstatus)) {
1381 return ERROR_NT(ntstatus);
1384 RESOLVE_FINDFIRST_DFSPATH(directory, conn, inbuf, outbuf);
1386 unix_convert(directory,conn,0,&bad_path,&sbuf);
1387 if(!check_name(directory,conn)) {
1388 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRbadpath);
1391 p = strrchr_m(directory,'/');
1393 /* Windows and OS/2 systems treat search on the root '\' as if it were '\*' */
1394 if((directory[0] == '.') && (directory[1] == '\0'))
1397 pstrcpy(mask,directory);
1398 pstrcpy(directory,"./");
1404 DEBUG(5,("dir=%s, mask = %s\n",directory, mask));
1406 pdata = Realloc(*ppdata, max_data_bytes + 1024);
1408 return(ERROR_DOS(ERRDOS,ERRnomem));
1411 memset((char *)pdata,'\0',max_data_bytes + 1024);
1413 /* Realloc the params space */
1414 params = Realloc(*pparams, 10);
1416 return ERROR_DOS(ERRDOS,ERRnomem);
1419 dptr_num = dptr_create(conn,directory, False, True ,SVAL(inbuf,smb_pid));
1421 return(UNIXERROR(ERRDOS,ERRbadfile));
1423 /* Save the wildcard match and attribs we are using on this directory -
1424 needed as lanman2 assumes these are being saved between calls */
1426 if(!(wcard = strdup(mask))) {
1427 dptr_close(&dptr_num);
1428 return ERROR_DOS(ERRDOS,ERRnomem);
1431 dptr_set_wcard(dptr_num, wcard);
1432 dptr_set_attr(dptr_num, dirtype);
1434 DEBUG(4,("dptr_num is %d, wcard = %s, attr = %d\n",dptr_num, wcard, dirtype));
1436 /* We don't need to check for VOL here as this is returned by
1437 a different TRANS2 call. */
1439 DEBUG(8,("dirpath=<%s> dontdescend=<%s>\n", conn->dirpath,lp_dontdescend(SNUM(conn))));
1440 if (in_list(conn->dirpath,lp_dontdescend(SNUM(conn)),conn->case_sensitive))
1441 dont_descend = True;
1444 space_remaining = max_data_bytes;
1445 out_of_space = False;
1447 for (i=0;(i<maxentries) && !finished && !out_of_space;i++) {
1448 BOOL got_exact_match = False;
1450 /* this is a heuristic to avoid seeking the dirptr except when
1451 absolutely necessary. It allows for a filename of about 40 chars */
1452 if (space_remaining < DIRLEN_GUESS && numentries > 0) {
1453 out_of_space = True;
1456 finished = !get_lanman2_dir_entry(conn,
1458 mask,dirtype,info_level,
1459 requires_resume_key,dont_descend,
1460 &p,pdata,space_remaining, &out_of_space, &got_exact_match,
1464 if (finished && out_of_space)
1467 if (!finished && !out_of_space)
1471 * As an optimisation if we know we aren't looking
1472 * for a wildcard name (ie. the name matches the wildcard exactly)
1473 * then we can finish on any (first) match.
1474 * This speeds up large directory searches. JRA.
1480 space_remaining = max_data_bytes - PTR_DIFF(p,pdata);
1483 /* Check if we can close the dirptr */
1484 if(close_after_first || (finished && close_if_end)) {
1485 DEBUG(5,("call_trans2findfirst - (2) closing dptr_num %d\n", dptr_num));
1486 dptr_close(&dptr_num);
1490 * If there are no matching entries we must return ERRDOS/ERRbadfile -
1491 * from observation of NT.
1494 if(numentries == 0) {
1495 dptr_close(&dptr_num);
1496 return ERROR_DOS(ERRDOS,ERRbadfile);
1499 /* At this point pdata points to numentries directory entries. */
1501 /* Set up the return parameter block */
1502 SSVAL(params,0,dptr_num);
1503 SSVAL(params,2,numentries);
1504 SSVAL(params,4,finished);
1505 SSVAL(params,6,0); /* Never an EA error */
1506 SSVAL(params,8,last_name_off);
1508 send_trans2_replies( outbuf, bufsize, params, 10, pdata, PTR_DIFF(p,pdata));
1510 if ((! *directory) && dptr_path(dptr_num))
1511 slprintf(directory,sizeof(directory)-1, "(%s)",dptr_path(dptr_num));
1513 DEBUG( 4, ( "%s mask=%s directory=%s dirtype=%d numentries=%d\n",
1514 smb_fn_name(CVAL(inbuf,smb_com)),
1515 mask, directory, dirtype, numentries ) );
1518 * Force a name mangle here to ensure that the
1519 * mask as an 8.3 name is top of the mangled cache.
1520 * The reasons for this are subtle. Don't remove
1521 * this code unless you know what you are doing
1522 * (see PR#13758). JRA.
1525 if(!mangle_is_8_3_wildcards( mask, False))
1526 mangle_map(mask, True, True, SNUM(conn));
1531 /****************************************************************************
1532 Reply to a TRANS2_FINDNEXT.
1533 ****************************************************************************/
1535 static int call_trans2findnext(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize,
1536 char **pparams, int total_params, char **ppdata, int total_data)
1538 /* We must be careful here that we don't return more than the
1539 allowed number of data bytes. If this means returning fewer than
1540 maxentries then so be it. We assume that the redirector has
1541 enough room for the fixed number of parameter bytes it has
1543 int max_data_bytes = SVAL(inbuf, smb_mdrcnt);
1544 char *params = *pparams;
1545 char *pdata = *ppdata;
1546 int dptr_num = SVAL(params,0);
1547 int maxentries = SVAL(params,2);
1548 uint16 info_level = SVAL(params,4);
1549 uint32 resume_key = IVAL(params,6);
1550 BOOL close_after_request = BITSETW(params+10,0);
1551 BOOL close_if_end = BITSETW(params+10,1);
1552 BOOL requires_resume_key = BITSETW(params+10,2);
1553 BOOL continue_bit = BITSETW(params+10,3);
1554 pstring resume_name;
1560 int i, last_name_off=0;
1561 BOOL finished = False;
1562 BOOL dont_descend = False;
1563 BOOL out_of_space = False;
1564 int space_remaining;
1565 NTSTATUS ntstatus = NT_STATUS_OK;
1567 if (total_params < 12)
1568 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
1570 *mask = *directory = *resume_name = 0;
1572 srvstr_get_path(inbuf, resume_name, params+12, sizeof(resume_name), -1, STR_TERMINATE, &ntstatus);
1573 if (!NT_STATUS_IS_OK(ntstatus)) {
1574 return ERROR_NT(ntstatus);
1577 DEBUG(3,("call_trans2findnext: dirhandle = %d, max_data_bytes = %d, maxentries = %d, \
1578 close_after_request=%d, close_if_end = %d requires_resume_key = %d \
1579 resume_key = %d resume name = %s continue=%d level = %d\n",
1580 dptr_num, max_data_bytes, maxentries, close_after_request, close_if_end,
1581 requires_resume_key, resume_key, resume_name, continue_bit, info_level));
1583 switch (info_level) {
1584 case SMB_INFO_STANDARD:
1585 case SMB_INFO_QUERY_EA_SIZE:
1586 case SMB_FIND_FILE_DIRECTORY_INFO:
1587 case SMB_FIND_FILE_FULL_DIRECTORY_INFO:
1588 case SMB_FIND_FILE_NAMES_INFO:
1589 case SMB_FIND_FILE_BOTH_DIRECTORY_INFO:
1591 case SMB_FIND_FILE_UNIX:
1592 if (!lp_unix_extensions())
1593 return(ERROR_DOS(ERRDOS,ERRunknownlevel));
1596 return ERROR_DOS(ERRDOS,ERRunknownlevel);
1599 pdata = Realloc( *ppdata, max_data_bytes + 1024);
1601 return ERROR_DOS(ERRDOS,ERRnomem);
1604 memset((char *)pdata,'\0',max_data_bytes + 1024);
1606 /* Realloc the params space */
1607 params = Realloc(*pparams, 6*SIZEOFWORD);
1608 if( params == NULL )
1609 return ERROR_DOS(ERRDOS,ERRnomem);
1613 /* Check that the dptr is valid */
1614 if(!(conn->dirptr = dptr_fetch_lanman2(dptr_num)))
1615 return ERROR_DOS(ERRDOS,ERRnofiles);
1617 string_set(&conn->dirpath,dptr_path(dptr_num));
1619 /* Get the wildcard mask from the dptr */
1620 if((p = dptr_wcard(dptr_num))== NULL) {
1621 DEBUG(2,("dptr_num %d has no wildcard\n", dptr_num));
1622 return ERROR_DOS(ERRDOS,ERRnofiles);
1626 pstrcpy(directory,conn->dirpath);
1628 /* Get the attr mask from the dptr */
1629 dirtype = dptr_attr(dptr_num);
1631 DEBUG(3,("dptr_num is %d, mask = %s, attr = %x, dirptr=(0x%lX,%d)\n",
1632 dptr_num, mask, dirtype,
1634 TellDir(conn->dirptr)));
1636 /* We don't need to check for VOL here as this is returned by
1637 a different TRANS2 call. */
1639 DEBUG(8,("dirpath=<%s> dontdescend=<%s>\n",conn->dirpath,lp_dontdescend(SNUM(conn))));
1640 if (in_list(conn->dirpath,lp_dontdescend(SNUM(conn)),conn->case_sensitive))
1641 dont_descend = True;
1644 space_remaining = max_data_bytes;
1645 out_of_space = False;
1648 * Seek to the correct position. We no longer use the resume key but
1649 * depend on the last file name instead.
1652 if(requires_resume_key && *resume_name && !continue_bit) {
1655 * Fix for NT redirector problem triggered by resume key indexes
1656 * changing between directory scans. We now return a resume key of 0
1657 * and instead look for the filename to continue from (also given
1658 * to us by NT/95/smbfs/smbclient). If no other scans have been done between the
1659 * findfirst/findnext (as is usual) then the directory pointer
1660 * should already be at the correct place. Check this by scanning
1661 * backwards looking for an exact (ie. case sensitive) filename match.
1662 * If we get to the beginning of the directory and haven't found it then scan
1663 * forwards again looking for a match. JRA.
1666 int current_pos, start_pos;
1667 const char *dname = NULL;
1668 pstring dname_pstring;
1669 void *dirptr = conn->dirptr;
1670 start_pos = TellDir(dirptr);
1671 for(current_pos = start_pos; current_pos >= 0; current_pos--) {
1672 DEBUG(7,("call_trans2findnext: seeking to pos %d\n", current_pos));
1674 SeekDir(dirptr, current_pos);
1675 dname = ReadDirName(dirptr);
1678 * Remember, mangle_map is called by
1679 * get_lanman2_dir_entry(), so the resume name
1680 * could be mangled. Ensure we do the same
1684 /* make sure we get a copy that mangle_map can modify */
1686 pstrcpy(dname_pstring, dname);
1687 mangle_map( dname_pstring, False, True, SNUM(conn));
1689 if(strcsequal( resume_name, dname_pstring)) {
1690 SeekDir(dirptr, current_pos+1);
1691 DEBUG(7,("call_trans2findnext: got match at pos %d\n", current_pos+1 ));
1698 * Scan forward from start if not found going backwards.
1701 if(current_pos < 0) {
1702 DEBUG(7,("call_trans2findnext: notfound: seeking to pos %d\n", start_pos));
1703 SeekDir(dirptr, start_pos);
1704 for(current_pos = start_pos; (dname = ReadDirName(dirptr)) != NULL; SeekDir(dirptr,++current_pos)) {
1707 * Remember, mangle_map is called by
1708 * get_lanman2_dir_entry(), so the resume name
1709 * could be mangled. Ensure we do the same
1714 /* make sure we get a copy that mangle_map can modify */
1716 pstrcpy(dname_pstring, dname);
1717 mangle_map(dname_pstring, False, True, SNUM(conn));
1719 if(strcsequal( resume_name, dname_pstring)) {
1720 SeekDir(dirptr, current_pos+1);
1721 DEBUG(7,("call_trans2findnext: got match at pos %d\n", current_pos+1 ));
1726 } /* end if current_pos */
1727 } /* end if requires_resume_key && !continue_bit */
1729 for (i=0;(i<(int)maxentries) && !finished && !out_of_space ;i++) {
1730 BOOL got_exact_match = False;
1732 /* this is a heuristic to avoid seeking the dirptr except when
1733 absolutely necessary. It allows for a filename of about 40 chars */
1734 if (space_remaining < DIRLEN_GUESS && numentries > 0) {
1735 out_of_space = True;
1738 finished = !get_lanman2_dir_entry(conn,
1740 mask,dirtype,info_level,
1741 requires_resume_key,dont_descend,
1742 &p,pdata,space_remaining, &out_of_space, &got_exact_match,
1746 if (finished && out_of_space)
1749 if (!finished && !out_of_space)
1753 * As an optimisation if we know we aren't looking
1754 * for a wildcard name (ie. the name matches the wildcard exactly)
1755 * then we can finish on any (first) match.
1756 * This speeds up large directory searches. JRA.
1762 space_remaining = max_data_bytes - PTR_DIFF(p,pdata);
1765 /* Check if we can close the dirptr */
1766 if(close_after_request || (finished && close_if_end)) {
1767 DEBUG(5,("call_trans2findnext: closing dptr_num = %d\n", dptr_num));
1768 dptr_close(&dptr_num); /* This frees up the saved mask */
1771 /* Set up the return parameter block */
1772 SSVAL(params,0,numentries);
1773 SSVAL(params,2,finished);
1774 SSVAL(params,4,0); /* Never an EA error */
1775 SSVAL(params,6,last_name_off);
1777 send_trans2_replies( outbuf, bufsize, params, 8, pdata, PTR_DIFF(p,pdata));
1779 if ((! *directory) && dptr_path(dptr_num))
1780 slprintf(directory,sizeof(directory)-1, "(%s)",dptr_path(dptr_num));
1782 DEBUG( 3, ( "%s mask=%s directory=%s dirtype=%d numentries=%d\n",
1783 smb_fn_name(CVAL(inbuf,smb_com)),
1784 mask, directory, dirtype, numentries ) );
1789 /****************************************************************************
1790 Reply to a TRANS2_QFSINFO (query filesystem info).
1791 ****************************************************************************/
1793 static int call_trans2qfsinfo(connection_struct *conn, char *inbuf, char *outbuf,
1794 int length, int bufsize,
1795 char **pparams, int total_params, char **ppdata, int total_data)
1797 int max_data_bytes = SVAL(inbuf, smb_mdrcnt);
1798 char *pdata = *ppdata;
1799 char *params = *pparams;
1800 uint16 info_level = SVAL(params,0);
1803 char *vname = volume_label(SNUM(conn));
1804 int snum = SNUM(conn);
1805 char *fstype = lp_fstype(SNUM(conn));
1808 DEBUG(3,("call_trans2qfsinfo: level = %d\n", info_level));
1810 if(SMB_VFS_STAT(conn,".",&st)!=0) {
1811 DEBUG(2,("call_trans2qfsinfo: stat of . failed (%s)\n", strerror(errno)));
1812 return ERROR_DOS(ERRSRV,ERRinvdevice);
1815 pdata = Realloc(*ppdata, max_data_bytes + 1024);
1816 if ( pdata == NULL )
1817 return ERROR_DOS(ERRDOS,ERRnomem);
1820 memset((char *)pdata,'\0',max_data_bytes + 1024);
1822 switch (info_level) {
1823 case SMB_INFO_ALLOCATION:
1825 SMB_BIG_UINT dfree,dsize,bsize,block_size,sectors_per_unit,bytes_per_sector;
1827 SMB_VFS_DISK_FREE(conn,".",False,&bsize,&dfree,&dsize);
1828 block_size = lp_block_size(snum);
1829 if (bsize < block_size) {
1830 SMB_BIG_UINT factor = block_size/bsize;
1835 if (bsize > block_size) {
1836 SMB_BIG_UINT factor = bsize/block_size;
1841 bytes_per_sector = 512;
1842 sectors_per_unit = bsize/bytes_per_sector;
1844 DEBUG(5,("call_trans2qfsinfo : SMB_INFO_ALLOCATION id=%x, bsize=%u, cSectorUnit=%u, \
1845 cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)st.st_dev, (unsigned int)bsize, (unsigned int)sectors_per_unit,
1846 (unsigned int)bytes_per_sector, (unsigned int)dsize, (unsigned int)dfree));
1848 SIVAL(pdata,l1_idFileSystem,st.st_dev);
1849 SIVAL(pdata,l1_cSectorUnit,sectors_per_unit);
1850 SIVAL(pdata,l1_cUnit,dsize);
1851 SIVAL(pdata,l1_cUnitAvail,dfree);
1852 SSVAL(pdata,l1_cbSector,bytes_per_sector);
1856 case SMB_INFO_VOLUME:
1857 /* Return volume name */
1859 * Add volume serial number - hash of a combination of
1860 * the called hostname and the service name.
1862 SIVAL(pdata,0,str_checksum(lp_servicename(snum)) ^ (str_checksum(local_machine)<<16) );
1863 len = srvstr_push(outbuf, pdata+l2_vol_szVolLabel, vname, -1, STR_NOALIGN);
1864 SCVAL(pdata,l2_vol_cch,len);
1865 data_len = l2_vol_szVolLabel + len;
1866 DEBUG(5,("call_trans2qfsinfo : time = %x, namelen = %d, name = %s\n",
1867 (unsigned)st.st_ctime, len, vname));
1870 case SMB_QUERY_FS_ATTRIBUTE_INFO:
1871 case SMB_FS_ATTRIBUTE_INFORMATION:
1874 #if defined(HAVE_SYS_QUOTAS)
1875 quota_flag = FILE_VOLUME_QUOTAS;
1878 SIVAL(pdata,0,FILE_CASE_PRESERVED_NAMES|FILE_CASE_SENSITIVE_SEARCH|
1879 (lp_nt_acl_support(SNUM(conn)) ? FILE_PERSISTENT_ACLS : 0)|
1880 quota_flag); /* FS ATTRIBUTES */
1882 SIVAL(pdata,4,255); /* Max filename component length */
1883 /* NOTE! the fstype must *not* be null terminated or win98 won't recognise it
1884 and will think we can't do long filenames */
1885 len = srvstr_push(outbuf, pdata+12, fstype, -1, STR_UNICODE);
1887 data_len = 12 + len;
1890 case SMB_QUERY_FS_LABEL_INFO:
1891 case SMB_FS_LABEL_INFORMATION:
1892 len = srvstr_push(outbuf, pdata+4, vname, -1, 0);
1897 case SMB_QUERY_FS_VOLUME_INFO:
1898 case SMB_FS_VOLUME_INFORMATION:
1901 * Add volume serial number - hash of a combination of
1902 * the called hostname and the service name.
1904 SIVAL(pdata,8,str_checksum(lp_servicename(snum)) ^
1905 (str_checksum(local_machine)<<16));
1907 len = srvstr_push(outbuf, pdata+18, vname, -1, STR_UNICODE);
1908 SIVAL(pdata,12,len);
1910 DEBUG(5,("call_trans2qfsinfo : SMB_QUERY_FS_VOLUME_INFO namelen = %d, vol=%s serv=%s\n",
1911 (int)strlen(vname),vname, lp_servicename(snum)));
1914 case SMB_QUERY_FS_SIZE_INFO:
1915 case SMB_FS_SIZE_INFORMATION:
1917 SMB_BIG_UINT dfree,dsize,bsize,block_size,sectors_per_unit,bytes_per_sector;
1919 SMB_VFS_DISK_FREE(conn,".",False,&bsize,&dfree,&dsize);
1920 block_size = lp_block_size(snum);
1921 if (bsize < block_size) {
1922 SMB_BIG_UINT factor = block_size/bsize;
1927 if (bsize > block_size) {
1928 SMB_BIG_UINT factor = bsize/block_size;
1933 bytes_per_sector = 512;
1934 sectors_per_unit = bsize/bytes_per_sector;
1935 DEBUG(5,("call_trans2qfsinfo : SMB_QUERY_FS_SIZE_INFO bsize=%u, cSectorUnit=%u, \
1936 cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize, (unsigned int)sectors_per_unit,
1937 (unsigned int)bytes_per_sector, (unsigned int)dsize, (unsigned int)dfree));
1938 SBIG_UINT(pdata,0,dsize);
1939 SBIG_UINT(pdata,8,dfree);
1940 SIVAL(pdata,16,sectors_per_unit);
1941 SIVAL(pdata,20,bytes_per_sector);
1945 case SMB_FS_FULL_SIZE_INFORMATION:
1947 SMB_BIG_UINT dfree,dsize,bsize,block_size,sectors_per_unit,bytes_per_sector;
1949 SMB_VFS_DISK_FREE(conn,".",False,&bsize,&dfree,&dsize);
1950 block_size = lp_block_size(snum);
1951 if (bsize < block_size) {
1952 SMB_BIG_UINT factor = block_size/bsize;
1957 if (bsize > block_size) {
1958 SMB_BIG_UINT factor = bsize/block_size;
1963 bytes_per_sector = 512;
1964 sectors_per_unit = bsize/bytes_per_sector;
1965 DEBUG(5,("call_trans2qfsinfo : SMB_QUERY_FS_FULL_SIZE_INFO bsize=%u, cSectorUnit=%u, \
1966 cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize, (unsigned int)sectors_per_unit,
1967 (unsigned int)bytes_per_sector, (unsigned int)dsize, (unsigned int)dfree));
1968 SBIG_UINT(pdata,0,dsize); /* Total Allocation units. */
1969 SBIG_UINT(pdata,8,dfree); /* Caller available allocation units. */
1970 SBIG_UINT(pdata,16,dfree); /* Actual available allocation units. */
1971 SIVAL(pdata,24,sectors_per_unit); /* Sectors per allocation unit. */
1972 SIVAL(pdata,28,bytes_per_sector); /* Bytes per sector. */
1976 case SMB_QUERY_FS_DEVICE_INFO:
1977 case SMB_FS_DEVICE_INFORMATION:
1979 SIVAL(pdata,0,0); /* dev type */
1980 SIVAL(pdata,4,0); /* characteristics */
1983 #ifdef HAVE_SYS_QUOTAS
1984 case SMB_FS_QUOTA_INFORMATION:
1986 * what we have to send --metze:
1988 * Unknown1: 24 NULL bytes
1989 * Soft Quota Treshold: 8 bytes seems like SMB_BIG_UINT or so
1990 * Hard Quota Limit: 8 bytes seems like SMB_BIG_UINT or so
1991 * Quota Flags: 2 byte :
1992 * Unknown3: 6 NULL bytes
1996 * details for Quota Flags:
1998 * 0x0020 Log Limit: log if the user exceeds his Hard Quota
1999 * 0x0010 Log Warn: log if the user exceeds his Soft Quota
2000 * 0x0002 Deny Disk: deny disk access when the user exceeds his Hard Quota
2001 * 0x0001 Enable Quotas: enable quota for this fs
2005 /* we need to fake up a fsp here,
2006 * because its not send in this call
2009 SMB_NTQUOTA_STRUCT quotas;
2012 ZERO_STRUCT(quotas);
2019 if (current_user.uid != 0) {
2020 DEBUG(0,("set_user_quota: access_denied service [%s] user [%s]\n",
2021 lp_servicename(SNUM(conn)),conn->user));
2022 return ERROR_DOS(ERRDOS,ERRnoaccess);
2025 if (vfs_get_ntquota(&fsp, SMB_USER_FS_QUOTA_TYPE, NULL, "as)!=0) {
2026 DEBUG(0,("vfs_get_ntquota() failed for service [%s]\n",lp_servicename(SNUM(conn))));
2027 return ERROR_DOS(ERRSRV,ERRerror);
2032 DEBUG(10,("SMB_FS_QUOTA_INFORMATION: for service [%s]\n",lp_servicename(SNUM(conn))));
2034 /* Unknown1 24 NULL bytes*/
2035 SBIG_UINT(pdata,0,(SMB_BIG_UINT)0);
2036 SBIG_UINT(pdata,8,(SMB_BIG_UINT)0);
2037 SBIG_UINT(pdata,16,(SMB_BIG_UINT)0);
2039 /* Default Soft Quota 8 bytes */
2040 SBIG_UINT(pdata,24,quotas.softlim);
2042 /* Default Hard Quota 8 bytes */
2043 SBIG_UINT(pdata,32,quotas.hardlim);
2045 /* Quota flag 2 bytes */
2046 SSVAL(pdata,40,quotas.qflags);
2048 /* Unknown3 6 NULL bytes */
2054 #endif /* HAVE_SYS_QUOTAS */
2055 case SMB_FS_OBJECTID_INFORMATION:
2060 * Query the version and capabilities of the CIFS UNIX extensions
2064 case SMB_QUERY_CIFS_UNIX_INFO:
2065 if (!lp_unix_extensions())
2066 return ERROR_DOS(ERRDOS,ERRunknownlevel);
2068 SSVAL(pdata,0,CIFS_UNIX_MAJOR_VERSION);
2069 SSVAL(pdata,2,CIFS_UNIX_MINOR_VERSION);
2070 SBIG_UINT(pdata,4,((SMB_BIG_UINT)0)); /* No capabilities for now... */
2073 case SMB_MAC_QUERY_FS_INFO:
2075 * Thursby MAC extension... ONLY on NTFS filesystems
2076 * once we do streams then we don't need this
2078 if (strequal(lp_fstype(SNUM(conn)),"NTFS")) {
2080 SIVAL(pdata,84,0x100); /* Don't support mac... */
2085 return ERROR_DOS(ERRDOS,ERRunknownlevel);
2089 send_trans2_replies( outbuf, bufsize, params, 0, pdata, data_len);
2091 DEBUG( 4, ( "%s info_level = %d\n", smb_fn_name(CVAL(inbuf,smb_com)), info_level) );
2096 #ifdef HAVE_SYS_QUOTAS
2097 /****************************************************************************
2098 Reply to a TRANS2_SETFSINFO (set filesystem info).
2099 ****************************************************************************/
2101 static int call_trans2setfsinfo(connection_struct *conn,
2102 char *inbuf, char *outbuf, int length, int bufsize,
2103 char **pparams, int total_params, char **ppdata, int total_data)
2105 char *pdata = *ppdata;
2106 char *params = *pparams;
2107 files_struct *fsp = NULL;
2110 SMB_NTQUOTA_STRUCT quotas;
2112 ZERO_STRUCT(quotas);
2114 DEBUG(10,("call_trans2setfsinfo: SET_FS_QUOTA: for service [%s]\n",lp_servicename(SNUM(conn))));
2117 if ((current_user.uid != 0)||!CAN_WRITE(conn)) {
2118 DEBUG(0,("set_user_quota: access_denied service [%s] user [%s]\n",
2119 lp_servicename(SNUM(conn)),conn->user));
2120 return ERROR_DOS(ERRSRV,ERRaccess);
2124 if (total_params < 4) {
2125 DEBUG(0,("call_trans2setfsinfo: requires total_params(%d) >= 4 bytes!\n",
2127 return ERROR_DOS(ERRDOS,ERRinvalidparam);
2130 fsp = file_fsp(params,0);
2132 if (!CHECK_NTQUOTA_HANDLE_OK(fsp,conn)) {
2133 DEBUG(3,("TRANSACT_GET_USER_QUOTA: no valid QUOTA HANDLE\n"));
2134 return ERROR_NT(NT_STATUS_INVALID_HANDLE);
2137 info_level = SVAL(params,2);
2139 switch(info_level) {
2140 case SMB_FS_QUOTA_INFORMATION:
2141 /* note: normaly there're 48 bytes,
2142 * but we didn't use the last 6 bytes for now
2145 if (total_data < 42) {
2146 DEBUG(0,("call_trans2setfsinfo: SET_FS_QUOTA: requires total_data(%d) >= 42 bytes!\n",
2148 return ERROR_DOS(ERRDOS,ERRunknownlevel);
2151 /* unknown_1 24 NULL bytes in pdata*/
2153 /* the soft quotas 8 bytes (SMB_BIG_UINT)*/
2154 quotas.softlim = (SMB_BIG_UINT)IVAL(pdata,24);
2155 #ifdef LARGE_SMB_OFF_T
2156 quotas.softlim |= (((SMB_BIG_UINT)IVAL(pdata,28)) << 32);
2157 #else /* LARGE_SMB_OFF_T */
2158 if ((IVAL(pdata,28) != 0)&&
2159 ((quotas.softlim != 0xFFFFFFFF)||
2160 (IVAL(pdata,28)!=0xFFFFFFFF))) {
2161 /* more than 32 bits? */
2162 return ERROR_DOS(ERRDOS,ERRunknownlevel);
2164 #endif /* LARGE_SMB_OFF_T */
2166 /* the hard quotas 8 bytes (SMB_BIG_UINT)*/
2167 quotas.hardlim = (SMB_BIG_UINT)IVAL(pdata,32);
2168 #ifdef LARGE_SMB_OFF_T
2169 quotas.hardlim |= (((SMB_BIG_UINT)IVAL(pdata,36)) << 32);
2170 #else /* LARGE_SMB_OFF_T */
2171 if ((IVAL(pdata,36) != 0)&&
2172 ((quotas.hardlim != 0xFFFFFFFF)||
2173 (IVAL(pdata,36)!=0xFFFFFFFF))) {
2174 /* more than 32 bits? */
2175 return ERROR_DOS(ERRDOS,ERRunknownlevel);
2177 #endif /* LARGE_SMB_OFF_T */
2179 /* quota_flags 2 bytes **/
2180 quotas.qflags = SVAL(pdata,40);
2182 /* unknown_2 6 NULL bytes follow*/
2184 /* now set the quotas */
2185 if (vfs_set_ntquota(fsp, SMB_USER_FS_QUOTA_TYPE, NULL, "as)!=0) {
2186 DEBUG(0,("vfs_set_ntquota() failed for service [%s]\n",lp_servicename(SNUM(conn))));
2187 return ERROR_DOS(ERRSRV,ERRerror);
2192 DEBUG(3,("call_trans2setfsinfo: unknown level (0x%X) not implemented yet.\n",
2194 return ERROR_DOS(ERRDOS,ERRunknownlevel);
2199 * sending this reply works fine,
2200 * but I'm not sure it's the same
2201 * like windows do...
2204 outsize = set_message(outbuf,10,0,True);
2208 #endif /* HAVE_SYS_QUOTAS */
2210 /****************************************************************************
2211 * Utility function to set bad path error.
2212 ****************************************************************************/
2214 int set_bad_path_error(int err, BOOL bad_path, char *outbuf, int def_class, uint32 def_code)
2216 DEBUG(10,("set_bad_path_error: err = %d bad_path = %d\n",
2217 err, (int)bad_path ));
2221 return ERROR_NT(NT_STATUS_OBJECT_PATH_NOT_FOUND);
2223 return ERROR_NT(NT_STATUS_OBJECT_NAME_NOT_FOUND);
2226 return UNIXERROR(def_class,def_code);
2229 /****************************************************************************
2230 Reply to a TRANS2_QFILEPATHINFO or TRANSACT2_QFILEINFO (query file info by
2231 file name or file id).
2232 ****************************************************************************/
2234 static int call_trans2qfilepathinfo(connection_struct *conn,
2235 char *inbuf, char *outbuf, int length,
2237 char **pparams, int total_params, char **ppdata, int total_data)
2239 int max_data_bytes = SVAL(inbuf, smb_mdrcnt);
2240 char *params = *pparams;
2241 char *pdata = *ppdata;
2242 uint16 tran_call = SVAL(inbuf, smb_setup0);
2245 SMB_OFF_T file_size=0;
2246 SMB_BIG_UINT allocation_size=0;
2247 unsigned int data_size;
2248 unsigned int param_size = 2;
2249 SMB_STRUCT_STAT sbuf;
2250 pstring fname, dos_fname;
2255 BOOL bad_path = False;
2256 BOOL delete_pending = False;
2259 files_struct *fsp = NULL;
2260 uint32 desired_access = 0x12019F; /* Default - GENERIC_EXECUTE mapping from Windows */
2263 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
2265 if (tran_call == TRANSACT2_QFILEINFO) {
2266 if (total_params < 4)
2267 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
2269 fsp = file_fsp(params,0);
2270 info_level = SVAL(params,2);
2272 DEBUG(3,("call_trans2qfilepathinfo: TRANSACT2_QFILEINFO: level = %d\n", info_level));
2274 if(fsp && (fsp->fake_file_handle)) {
2276 * This is actually for the QUOTA_FAKE_FILE --metze
2279 pstrcpy(fname, fsp->fsp_name);
2280 unix_convert(fname,conn,0,&bad_path,&sbuf);
2281 if (!check_name(fname,conn)) {
2282 DEBUG(3,("call_trans2qfilepathinfo: fileinfo of %s failed for fake_file(%s)\n",fname,strerror(errno)));
2283 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRbadpath);
2286 } else if(fsp && (fsp->is_directory || fsp->fd == -1)) {
2288 * This is actually a QFILEINFO on a directory
2289 * handle (returned from an NT SMB). NT5.0 seems
2290 * to do this call. JRA.
2292 pstrcpy(fname, fsp->fsp_name);
2293 unix_convert(fname,conn,0,&bad_path,&sbuf);
2294 if (!check_name(fname,conn)) {
2295 DEBUG(3,("call_trans2qfilepathinfo: fileinfo of %s failed (%s)\n",fname,strerror(errno)));
2296 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRbadpath);
2299 if (INFO_LEVEL_IS_UNIX(info_level)) {
2300 /* Always do lstat for UNIX calls. */
2301 if (SMB_VFS_LSTAT(conn,fname,&sbuf)) {
2302 DEBUG(3,("call_trans2qfilepathinfo: SMB_VFS_LSTAT of %s failed (%s)\n",fname,strerror(errno)));
2303 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRbadpath);
2305 } else if (!VALID_STAT(sbuf) && SMB_VFS_STAT(conn,fname,&sbuf)) {
2306 DEBUG(3,("call_trans2qfilepathinfo: SMB_VFS_STAT of %s failed (%s)\n",fname,strerror(errno)));
2307 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRbadpath);
2310 delete_pending = fsp->is_directory ? fsp->directory_delete_on_close : 0;
2313 * Original code - this is an open file.
2315 CHECK_FSP(fsp,conn);
2317 pstrcpy(fname, fsp->fsp_name);
2318 if (SMB_VFS_FSTAT(fsp,fsp->fd,&sbuf) != 0) {
2319 DEBUG(3,("fstat of fnum %d failed (%s)\n", fsp->fnum, strerror(errno)));
2320 return(UNIXERROR(ERRDOS,ERRbadfid));
2322 pos = fsp->position_information;
2323 delete_pending = fsp->delete_on_close;
2324 desired_access = fsp->desired_access;
2327 NTSTATUS status = NT_STATUS_OK;
2330 if (total_params < 6)
2331 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
2333 info_level = SVAL(params,0);
2335 DEBUG(3,("call_trans2qfilepathinfo: TRANSACT2_QPATHINFO: level = %d\n", info_level));
2337 srvstr_get_path(inbuf, fname, ¶ms[6], sizeof(fname), -1, STR_TERMINATE, &status);
2338 if (!NT_STATUS_IS_OK(status)) {
2339 return ERROR_NT(status);
2342 RESOLVE_DFSPATH(fname, conn, inbuf, outbuf);
2344 unix_convert(fname,conn,0,&bad_path,&sbuf);
2345 if (!check_name(fname,conn)) {
2346 DEBUG(3,("call_trans2qfilepathinfo: fileinfo of %s failed (%s)\n",fname,strerror(errno)));
2347 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRbadpath);
2350 if (INFO_LEVEL_IS_UNIX(info_level)) {
2351 /* Always do lstat for UNIX calls. */
2352 if (SMB_VFS_LSTAT(conn,fname,&sbuf)) {
2353 DEBUG(3,("call_trans2qfilepathinfo: SMB_VFS_LSTAT of %s failed (%s)\n",fname,strerror(errno)));
2354 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRbadpath);
2356 } else if (!VALID_STAT(sbuf) && SMB_VFS_STAT(conn,fname,&sbuf) && (info_level != SMB_INFO_IS_NAME_VALID)) {
2357 DEBUG(3,("call_trans2qfilepathinfo: SMB_VFS_STAT of %s failed (%s)\n",fname,strerror(errno)));
2358 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRbadpath);
2362 if (INFO_LEVEL_IS_UNIX(info_level) && !lp_unix_extensions())
2363 return ERROR_DOS(ERRDOS,ERRunknownlevel);
2365 DEBUG(3,("call_trans2qfilepathinfo %s (fnum = %d) level=%d call=%d total_data=%d\n",
2366 fname,fsp ? fsp->fnum : -1, info_level,tran_call,total_data));
2368 p = strrchr_m(fname,'/');
2374 mode = dos_mode(conn,fname,&sbuf);
2376 mode = FILE_ATTRIBUTE_NORMAL;
2378 fullpathname = fname;
2379 file_size = get_file_size(sbuf);
2380 allocation_size = get_allocation_size(fsp,&sbuf);
2384 params = Realloc(*pparams,2);
2386 return ERROR_DOS(ERRDOS,ERRnomem);
2388 memset((char *)params,'\0',2);
2389 data_size = max_data_bytes + 1024;
2390 pdata = Realloc(*ppdata, data_size);
2391 if ( pdata == NULL )
2392 return ERROR_DOS(ERRDOS,ERRnomem);
2395 if (total_data > 0 && IVAL(pdata,0) == total_data) {
2396 /* uggh, EAs for OS2 */
2397 DEBUG(4,("Rejecting EA request with total_data=%d\n",total_data));
2398 return ERROR_DOS(ERRDOS,ERReasnotsupported);
2401 memset((char *)pdata,'\0',data_size);
2403 c_time = get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(conn)));
2405 if (lp_dos_filetime_resolution(SNUM(conn))) {
2407 sbuf.st_atime &= ~1;
2408 sbuf.st_ctime &= ~1;
2409 sbuf.st_mtime &= ~1;
2412 /* NT expects the name to be in an exact form of the *full*
2413 filename. See the trans2 torture test */
2414 if (strequal(base_name,".")) {
2415 pstrcpy(dos_fname, "\\");
2417 pstr_sprintf(dos_fname, "\\%s", fname);
2418 string_replace(dos_fname, '/', '\\');
2421 switch (info_level) {
2422 case SMB_INFO_STANDARD:
2423 DEBUG(10,("call_trans2qfilepathinfo: SMB_INFO_STANDARD\n"));
2425 put_dos_date2(pdata,l1_fdateCreation,c_time);
2426 put_dos_date2(pdata,l1_fdateLastAccess,sbuf.st_atime);
2427 put_dos_date2(pdata,l1_fdateLastWrite,sbuf.st_mtime); /* write time */
2428 SIVAL(pdata,l1_cbFile,(uint32)file_size);
2429 SIVAL(pdata,l1_cbFileAlloc,(uint32)allocation_size);
2430 SSVAL(pdata,l1_attrFile,mode);
2433 case SMB_INFO_QUERY_EA_SIZE:
2435 unsigned int ea_size = estimate_ea_size(conn, fsp, fname);
2436 DEBUG(10,("call_trans2qfilepathinfo: SMB_INFO_QUERY_EA_SIZE\n"));
2438 put_dos_date2(pdata,l1_fdateCreation,c_time);
2439 put_dos_date2(pdata,l1_fdateLastAccess,sbuf.st_atime);
2440 put_dos_date2(pdata,l1_fdateLastWrite,sbuf.st_mtime); /* write time */
2441 SIVAL(pdata,l1_cbFile,(uint32)file_size);
2442 SIVAL(pdata,l1_cbFileAlloc,(uint32)allocation_size);
2443 SSVAL(pdata,l1_attrFile,mode);
2444 SIVAL(pdata,l1_attrFile+2,ea_size);
2448 case SMB_INFO_IS_NAME_VALID:
2449 DEBUG(10,("call_trans2qfilepathinfo: SMB_INFO_IS_NAME_VALID\n"));
2450 if (tran_call == TRANSACT2_QFILEINFO) {
2451 /* os/2 needs this ? really ?*/
2452 return ERROR_DOS(ERRDOS,ERRbadfunc);
2458 case SMB_INFO_QUERY_EAS_FROM_LIST:
2459 DEBUG(10,("call_trans2qfilepathinfo: SMB_INFO_QUERY_EAS_FROM_LIST\n"));
2461 put_dos_date2(pdata,0,c_time);
2462 put_dos_date2(pdata,4,sbuf.st_atime);
2463 put_dos_date2(pdata,8,sbuf.st_mtime);
2464 SIVAL(pdata,12,(uint32)file_size);
2465 SIVAL(pdata,16,(uint32)allocation_size);
2466 SIVAL(pdata,20,mode);
2469 case SMB_INFO_QUERY_ALL_EAS:
2470 DEBUG(10,("call_trans2qfilepathinfo: SMB_INFO_QUERY_ALL_EAS\n"));
2471 /* We have data_size bytes to put EA's into. */
2472 data_size = fill_ea_buffer(pdata, data_size, conn, fsp, fname);
2475 case SMB_FILE_BASIC_INFORMATION:
2476 case SMB_QUERY_FILE_BASIC_INFO:
2478 if (info_level == SMB_QUERY_FILE_BASIC_INFO) {
2479 DEBUG(10,("call_trans2qfilepathinfo: SMB_QUERY_FILE_BASIC_INFO\n"));
2480 data_size = 36; /* w95 returns 40 bytes not 36 - why ?. */
2482 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_BASIC_INFORMATION\n"));
2486 put_long_date(pdata,c_time);
2487 put_long_date(pdata+8,sbuf.st_atime);
2488 put_long_date(pdata+16,sbuf.st_mtime); /* write time */
2489 put_long_date(pdata+24,sbuf.st_mtime); /* change time */
2490 SIVAL(pdata,32,mode);
2492 DEBUG(5,("SMB_QFBI - "));
2494 time_t create_time = c_time;
2495 DEBUG(5,("create: %s ", ctime(&create_time)));
2497 DEBUG(5,("access: %s ", ctime(&sbuf.st_atime)));
2498 DEBUG(5,("write: %s ", ctime(&sbuf.st_mtime)));
2499 DEBUG(5,("change: %s ", ctime(&sbuf.st_mtime)));
2500 DEBUG(5,("mode: %x\n", mode));
2504 case SMB_FILE_STANDARD_INFORMATION:
2505 case SMB_QUERY_FILE_STANDARD_INFO:
2507 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_STANDARD_INFORMATION\n"));
2509 SOFF_T(pdata,0,allocation_size);
2510 SOFF_T(pdata,8,file_size);
2511 if (delete_pending & sbuf.st_nlink)
2512 SIVAL(pdata,16,sbuf.st_nlink - 1);
2514 SIVAL(pdata,16,sbuf.st_nlink);
2516 SCVAL(pdata,21,(mode&aDIR)?1:0);
2519 case SMB_FILE_EA_INFORMATION:
2520 case SMB_QUERY_FILE_EA_INFO:
2522 unsigned int ea_size = estimate_ea_size(conn, fsp, fname);
2523 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_EA_INFORMATION\n"));
2525 SIVAL(pdata,0,ea_size);
2529 /* Get the 8.3 name - used if NT SMB was negotiated. */
2530 case SMB_QUERY_FILE_ALT_NAME_INFO:
2531 case SMB_FILE_ALTERNATE_NAME_INFORMATION:
2535 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_ALTERNATE_NAME_INFORMATION\n"));
2536 pstrcpy(short_name,base_name);
2537 /* Mangle if not already 8.3 */
2538 if(!mangle_is_8_3(short_name, True)) {
2539 mangle_map(short_name,True,True,SNUM(conn));
2541 len = srvstr_push(outbuf, pdata+4, short_name, -1, STR_UNICODE);
2542 data_size = 4 + len;
2547 case SMB_QUERY_FILE_NAME_INFO:
2549 this must be *exactly* right for ACLs on mapped drives to work
2551 len = srvstr_push(outbuf, pdata+4, dos_fname, -1, STR_UNICODE);
2552 DEBUG(10,("call_trans2qfilepathinfo: SMB_QUERY_FILE_NAME_INFO\n"));
2553 data_size = 4 + len;
2557 case SMB_FILE_ALLOCATION_INFORMATION:
2558 case SMB_QUERY_FILE_ALLOCATION_INFO:
2559 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_ALLOCATION_INFORMATION\n"));
2561 SOFF_T(pdata,0,allocation_size);
2564 case SMB_FILE_END_OF_FILE_INFORMATION:
2565 case SMB_QUERY_FILE_END_OF_FILEINFO:
2566 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_END_OF_FILE_INFORMATION\n"));
2568 SOFF_T(pdata,0,file_size);
2571 case SMB_QUERY_FILE_ALL_INFO:
2572 case SMB_FILE_ALL_INFORMATION:
2574 unsigned int ea_size = estimate_ea_size(conn, fsp, fname);
2575 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_ALL_INFORMATION\n"));
2576 put_long_date(pdata,c_time);
2577 put_long_date(pdata+8,sbuf.st_atime);
2578 put_long_date(pdata+16,sbuf.st_mtime); /* write time */
2579 put_long_date(pdata+24,sbuf.st_mtime); /* change time */
2580 SIVAL(pdata,32,mode);
2582 SOFF_T(pdata,0,allocation_size);
2583 SOFF_T(pdata,8,file_size);
2584 if (delete_pending && sbuf.st_nlink)
2585 SIVAL(pdata,16,sbuf.st_nlink - 1);
2587 SIVAL(pdata,16,sbuf.st_nlink);
2588 SCVAL(pdata,20,delete_pending);
2589 SCVAL(pdata,21,(mode&aDIR)?1:0);
2591 SIVAL(pdata,0,ea_size);
2592 pdata += 4; /* EA info */
2593 len = srvstr_push(outbuf, pdata+4, dos_fname, -1, STR_UNICODE);
2596 data_size = PTR_DIFF(pdata,(*ppdata));
2599 case SMB_FILE_INTERNAL_INFORMATION:
2600 /* This should be an index number - looks like
2603 I think this causes us to fail the IFSKIT
2604 BasicFileInformationTest. -tpot */
2606 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_INTERNAL_INFORMATION\n"));
2607 SIVAL(pdata,0,sbuf.st_dev);
2608 SIVAL(pdata,4,sbuf.st_ino);
2612 case SMB_FILE_ACCESS_INFORMATION:
2613 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_ACCESS_INFORMATION\n"));
2614 SIVAL(pdata,0,desired_access);
2618 case SMB_FILE_NAME_INFORMATION:
2619 /* Pathname with leading '\'. */
2622 byte_len = dos_PutUniCode(pdata+4,dos_fname,max_data_bytes,False);
2623 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_NAME_INFORMATION\n"));
2624 SIVAL(pdata,0,byte_len);
2625 data_size = 4 + byte_len;
2629 case SMB_FILE_DISPOSITION_INFORMATION:
2630 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_DISPOSITION_INFORMATION\n"));
2632 SCVAL(pdata,0,delete_pending);
2635 case SMB_FILE_POSITION_INFORMATION:
2636 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_POSITION_INFORMATION\n"));
2638 SOFF_T(pdata,0,pos);
2641 case SMB_FILE_MODE_INFORMATION:
2642 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_MODE_INFORMATION\n"));
2643 SIVAL(pdata,0,mode);
2647 case SMB_FILE_ALIGNMENT_INFORMATION:
2648 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_ALIGNMENT_INFORMATION\n"));
2649 SIVAL(pdata,0,0); /* No alignment needed. */
2655 * NT4 server just returns "invalid query" to this - if we try to answer
2656 * it then NTws gets a BSOD! (tridge).
2657 * W2K seems to want this. JRA.
2659 case SMB_QUERY_FILE_STREAM_INFO:
2661 case SMB_FILE_STREAM_INFORMATION:
2662 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_STREAM_INFORMATION\n"));
2666 size_t byte_len = dos_PutUniCode(pdata+24,"::$DATA", 0xE, False);
2667 SIVAL(pdata,0,0); /* ??? */
2668 SIVAL(pdata,4,byte_len); /* Byte length of unicode string ::$DATA */
2669 SOFF_T(pdata,8,file_size);
2670 SIVAL(pdata,16,allocation_size);
2671 SIVAL(pdata,20,0); /* ??? */
2672 data_size = 24 + byte_len;
2676 case SMB_QUERY_COMPRESSION_INFO:
2677 case SMB_FILE_COMPRESSION_INFORMATION:
2678 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_COMPRESSION_INFORMATION\n"));
2679 SOFF_T(pdata,0,file_size);
2680 SIVAL(pdata,8,0); /* ??? */
2681 SIVAL(pdata,12,0); /* ??? */
2685 case SMB_FILE_NETWORK_OPEN_INFORMATION:
2686 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_NETWORK_OPEN_INFORMATION\n"));
2687 put_long_date(pdata,c_time);
2688 put_long_date(pdata+8,sbuf.st_atime);
2689 put_long_date(pdata+16,sbuf.st_mtime); /* write time */
2690 put_long_date(pdata+24,sbuf.st_mtime); /* change time */
2691 SIVAL(pdata,32,allocation_size);
2692 SOFF_T(pdata,40,file_size);
2693 SIVAL(pdata,48,mode);
2694 SIVAL(pdata,52,0); /* ??? */
2698 case SMB_FILE_ATTRIBUTE_TAG_INFORMATION:
2699 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_ATTRIBUTE_TAG_INFORMATION\n"));
2700 SIVAL(pdata,0,mode);
2706 * CIFS UNIX Extensions.
2709 case SMB_QUERY_FILE_UNIX_BASIC:
2711 DEBUG(10,("call_trans2qfilepathinfo: SMB_QUERY_FILE_UNIX_BASIC\n"));
2712 DEBUG(4,("call_trans2qfilepathinfo: st_mode=%o\n",(int)sbuf.st_mode));
2714 SOFF_T(pdata,0,get_file_size(sbuf)); /* File size 64 Bit */
2717 SOFF_T(pdata,0,get_allocation_size(fsp,&sbuf)); /* Number of bytes used on disk - 64 Bit */
2720 put_long_date(pdata,sbuf.st_ctime); /* Creation Time 64 Bit */
2721 put_long_date(pdata+8,sbuf.st_atime); /* Last access time 64 Bit */
2722 put_long_date(pdata+16,sbuf.st_mtime); /* Last modification time 64 Bit */
2725 SIVAL(pdata,0,sbuf.st_uid); /* user id for the owner */
2729 SIVAL(pdata,0,sbuf.st_gid); /* group id of owner */
2733 SIVAL(pdata,0,unix_filetype(sbuf.st_mode));
2736 SIVAL(pdata,0,unix_dev_major(sbuf.st_rdev)); /* Major device number if type is device */
2740 SIVAL(pdata,0,unix_dev_minor(sbuf.st_rdev)); /* Minor device number if type is device */
2744 SINO_T(pdata,0,(SMB_INO_T)sbuf.st_ino); /* inode number */
2747 SIVAL(pdata,0, unix_perms_to_wire(sbuf.st_mode)); /* Standard UNIX file permissions */
2751 SIVAL(pdata,0,sbuf.st_nlink); /* number of hard links */
2754 data_size = PTR_DIFF(pdata,(*ppdata));
2758 DEBUG(4,("call_trans2qfilepathinfo: SMB_QUERY_FILE_UNIX_BASIC"));
2760 for (i=0; i<100; i++)
2761 DEBUG(4,("%d=%x, ",i, (*ppdata)[i]));
2767 case SMB_QUERY_FILE_UNIX_LINK:
2771 DEBUG(10,("call_trans2qfilepathinfo: SMB_QUERY_FILE_UNIX_LINK\n"));
2773 if(!S_ISLNK(sbuf.st_mode))
2774 return(UNIXERROR(ERRSRV,ERRbadlink));
2776 return(UNIXERROR(ERRDOS,ERRbadlink));
2778 len = SMB_VFS_READLINK(conn,fullpathname, buffer, sizeof(pstring)-1); /* read link */
2780 return(UNIXERROR(ERRDOS,ERRnoaccess));
2782 len = srvstr_push(outbuf, pdata, buffer, -1, STR_TERMINATE);
2784 data_size = PTR_DIFF(pdata,(*ppdata));
2790 return ERROR_DOS(ERRDOS,ERRunknownlevel);
2793 send_trans2_replies(outbuf, bufsize, params, param_size, *ppdata, data_size);
2798 /****************************************************************************
2799 Deal with the internal needs of setting the delete on close flag. Note that
2800 as the tdb locking is recursive, it is safe to call this from within
2801 open_file_shared. JRA.
2802 ****************************************************************************/
2804 NTSTATUS set_delete_on_close_internal(files_struct *fsp, BOOL delete_on_close)
2807 * Only allow delete on close for writable shares.
2810 if (delete_on_close && !CAN_WRITE(fsp->conn)) {
2811 DEBUG(10,("set_delete_on_close_internal: file %s delete on close flag set but write access denied on share.\n",
2813 return NT_STATUS_ACCESS_DENIED;
2816 * Only allow delete on close for files/directories opened with delete intent.
2819 if (delete_on_close && !(fsp->desired_access & DELETE_ACCESS)) {
2820 DEBUG(10,("set_delete_on_close_internal: file %s delete on close flag set but delete access denied.\n",
2822 return NT_STATUS_ACCESS_DENIED;
2825 if(fsp->is_directory) {
2826 fsp->directory_delete_on_close = delete_on_close;
2827 DEBUG(10, ("set_delete_on_close_internal: %s delete on close flag for fnum = %d, directory %s\n",
2828 delete_on_close ? "Added" : "Removed", fsp->fnum, fsp->fsp_name ));
2830 fsp->delete_on_close = delete_on_close;
2831 DEBUG(10, ("set_delete_on_close_internal: %s delete on close flag for fnum = %d, file %s\n",
2832 delete_on_close ? "Added" : "Removed", fsp->fnum, fsp->fsp_name ));
2835 return NT_STATUS_OK;
2838 /****************************************************************************
2839 Sets the delete on close flag over all share modes on this file.
2840 Modify the share mode entry for all files open
2841 on this device and inode to tell other smbds we have
2842 changed the delete on close flag. This will be noticed
2843 in the close code, the last closer will delete the file
2845 ****************************************************************************/
2847 NTSTATUS set_delete_on_close_over_all(files_struct *fsp, BOOL delete_on_close)
2849 DEBUG(10,("set_delete_on_close_over_all: %s delete on close flag for fnum = %d, file %s\n",
2850 delete_on_close ? "Adding" : "Removing", fsp->fnum, fsp->fsp_name ));
2852 if (fsp->is_directory || fsp->is_stat)
2853 return NT_STATUS_OK;
2855 if (lock_share_entry_fsp(fsp) == False)
2856 return NT_STATUS_ACCESS_DENIED;
2858 if (!modify_delete_flag(fsp->dev, fsp->inode, delete_on_close)) {
2859 DEBUG(0,("set_delete_on_close_internal: failed to change delete on close flag for file %s\n",
2861 unlock_share_entry_fsp(fsp);
2862 return NT_STATUS_ACCESS_DENIED;
2865 unlock_share_entry_fsp(fsp);
2866 return NT_STATUS_OK;
2869 /****************************************************************************
2870 Set a hard link (called by UNIX extensions and by NT rename with HARD link
2872 ****************************************************************************/
2874 NTSTATUS hardlink_internals(connection_struct *conn, char *oldname, char *newname)
2876 BOOL bad_path_oldname = False;
2877 BOOL bad_path_newname = False;
2878 SMB_STRUCT_STAT sbuf1, sbuf2;
2880 pstring last_component_oldname;
2881 pstring last_component_newname;
2882 NTSTATUS status = NT_STATUS_OK;
2888 if (ms_has_wild(newname) || ms_has_wild(oldname)) {
2889 return NT_STATUS_OBJECT_PATH_SYNTAX_BAD;
2892 rc = unix_convert(oldname,conn,last_component_oldname,&bad_path_oldname,&sbuf1);
2893 if (!rc && bad_path_oldname) {
2894 return NT_STATUS_OBJECT_PATH_NOT_FOUND;
2897 /* Quick check for "." and ".." */
2898 if (last_component_oldname[0] == '.') {
2899 if (!last_component_oldname[1] || (last_component_oldname[1] == '.' && !last_component_oldname[2])) {
2900 return NT_STATUS_OBJECT_NAME_INVALID;
2904 /* source must already exist. */
2905 if (!VALID_STAT(sbuf1)) {
2906 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2909 if (!check_name(oldname,conn)) {
2910 return NT_STATUS_ACCESS_DENIED;
2913 rcdest = unix_convert(newname,conn,last_component_newname,&bad_path_newname,&sbuf2);
2914 if (!rcdest && bad_path_newname) {
2915 return NT_STATUS_OBJECT_PATH_NOT_FOUND;
2918 /* Quick check for "." and ".." */
2919 if (last_component_newname[0] == '.') {
2920 if (!last_component_newname[1] || (last_component_newname[1] == '.' && !last_component_newname[2])) {
2921 return NT_STATUS_OBJECT_NAME_INVALID;
2925 /* Disallow if newname already exists. */
2926 if (VALID_STAT(sbuf2)) {
2927 return NT_STATUS_OBJECT_NAME_COLLISION;
2930 if (!check_name(newname,conn)) {
2931 return NT_STATUS_ACCESS_DENIED;
2934 /* No links from a directory. */
2935 if (S_ISDIR(sbuf1.st_mode)) {
2936 return NT_STATUS_FILE_IS_A_DIRECTORY;
2939 /* Ensure this is within the share. */
2940 if (!reduce_name(conn, oldname) != 0)
2941 return NT_STATUS_ACCESS_DENIED;
2943 DEBUG(10,("hardlink_internals: doing hard link %s -> %s\n", newname, oldname ));
2945 if (SMB_VFS_LINK(conn,oldname,newname) != 0) {
2946 status = map_nt_error_from_unix(errno);
2947 DEBUG(3,("hardlink_internals: Error %s hard link %s -> %s\n",
2948 nt_errstr(status), newname, oldname));
2954 /****************************************************************************
2955 Reply to a TRANS2_SETFILEINFO (set file info by fileid).
2956 ****************************************************************************/
2958 static int call_trans2setfilepathinfo(connection_struct *conn,
2959 char *inbuf, char *outbuf, int length, int bufsize,
2960 char **pparams, int total_params, char **ppdata, int total_data)
2962 char *params = *pparams;
2963 char *pdata = *ppdata;
2964 uint16 tran_call = SVAL(inbuf, smb_setup0);
2969 SMB_STRUCT_STAT sbuf;
2972 BOOL bad_path = False;
2973 files_struct *fsp = NULL;
2974 uid_t set_owner = (uid_t)SMB_UID_NO_CHANGE;
2975 gid_t set_grp = (uid_t)SMB_GID_NO_CHANGE;
2976 mode_t unixmode = 0;
2977 NTSTATUS status = NT_STATUS_OK;
2980 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
2982 if (tran_call == TRANSACT2_SETFILEINFO) {
2983 if (total_params < 4)
2984 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
2986 fsp = file_fsp(params,0);
2987 info_level = SVAL(params,2);
2989 if(fsp && (fsp->is_directory || fsp->fd == -1)) {
2991 * This is actually a SETFILEINFO on a directory
2992 * handle (returned from an NT SMB). NT5.0 seems
2993 * to do this call. JRA.
2995 pstrcpy(fname, fsp->fsp_name);
2996 unix_convert(fname,conn,0,&bad_path,&sbuf);
2997 if (!check_name(fname,conn) || (!VALID_STAT(sbuf))) {
2998 DEBUG(3,("call_trans2setfilepathinfo: fileinfo of %s failed (%s)\n",fname,strerror(errno)));
2999 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRbadpath);
3001 } else if (fsp && fsp->print_file) {
3003 * Doing a DELETE_ON_CLOSE should cancel a print job.
3005 if ((info_level == SMB_SET_FILE_DISPOSITION_INFO) && CVAL(pdata,0)) {
3006 fsp->share_mode = FILE_DELETE_ON_CLOSE;
3008 DEBUG(3,("call_trans2setfilepathinfo: Cancelling print job (%s)\n", fsp->fsp_name ));
3011 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
3014 return (UNIXERROR(ERRDOS,ERRbadpath));
3017 * Original code - this is an open file.
3019 CHECK_FSP(fsp,conn);
3021 pstrcpy(fname, fsp->fsp_name);
3024 if (SMB_VFS_FSTAT(fsp,fd,&sbuf) != 0) {
3025 DEBUG(3,("call_trans2setfilepathinfo: fstat of fnum %d failed (%s)\n",fsp->fnum, strerror(errno)));
3026 return(UNIXERROR(ERRDOS,ERRbadfid));
3031 if (total_params < 6)
3032 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
3034 info_level = SVAL(params,0);
3035 srvstr_get_path(inbuf, fname, ¶ms[6], sizeof(fname), -1, STR_TERMINATE, &status);
3036 if (!NT_STATUS_IS_OK(status)) {
3037 return ERROR_NT(status);
3039 unix_convert(fname,conn,0,&bad_path,&sbuf);
3042 * For CIFS UNIX extensions the target name may not exist.
3045 if(!VALID_STAT(sbuf) && !INFO_LEVEL_IS_UNIX(info_level)) {
3046 DEBUG(3,("call_trans2setfilepathinfo: stat of %s failed (%s)\n", fname, strerror(errno)));
3047 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRbadpath);
3050 if(!check_name(fname, conn)) {
3051 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRbadpath);
3056 if (!CAN_WRITE(conn))
3057 return ERROR_DOS(ERRSRV,ERRaccess);
3059 if (INFO_LEVEL_IS_UNIX(info_level) && !lp_unix_extensions())
3060 return ERROR_DOS(ERRDOS,ERRunknownlevel);
3062 if (VALID_STAT(sbuf))
3063 unixmode = sbuf.st_mode;
3065 DEBUG(3,("call_trans2setfilepathinfo(%d) %s (fnum %d) info_level=%d totdata=%d\n",
3066 tran_call,fname, fsp ? fsp->fnum : -1, info_level,total_data));
3068 /* Realloc the parameter and data sizes */
3069 params = Realloc(*pparams,2);
3071 return ERROR_DOS(ERRDOS,ERRnomem);
3077 /* the pending modtime overrides the current modtime */
3078 sbuf.st_mtime = fsp->pending_modtime;
3081 size = get_file_size(sbuf);
3082 tvs.modtime = sbuf.st_mtime;
3083 tvs.actime = sbuf.st_atime;
3084 dosmode = dos_mode(conn,fname,&sbuf);
3085 unixmode = sbuf.st_mode;
3087 set_owner = VALID_STAT(sbuf) ? sbuf.st_uid : (uid_t)SMB_UID_NO_CHANGE;
3088 set_grp = VALID_STAT(sbuf) ? sbuf.st_gid : (gid_t)SMB_GID_NO_CHANGE;
3090 switch (info_level) {
3091 case SMB_INFO_STANDARD:
3093 if (total_data < 12)
3094 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
3097 tvs.actime = make_unix_date2(pdata+l1_fdateLastAccess);
3099 tvs.modtime = make_unix_date2(pdata+l1_fdateLastWrite);
3103 case SMB_INFO_SET_EA:
3104 status = set_ea(conn, fsp, fname, pdata, total_data);
3105 if (NT_STATUS_V(status) != NT_STATUS_V(NT_STATUS_OK))
3106 return ERROR_NT(status);
3109 /* XXXX um, i don't think this is right.
3110 it's also not in the cifs6.txt spec.
3112 case SMB_INFO_QUERY_EAS_FROM_LIST:
3113 if (total_data < 28)
3114 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
3116 tvs.actime = make_unix_date2(pdata+8);
3117 tvs.modtime = make_unix_date2(pdata+12);
3118 size = IVAL(pdata,16);
3119 dosmode = IVAL(pdata,24);
3122 /* XXXX nor this. not in cifs6.txt, either. */
3123 case SMB_INFO_QUERY_ALL_EAS:
3124 if (total_data < 28)
3125 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
3127 tvs.actime = make_unix_date2(pdata+8);
3128 tvs.modtime = make_unix_date2(pdata+12);
3129 size = IVAL(pdata,16);
3130 dosmode = IVAL(pdata,24);
3133 case SMB_SET_FILE_BASIC_INFO:
3134 case SMB_FILE_BASIC_INFORMATION:
3136 /* Patch to do this correctly from Paul Eggert <eggert@twinsun.com>. */
3138 time_t changed_time;
3140 if (total_data < 36)
3141 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
3143 /* Ignore create time at offset pdata. */
3146 tvs.actime = interpret_long_date(pdata+8);
3148 write_time = interpret_long_date(pdata+16);
3149 changed_time = interpret_long_date(pdata+24);
3151 tvs.modtime = MIN(write_time, changed_time);
3153 if (write_time > tvs.modtime && write_time != 0xffffffff) {
3154 tvs.modtime = write_time;
3156 /* Prefer a defined time to an undefined one. */
3157 if (tvs.modtime == (time_t)0 || tvs.modtime == (time_t)-1)
3158 tvs.modtime = (write_time == (time_t)0 || write_time == (time_t)-1
3159 ? changed_time : write_time);
3162 dosmode = IVAL(pdata,32);
3166 case SMB_FILE_ALLOCATION_INFORMATION:
3167 case SMB_SET_FILE_ALLOCATION_INFO:
3170 SMB_BIG_UINT allocation_size;
3173 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
3175 allocation_size = (SMB_BIG_UINT)IVAL(pdata,0);
3176 #ifdef LARGE_SMB_OFF_T
3177 allocation_size |= (((SMB_BIG_UINT)IVAL(pdata,4)) << 32);
3178 #else /* LARGE_SMB_OFF_T */
3179 if (IVAL(pdata,4) != 0) /* more than 32 bits? */
3180 return ERROR_DOS(ERRDOS,ERRunknownlevel);
3181 #endif /* LARGE_SMB_OFF_T */
3182 DEBUG(10,("call_trans2setfilepathinfo: Set file allocation info for file %s to %.0f\n",
3183 fname, (double)allocation_size ));
3185 if (allocation_size)
3186 allocation_size = SMB_ROUNDUP(allocation_size,SMB_ROUNDUP_ALLOCATION_SIZE);
3188 if(allocation_size != get_file_size(sbuf)) {
3189 SMB_STRUCT_STAT new_sbuf;
3191 DEBUG(10,("call_trans2setfilepathinfo: file %s : setting new allocation size to %.0f\n",
3192 fname, (double)allocation_size ));
3195 files_struct *new_fsp = NULL;
3196 int access_mode = 0;
3199 if(global_oplock_break) {
3200 /* Queue this file modify as we are the process of an oplock break. */
3202 DEBUG(2,("call_trans2setfilepathinfo: queueing message due to being "));
3203 DEBUGADD(2,( "in oplock break state.\n"));
3205 push_oplock_pending_smb_message(inbuf, length);
3209 new_fsp = open_file_shared1(conn, fname, &sbuf,FILE_WRITE_DATA,
3210 SET_OPEN_MODE(DOS_OPEN_RDWR),
3211 (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN),
3212 FILE_ATTRIBUTE_NORMAL,
3213 INTERNAL_OPEN_ONLY, &access_mode, &action);
3215 if (new_fsp == NULL)
3216 return(UNIXERROR(ERRDOS,ERRbadpath));
3217 ret = vfs_allocate_file_space(new_fsp, allocation_size);
3218 if (SMB_VFS_FSTAT(new_fsp,new_fsp->fd,&new_sbuf) != 0) {
3219 DEBUG(3,("call_trans2setfilepathinfo: fstat of fnum %d failed (%s)\n",
3220 new_fsp->fnum, strerror(errno)));
3223 close_file(new_fsp,True);
3225 ret = vfs_allocate_file_space(fsp, allocation_size);
3226 if (SMB_VFS_FSTAT(fsp,fd,&new_sbuf) != 0) {
3227 DEBUG(3,("call_trans2setfilepathinfo: fstat of fnum %d failed (%s)\n",
3228 fsp->fnum, strerror(errno)));
3233 return ERROR_NT(NT_STATUS_DISK_FULL);
3235 /* Allocate can truncate size... */
3236 size = get_file_size(new_sbuf);
3242 case SMB_FILE_END_OF_FILE_INFORMATION:
3243 case SMB_SET_FILE_END_OF_FILE_INFO:
3246 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
3248 size = IVAL(pdata,0);
3249 #ifdef LARGE_SMB_OFF_T
3250 size |= (((SMB_OFF_T)IVAL(pdata,4)) << 32);
3251 #else /* LARGE_SMB_OFF_T */
3252 if (IVAL(pdata,4) != 0) /* more than 32 bits? */
3253 return ERROR_DOS(ERRDOS,ERRunknownlevel);
3254 #endif /* LARGE_SMB_OFF_T */
3255 DEBUG(10,("call_trans2setfilepathinfo: Set end of file info for file %s to %.0f\n", fname, (double)size ));
3259 case SMB_FILE_DISPOSITION_INFORMATION:
3260 case SMB_SET_FILE_DISPOSITION_INFO: /* Set delete on close for open file. */
3262 BOOL delete_on_close;
3265 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
3267 delete_on_close = (CVAL(pdata,0) ? True : False);
3269 /* Just ignore this set on a path. */
3270 if (tran_call != TRANSACT2_SETFILEINFO)
3274 return(UNIXERROR(ERRDOS,ERRbadfid));
3276 status = set_delete_on_close_internal(fsp, delete_on_close);
3278 if (NT_STATUS_V(status) != NT_STATUS_V(NT_STATUS_OK))
3279 return ERROR_NT(status);
3281 /* The set is across all open files on this dev/inode pair. */
3282 status =set_delete_on_close_over_all(fsp, delete_on_close);
3283 if (NT_STATUS_V(status) != NT_STATUS_V(NT_STATUS_OK))
3284 return ERROR_NT(status);
3289 case SMB_FILE_POSITION_INFORMATION:
3291 SMB_BIG_UINT position_information;
3294 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
3296 position_information = (SMB_BIG_UINT)IVAL(pdata,0);
3297 #ifdef LARGE_SMB_OFF_T
3298 position_information |= (((SMB_BIG_UINT)IVAL(pdata,4)) << 32);
3299 #else /* LARGE_SMB_OFF_T */
3300 if (IVAL(pdata,4) != 0) /* more than 32 bits? */
3301 return ERROR_DOS(ERRDOS,ERRunknownlevel);
3302 #endif /* LARGE_SMB_OFF_T */
3303 DEBUG(10,("call_trans2setfilepathinfo: Set file position information for file %s to %.0f\n",
3304 fname, (double)position_information ));
3306 fsp->position_information = position_information;
3311 * CIFS UNIX extensions.
3314 case SMB_SET_FILE_UNIX_BASIC:
3316 uint32 raw_unixmode;
3318 if (total_data < 100)
3319 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
3321 if(IVAL(pdata, 0) != SMB_SIZE_NO_CHANGE_LO &&
3322 IVAL(pdata, 4) != SMB_SIZE_NO_CHANGE_HI) {
3323 size=IVAL(pdata,0); /* first 8 Bytes are size */
3324 #ifdef LARGE_SMB_OFF_T
3325 size |= (((SMB_OFF_T)IVAL(pdata,4)) << 32);
3326 #else /* LARGE_SMB_OFF_T */
3327 if (IVAL(pdata,4) != 0) /* more than 32 bits? */
3328 return ERROR_DOS(ERRDOS,ERRunknownlevel);
3329 #endif /* LARGE_SMB_OFF_T */
3331 pdata+=24; /* ctime & st_blocks are not changed */
3332 tvs.actime = interpret_long_unix_date(pdata); /* access_time */
3333 tvs.modtime = interpret_long_unix_date(pdata+8); /* modification_time */
3335 set_owner = (uid_t)IVAL(pdata,0);
3337 set_grp = (gid_t)IVAL(pdata,0);
3339 raw_unixmode = IVAL(pdata,28);
3340 unixmode = unix_perms_from_wire(conn, &sbuf, raw_unixmode);
3341 dosmode = 0; /* Ensure dos mode change doesn't override this. */
3343 DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_BASIC: name = %s \
3344 size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n",
3345 fname, (double)size, (unsigned int)set_owner, (unsigned int)set_grp, (int)raw_unixmode));
3347 if (!VALID_STAT(sbuf)) {
3350 * The only valid use of this is to create character and block
3351 * devices, and named pipes. This is deprecated (IMHO) and
3352 * a new info level should be used for mknod. JRA.
3355 #if !defined(HAVE_MAKEDEV_FN)
3356 return(ERROR_DOS(ERRDOS,ERRnoaccess));
3357 #else /* HAVE_MAKEDEV_FN */
3358 uint32 file_type = IVAL(pdata,0);
3359 uint32 dev_major = IVAL(pdata,4);
3360 uint32 dev_minor = IVAL(pdata,12);
3362 uid_t myuid = geteuid();
3363 gid_t mygid = getegid();
3366 if (tran_call == TRANSACT2_SETFILEINFO)
3367 return(ERROR_DOS(ERRDOS,ERRnoaccess));
3369 if (raw_unixmode == SMB_MODE_NO_CHANGE)
3370 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
3372 dev = makedev(dev_major, dev_minor);
3374 /* We can only create as the owner/group we are. */
3376 if ((set_owner != myuid) && (set_owner != (uid_t)SMB_UID_NO_CHANGE))
3377 return(ERROR_DOS(ERRDOS,ERRnoaccess));
3378 if ((set_grp != mygid) && (set_grp != (gid_t)SMB_GID_NO_CHANGE))
3379 return(ERROR_DOS(ERRDOS,ERRnoaccess));
3381 if (file_type != UNIX_TYPE_CHARDEV && file_type != UNIX_TYPE_BLKDEV &&
3382 file_type != UNIX_TYPE_FIFO &&
3383 file_type != UNIX_TYPE_SOCKET)
3384 return(ERROR_DOS(ERRDOS,ERRnoaccess));
3386 DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_BASIC doing mknod dev %.0f mode \
3387 0%o for file %s\n", (double)dev, unixmode, fname ));
3389 /* Ok - do the mknod. */
3390 if (SMB_VFS_MKNOD(conn,fname, unixmode, dev) != 0)
3391 return(UNIXERROR(ERRDOS,ERRnoaccess));
3393 inherit_access_acl(conn, fname, unixmode);
3396 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
3398 #endif /* HAVE_MAKEDEV_FN */
3403 * Deal with the UNIX specific mode set.
3406 if (raw_unixmode != SMB_MODE_NO_CHANGE) {
3407 DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_BASIC setting mode 0%o for file %s\n",
3408 (unsigned int)unixmode, fname ));
3409 if (SMB_VFS_CHMOD(conn,fname,unixmode) != 0)
3410 return(UNIXERROR(ERRDOS,ERRnoaccess));
3414 * Deal with the UNIX specific uid set.
3417 if ((set_owner != (uid_t)SMB_UID_NO_CHANGE) && (sbuf.st_uid != set_owner)) {
3418 DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_BASIC changing owner %u for file %s\n",
3419 (unsigned int)set_owner, fname ));
3420 if (SMB_VFS_CHOWN(conn,fname,set_owner, (gid_t)-1) != 0)
3421 return(UNIXERROR(ERRDOS,ERRnoaccess));
3425 * Deal with the UNIX specific gid set.
3428 if ((set_grp != (uid_t)SMB_GID_NO_CHANGE) && (sbuf.st_gid != set_grp)) {
3429 DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_BASIC changing group %u for file %s\n",
3430 (unsigned int)set_owner, fname ));
3431 if (SMB_VFS_CHOWN(conn,fname,(uid_t)-1, set_grp) != 0)
3432 return(UNIXERROR(ERRDOS,ERRnoaccess));
3437 case SMB_SET_FILE_UNIX_LINK:
3439 pstring link_target;
3440 char *newname = fname;
3442 /* Set a symbolic link. */
3443 /* Don't allow this if follow links is false. */
3445 if (!lp_symlinks(SNUM(conn)))
3446 return(ERROR_DOS(ERRDOS,ERRnoaccess));
3448 srvstr_pull(inbuf, link_target, pdata, sizeof(link_target), -1, STR_TERMINATE);
3450 /* !widelinks forces the target path to be within the share. */
3451 /* This means we can interpret the target as a pathname. */
3452 if (!lp_widelinks(SNUM(conn))) {
3454 char *last_dirp = NULL;
3456 unix_format(link_target);
3457 if (*link_target == '/') {
3458 /* No absolute paths allowed. */
3459 return(UNIXERROR(ERRDOS,ERRnoaccess));
3461 pstrcpy(rel_name, newname);
3462 last_dirp = strrchr_m(rel_name, '/');
3464 last_dirp[1] = '\0';
3466 pstrcpy(rel_name, "./");
3468 pstrcat(rel_name, link_target);
3470 if (!check_name(rel_name, conn)) {
3471 return(UNIXERROR(ERRDOS,ERRnoaccess));
3475 DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_LINK doing symlink %s -> %s\n",
3476 fname, link_target ));
3478 if (SMB_VFS_SYMLINK(conn,link_target,newname) != 0)
3479 return(UNIXERROR(ERRDOS,ERRnoaccess));
3481 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
3485 case SMB_SET_FILE_UNIX_HLINK:
3488 char *newname = fname;
3490 /* Set a hard link. */
3491 srvstr_get_path(inbuf, oldname, pdata, sizeof(oldname), -1, STR_TERMINATE, &status);
3492 if (!NT_STATUS_IS_OK(status)) {
3493 return ERROR_NT(status);
3496 DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_LINK doing hard link %s -> %s\n",
3499 status = hardlink_internals(conn, oldname, newname);
3500 if (!NT_STATUS_IS_OK(status)) {
3501 return ERROR_NT(status);
3505 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
3509 case SMB_FILE_RENAME_INFORMATION:
3518 if (total_data < 12)
3519 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
3521 overwrite = (CVAL(pdata,0) ? True : False);
3522 root_fid = IVAL(pdata,4);
3523 len = IVAL(pdata,8);
3524 srvstr_get_path(inbuf, newname, &pdata[12], sizeof(newname), len, 0, &status);
3525 if (!NT_STATUS_IS_OK(status)) {
3526 return ERROR_NT(status);
3529 /* Check the new name has no '/' characters. */
3530 if (strchr_m(newname, '/'))
3531 return ERROR_NT(NT_STATUS_NOT_SUPPORTED);
3533 RESOLVE_DFSPATH(newname, conn, inbuf, outbuf);
3535 /* Create the base directory. */
3536 pstrcpy(base_name, fname);
3537 p = strrchr_m(base_name, '/');
3540 /* Append the new name. */
3541 pstrcat(base_name, "/");
3542 pstrcat(base_name, newname);
3545 DEBUG(10,("call_trans2setfilepathinfo: SMB_FILE_RENAME_INFORMATION (fnum %d) %s -> %s\n",
3546 fsp->fnum, fsp->fsp_name, base_name ));
3547 status = rename_internals_fsp(conn, fsp, base_name, overwrite);
3549 DEBUG(10,("call_trans2setfilepathinfo: SMB_FILE_RENAME_INFORMATION %s -> %s\n",
3551 status = rename_internals(conn, fname, base_name, 0, overwrite);
3553 if (!NT_STATUS_IS_OK(status)) {
3554 return ERROR_NT(status);
3556 process_pending_change_notify_queue((time_t)0);
3558 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
3562 return ERROR_DOS(ERRDOS,ERRunknownlevel);
3565 /* get some defaults (no modifications) if any info is zero or -1. */
3566 if (tvs.actime == (time_t)0 || tvs.actime == (time_t)-1)
3567 tvs.actime = sbuf.st_atime;
3569 if (tvs.modtime == (time_t)0 || tvs.modtime == (time_t)-1)
3570 tvs.modtime = sbuf.st_mtime;
3572 DEBUG(6,("actime: %s " , ctime(&tvs.actime)));
3573 DEBUG(6,("modtime: %s ", ctime(&tvs.modtime)));
3574 DEBUG(6,("size: %.0f ", (double)size));
3577 if (S_ISDIR(sbuf.st_mode))
3583 DEBUG(6,("dosmode: %x\n" , dosmode));
3585 if(!((info_level == SMB_SET_FILE_END_OF_FILE_INFO) ||
3586 (info_level == SMB_SET_FILE_ALLOCATION_INFO) ||
3587 (info_level == SMB_FILE_ALLOCATION_INFORMATION) ||
3588 (info_level == SMB_FILE_END_OF_FILE_INFORMATION))) {
3591 * Only do this test if we are not explicitly
3592 * changing the size of a file.
3595 size = get_file_size(sbuf);
3599 * Try and set the times, size and mode of this file -
3600 * if they are different from the current values
3602 if (sbuf.st_mtime != tvs.modtime || sbuf.st_atime != tvs.actime) {
3605 * This was a setfileinfo on an open file.
3606 * NT does this a lot. It's actually pointless
3607 * setting the time here, as it will be overwritten
3608 * on the next write, so we save the request
3609 * away and will set it on file close. JRA.
3612 if (tvs.modtime != (time_t)0 && tvs.modtime != (time_t)-1) {
3613 DEBUG(10,("call_trans2setfilepathinfo: setting pending modtime to %s\n", ctime(&tvs.modtime) ));
3614 fsp->pending_modtime = tvs.modtime;
3619 DEBUG(10,("call_trans2setfilepathinfo: setting utimes to modified values.\n"));
3621 if(file_utime(conn, fname, &tvs)!=0)
3622 return(UNIXERROR(ERRDOS,ERRnoaccess));
3626 /* check the mode isn't different, before changing it */
3627 if ((dosmode != 0) && (dosmode != dos_mode(conn, fname, &sbuf))) {
3629 DEBUG(10,("call_trans2setfilepathinfo: file %s : setting dos mode %x\n", fname, dosmode ));
3631 if(file_set_dosmode(conn, fname, dosmode, NULL)) {
3632 DEBUG(2,("file_set_dosmode of %s failed (%s)\n", fname, strerror(errno)));
3633 return(UNIXERROR(ERRDOS,ERRnoaccess));
3637 if (size != get_file_size(sbuf)) {
3641 DEBUG(10,("call_trans2setfilepathinfo: file %s : setting new size to %.0f\n",
3642 fname, (double)size ));
3645 files_struct *new_fsp = NULL;
3646 int access_mode = 0;
3649 if(global_oplock_break) {
3650 /* Queue this file modify as we are the process of an oplock break. */
3652 DEBUG(2,("call_trans2setfilepathinfo: queueing message due to being "));
3653 DEBUGADD(2,( "in oplock break state.\n"));
3655 push_oplock_pending_smb_message(inbuf, length);
3659 new_fsp = open_file_shared(conn, fname, &sbuf,
3660 SET_OPEN_MODE(DOS_OPEN_RDWR),
3661 (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN),
3662 FILE_ATTRIBUTE_NORMAL,
3663 INTERNAL_OPEN_ONLY, &access_mode, &action);
3665 if (new_fsp == NULL)
3666 return(UNIXERROR(ERRDOS,ERRbadpath));
3667 ret = vfs_set_filelen(new_fsp, size);
3668 close_file(new_fsp,True);
3670 ret = vfs_set_filelen(fsp, size);
3674 return (UNIXERROR(ERRHRD,ERRdiskfull));
3678 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
3683 /****************************************************************************
3684 Reply to a TRANS2_MKDIR (make directory with extended attributes).
3685 ****************************************************************************/
3687 static int call_trans2mkdir(connection_struct *conn,
3688 char *inbuf, char *outbuf, int length, int bufsize,
3689 char **pparams, int total_params, char **ppdata, int total_data)
3691 char *params = *pparams;
3694 SMB_STRUCT_STAT sbuf;
3695 BOOL bad_path = False;
3696 NTSTATUS status = NT_STATUS_OK;
3698 if (!CAN_WRITE(conn))
3699 return ERROR_DOS(ERRSRV,ERRaccess);
3701 if (total_params < 4)
3702 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
3704 srvstr_get_path(inbuf, directory, ¶ms[4], sizeof(directory), -1, STR_TERMINATE, &status);
3705 if (!NT_STATUS_IS_OK(status)) {
3706 return ERROR_NT(status);
3709 DEBUG(3,("call_trans2mkdir : name = %s\n", directory));
3711 unix_convert(directory,conn,0,&bad_path,&sbuf);
3712 if (check_name(directory,conn))
3713 ret = vfs_MkDir(conn,directory,unix_mode(conn,aDIR,directory));
3716 DEBUG(5,("call_trans2mkdir error (%s)\n", strerror(errno)));
3717 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRnoaccess);
3720 /* Realloc the parameter and data sizes */
3721 params = Realloc(*pparams,2);
3723 return ERROR_DOS(ERRDOS,ERRnomem);
3728 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
3733 /****************************************************************************
3734 Reply to a TRANS2_FINDNOTIFYFIRST (start monitoring a directory for changes).
3735 We don't actually do this - we just send a null response.
3736 ****************************************************************************/
3738 static int call_trans2findnotifyfirst(connection_struct *conn,
3739 char *inbuf, char *outbuf, int length, int bufsize,
3740 char **pparams, int total_params, char **ppdata, int total_data)
3742 static uint16 fnf_handle = 257;
3743 char *params = *pparams;
3746 if (total_params < 6)
3747 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
3749 info_level = SVAL(params,4);
3750 DEBUG(3,("call_trans2findnotifyfirst - info_level %d\n", info_level));
3752 switch (info_level) {
3757 return ERROR_DOS(ERRDOS,ERRunknownlevel);
3760 /* Realloc the parameter and data sizes */
3761 params = Realloc(*pparams,6);
3763 return ERROR_DOS(ERRDOS,ERRnomem);
3766 SSVAL(params,0,fnf_handle);
3767 SSVAL(params,2,0); /* No changes */
3768 SSVAL(params,4,0); /* No EA errors */
3775 send_trans2_replies(outbuf, bufsize, params, 6, *ppdata, 0);
3780 /****************************************************************************
3781 Reply to a TRANS2_FINDNOTIFYNEXT (continue monitoring a directory for
3782 changes). Currently this does nothing.
3783 ****************************************************************************/
3785 static int call_trans2findnotifynext(connection_struct *conn,
3786 char *inbuf, char *outbuf, int length, int bufsize,
3787 char **pparams, int total_params, char **ppdata, int total_data)
3789 char *params = *pparams;
3791 DEBUG(3,("call_trans2findnotifynext\n"));
3793 /* Realloc the parameter and data sizes */
3794 params = Realloc(*pparams,4);
3796 return ERROR_DOS(ERRDOS,ERRnomem);
3799 SSVAL(params,0,0); /* No changes */
3800 SSVAL(params,2,0); /* No EA errors */
3802 send_trans2_replies(outbuf, bufsize, params, 4, *ppdata, 0);
3807 /****************************************************************************
3808 Reply to a TRANS2_GET_DFS_REFERRAL - Shirish Kalele <kalele@veritas.com>.
3809 ****************************************************************************/
3811 static int call_trans2getdfsreferral(connection_struct *conn, char* inbuf,
3812 char* outbuf, int length, int bufsize,
3813 char **pparams, int total_params, char **ppdata, int total_data)
3815 char *params = *pparams;
3818 int max_referral_level;
3820 DEBUG(10,("call_trans2getdfsreferral\n"));
3822 if (total_params < 2)
3823 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
3825 max_referral_level = SVAL(params,0);
3827 if(!lp_host_msdfs())
3828 return ERROR_DOS(ERRDOS,ERRbadfunc);
3830 srvstr_pull(inbuf, pathname, ¶ms[2], sizeof(pathname), -1, STR_TERMINATE);
3831 if((reply_size = setup_dfs_referral(conn, pathname,max_referral_level,ppdata)) < 0)
3832 return UNIXERROR(ERRDOS,ERRbadfile);
3834 SSVAL(outbuf,smb_flg2,SVAL(outbuf,smb_flg2) | FLAGS2_DFS_PATHNAMES);
3835 send_trans2_replies(outbuf,bufsize,0,0,*ppdata,reply_size);
3840 #define LMCAT_SPL 0x53
3841 #define LMFUNC_GETJOBID 0x60
3843 /****************************************************************************
3844 Reply to a TRANS2_IOCTL - used for OS/2 printing.
3845 ****************************************************************************/
3847 static int call_trans2ioctl(connection_struct *conn, char* inbuf,
3848 char* outbuf, int length, int bufsize,
3849 char **pparams, int total_params, char **ppdata, int total_data)
3851 char *pdata = *ppdata;
3852 files_struct *fsp = file_fsp(inbuf,smb_vwv15);
3854 /* check for an invalid fid before proceeding */
3857 return(ERROR_DOS(ERRDOS,ERRbadfid));
3859 if ((SVAL(inbuf,(smb_setup+4)) == LMCAT_SPL) &&
3860 (SVAL(inbuf,(smb_setup+6)) == LMFUNC_GETJOBID)) {
3861 pdata = Realloc(*ppdata, 32);
3863 return ERROR_DOS(ERRDOS,ERRnomem);
3866 /* NOTE - THIS IS ASCII ONLY AT THE MOMENT - NOT SURE IF OS/2
3867 CAN ACCEPT THIS IN UNICODE. JRA. */
3869 SSVAL(pdata,0,fsp->rap_print_jobid); /* Job number */
3870 srvstr_push( outbuf, pdata + 2, global_myname(), 15, STR_ASCII|STR_TERMINATE); /* Our NetBIOS name */
3871 srvstr_push( outbuf, pdata+18, lp_servicename(SNUM(conn)), 13, STR_ASCII|STR_TERMINATE); /* Service name */
3872 send_trans2_replies(outbuf,bufsize,*pparams,0,*ppdata,32);
3875 DEBUG(2,("Unknown TRANS2_IOCTL\n"));
3876 return ERROR_DOS(ERRSRV,ERRerror);
3880 /****************************************************************************
3881 Reply to a SMBfindclose (stop trans2 directory search).
3882 ****************************************************************************/
3884 int reply_findclose(connection_struct *conn,
3885 char *inbuf,char *outbuf,int length,int bufsize)
3888 int dptr_num=SVALS(inbuf,smb_vwv0);
3889 START_PROFILE(SMBfindclose);
3891 DEBUG(3,("reply_findclose, dptr_num = %d\n", dptr_num));
3893 dptr_close(&dptr_num);
3895 outsize = set_message(outbuf,0,0,True);
3897 DEBUG(3,("SMBfindclose dptr_num = %d\n", dptr_num));
3899 END_PROFILE(SMBfindclose);
3903 /****************************************************************************
3904 Reply to a SMBfindnclose (stop FINDNOTIFYFIRST directory search).
3905 ****************************************************************************/
3907 int reply_findnclose(connection_struct *conn,
3908 char *inbuf,char *outbuf,int length,int bufsize)
3912 START_PROFILE(SMBfindnclose);
3914 dptr_num = SVAL(inbuf,smb_vwv0);
3916 DEBUG(3,("reply_findnclose, dptr_num = %d\n", dptr_num));
3918 /* We never give out valid handles for a
3919 findnotifyfirst - so any dptr_num is ok here.
3922 outsize = set_message(outbuf,0,0,True);
3924 DEBUG(3,("SMB_findnclose dptr_num = %d\n", dptr_num));
3926 END_PROFILE(SMBfindnclose);
3930 /****************************************************************************
3931 Reply to a SMBtranss2 - just ignore it!
3932 ****************************************************************************/
3934 int reply_transs2(connection_struct *conn,
3935 char *inbuf,char *outbuf,int length,int bufsize)
3937 START_PROFILE(SMBtranss2);
3938 DEBUG(4,("Ignoring transs2 of length %d\n",length));
3939 END_PROFILE(SMBtranss2);
3943 /****************************************************************************
3944 Reply to a SMBtrans2.
3945 ****************************************************************************/
3947 int reply_trans2(connection_struct *conn,
3948 char *inbuf,char *outbuf,int length,int bufsize)
3951 unsigned int total_params = SVAL(inbuf, smb_tpscnt);
3952 unsigned int total_data =SVAL(inbuf, smb_tdscnt);
3954 unsigned int max_param_reply = SVAL(inbuf, smb_mprcnt);
3955 unsigned int max_data_reply = SVAL(inbuf, smb_mdrcnt);
3956 unsigned int max_setup_fields = SVAL(inbuf, smb_msrcnt);
3957 BOOL close_tid = BITSETW(inbuf+smb_flags,0);
3958 BOOL no_final_response = BITSETW(inbuf+smb_flags,1);
3959 int32 timeout = IVALS(inbuf,smb_timeout);
3961 unsigned int suwcnt = SVAL(inbuf, smb_suwcnt);
3962 unsigned int tran_call = SVAL(inbuf, smb_setup0);
3963 char *params = NULL, *data = NULL;
3964 unsigned int num_params, num_params_sofar, num_data, num_data_sofar;
3965 START_PROFILE(SMBtrans2);
3967 if(global_oplock_break && (tran_call == TRANSACT2_OPEN)) {
3968 /* Queue this open message as we are the process of an
3971 DEBUG(2,("reply_trans2: queueing message trans2open due to being "));
3972 DEBUGADD(2,( "in oplock break state.\n"));
3974 push_oplock_pending_smb_message(inbuf, length);
3975 END_PROFILE(SMBtrans2);
3979 if (IS_IPC(conn) && (tran_call != TRANSACT2_OPEN)
3980 && (tran_call != TRANSACT2_GET_DFS_REFERRAL)) {
3981 END_PROFILE(SMBtrans2);
3982 return ERROR_DOS(ERRSRV,ERRaccess);
3985 outsize = set_message(outbuf,0,0,True);
3987 /* All trans2 messages we handle have smb_sucnt == 1 - ensure this
3988 is so as a sanity check */
3991 * Need to have rc=0 for ioctl to get job id for OS/2.
3992 * Network printing will fail if function is not successful.
3993 * Similar function in reply.c will be used if protocol
3994 * is LANMAN1.0 instead of LM1.2X002.
3995 * Until DosPrintSetJobInfo with PRJINFO3 is supported,
3996 * outbuf doesn't have to be set(only job id is used).
3998 if ( (suwcnt == 4) && (tran_call == TRANSACT2_IOCTL) &&
3999 (SVAL(inbuf,(smb_setup+4)) == LMCAT_SPL) &&
4000 (SVAL(inbuf,(smb_setup+6)) == LMFUNC_GETJOBID)) {
4001 DEBUG(2,("Got Trans2 DevIOctl jobid\n"));
4003 DEBUG(2,("Invalid smb_sucnt in trans2 call(%u)\n",suwcnt));
4004 DEBUG(2,("Transaction is %d\n",tran_call));
4005 END_PROFILE(SMBtrans2);
4006 ERROR_DOS(ERRDOS,ERRinvalidparam);
4010 /* Allocate the space for the maximum needed parameters and data */
4011 if (total_params > 0)
4012 params = (char *)malloc(total_params);
4014 data = (char *)malloc(total_data);
4016 if ((total_params && !params) || (total_data && !data)) {
4017 DEBUG(2,("Out of memory in reply_trans2\n"));
4020 END_PROFILE(SMBtrans2);
4021 return ERROR_DOS(ERRDOS,ERRnomem);
4024 /* Copy the param and data bytes sent with this request into
4025 the params buffer */
4026 num_params = num_params_sofar = SVAL(inbuf,smb_pscnt);
4027 num_data = num_data_sofar = SVAL(inbuf, smb_dscnt);
4029 if (num_params > total_params || num_data > total_data)
4030 exit_server("invalid params in reply_trans2");
4033 unsigned int psoff = SVAL(inbuf, smb_psoff);
4034 if ((psoff + num_params < psoff) || (psoff + num_params < num_params))
4036 if ((smb_base(inbuf) + psoff + num_params > inbuf + length) ||
4037 (smb_base(inbuf) + psoff + num_params < smb_base(inbuf)))
4039 memcpy( params, smb_base(inbuf) + psoff, num_params);
4042 unsigned int dsoff = SVAL(inbuf, smb_dsoff);
4043 if ((dsoff + num_data < dsoff) || (dsoff + num_data < num_data))
4045 if ((smb_base(inbuf) + dsoff + num_data > inbuf + length) ||
4046 (smb_base(inbuf) + dsoff + num_data < smb_base(inbuf)))
4048 memcpy( data, smb_base(inbuf) + dsoff, num_data);
4051 srv_signing_trans_start(SVAL(inbuf,smb_mid));
4053 if(num_data_sofar < total_data || num_params_sofar < total_params) {
4054 /* We need to send an interim response then receive the rest
4055 of the parameter/data bytes */
4056 outsize = set_message(outbuf,0,0,True);
4057 srv_signing_trans_stop();
4058 if (!send_smb(smbd_server_fd(),outbuf))
4059 exit_server("reply_trans2: send_smb failed.");
4061 while (num_data_sofar < total_data ||
4062 num_params_sofar < total_params) {
4064 unsigned int param_disp;
4065 unsigned int param_off;
4066 unsigned int data_disp;
4067 unsigned int data_off;
4069 ret = receive_next_smb(inbuf,bufsize,SMB_SECONDARY_WAIT);
4072 * The sequence number for the trans reply is always
4073 * based on the last secondary received.
4076 srv_signing_trans_start(SVAL(inbuf,smb_mid));
4079 (CVAL(inbuf, smb_com) != SMBtranss2)) || !ret) {
4080 outsize = set_message(outbuf,0,0,True);
4082 DEBUG(0,("reply_trans2: Invalid secondary trans2 packet\n"));
4084 DEBUG(0,("reply_trans2: %s in getting secondary trans2 response.\n",
4085 (smb_read_error == READ_ERROR) ? "error" : "timeout" ));
4089 /* Revise total_params and total_data in case
4090 they have changed downwards */
4091 if (SVAL(inbuf, smb_tpscnt) < total_params)
4092 total_params = SVAL(inbuf, smb_tpscnt);
4093 if (SVAL(inbuf, smb_tdscnt) < total_data)
4094 total_data = SVAL(inbuf, smb_tdscnt);
4096 num_params = SVAL(inbuf,smb_spscnt);
4097 param_off = SVAL(inbuf, smb_spsoff);
4098 param_disp = SVAL(inbuf, smb_spsdisp);
4099 num_params_sofar += num_params;
4101 num_data = SVAL(inbuf, smb_sdscnt);
4102 data_off = SVAL(inbuf, smb_sdsoff);
4103 data_disp = SVAL(inbuf, smb_sdsdisp);
4104 num_data_sofar += num_data;
4106 if (num_params_sofar > total_params || num_data_sofar > total_data)
4110 if (param_disp + num_params >= total_params)
4112 if ((param_disp + num_params < param_disp) ||
4113 (param_disp + num_params < num_params))
4115 if (param_disp > total_params)
4117 if ((smb_base(inbuf) + param_off + num_params >= inbuf + bufsize) ||
4118 (smb_base(inbuf) + param_off + num_params < smb_base(inbuf)))
4120 if (params + param_disp < params)
4123 memcpy( ¶ms[param_disp], smb_base(inbuf) + param_off, num_params);
4126 if (data_disp + num_data >= total_data)
4128 if ((data_disp + num_data < data_disp) ||
4129 (data_disp + num_data < num_data))
4131 if (data_disp > total_data)
4133 if ((smb_base(inbuf) + data_off + num_data >= inbuf + bufsize) ||
4134 (smb_base(inbuf) + data_off + num_data < smb_base(inbuf)))
4136 if (data + data_disp < data)
4139 memcpy( &data[data_disp], smb_base(inbuf) + data_off, num_data);
4144 if (Protocol >= PROTOCOL_NT1) {
4145 SSVAL(outbuf,smb_flg2,SVAL(outbuf,smb_flg2) | 0x40); /* IS_LONG_NAME */
4148 /* Now we must call the relevant TRANS2 function */
4150 case TRANSACT2_OPEN:
4151 START_PROFILE_NESTED(Trans2_open);
4152 outsize = call_trans2open(conn, inbuf, outbuf, bufsize,
4153 ¶ms, total_params, &data, total_data);
4154 END_PROFILE_NESTED(Trans2_open);
4157 case TRANSACT2_FINDFIRST:
4158 START_PROFILE_NESTED(Trans2_findfirst);
4159 outsize = call_trans2findfirst(conn, inbuf, outbuf, bufsize,
4160 ¶ms, total_params, &data, total_data);
4161 END_PROFILE_NESTED(Trans2_findfirst);
4164 case TRANSACT2_FINDNEXT:
4165 START_PROFILE_NESTED(Trans2_findnext);
4166 outsize = call_trans2findnext(conn, inbuf, outbuf, length, bufsize,
4167 ¶ms, total_params, &data, total_data);
4168 END_PROFILE_NESTED(Trans2_findnext);
4171 case TRANSACT2_QFSINFO:
4172 START_PROFILE_NESTED(Trans2_qfsinfo);
4173 outsize = call_trans2qfsinfo(conn, inbuf, outbuf, length, bufsize,
4174 ¶ms, total_params, &data, total_data);
4175 END_PROFILE_NESTED(Trans2_qfsinfo);
4178 #ifdef HAVE_SYS_QUOTAS
4179 case TRANSACT2_SETFSINFO:
4180 START_PROFILE_NESTED(Trans2_setfsinfo);
4181 outsize = call_trans2setfsinfo(conn, inbuf, outbuf, length, bufsize,
4182 ¶ms, total_params, &data, total_data);
4183 END_PROFILE_NESTED(Trans2_setfsinfo);
4186 case TRANSACT2_QPATHINFO:
4187 case TRANSACT2_QFILEINFO:
4188 START_PROFILE_NESTED(Trans2_qpathinfo);
4189 outsize = call_trans2qfilepathinfo(conn, inbuf, outbuf, length, bufsize,
4190 ¶ms, total_params, &data, total_data);
4191 END_PROFILE_NESTED(Trans2_qpathinfo);
4193 case TRANSACT2_SETPATHINFO:
4194 case TRANSACT2_SETFILEINFO:
4195 START_PROFILE_NESTED(Trans2_setpathinfo);
4196 outsize = call_trans2setfilepathinfo(conn, inbuf, outbuf, length, bufsize,
4197 ¶ms, total_params, &data, total_data);
4198 END_PROFILE_NESTED(Trans2_setpathinfo);
4201 case TRANSACT2_FINDNOTIFYFIRST:
4202 START_PROFILE_NESTED(Trans2_findnotifyfirst);
4203 outsize = call_trans2findnotifyfirst(conn, inbuf, outbuf, length, bufsize,
4204 ¶ms, total_params, &data, total_data);
4205 END_PROFILE_NESTED(Trans2_findnotifyfirst);
4208 case TRANSACT2_FINDNOTIFYNEXT:
4209 START_PROFILE_NESTED(Trans2_findnotifynext);
4210 outsize = call_trans2findnotifynext(conn, inbuf, outbuf, length, bufsize,
4211 ¶ms, total_params, &data, total_data);
4212 END_PROFILE_NESTED(Trans2_findnotifynext);
4214 case TRANSACT2_MKDIR:
4215 START_PROFILE_NESTED(Trans2_mkdir);
4216 outsize = call_trans2mkdir(conn, inbuf, outbuf, length, bufsize,
4217 ¶ms, total_params, &data, total_data);
4218 END_PROFILE_NESTED(Trans2_mkdir);
4221 case TRANSACT2_GET_DFS_REFERRAL:
4222 START_PROFILE_NESTED(Trans2_get_dfs_referral);
4223 outsize = call_trans2getdfsreferral(conn,inbuf,outbuf,length, bufsize,
4224 ¶ms, total_params, &data, total_data);
4225 END_PROFILE_NESTED(Trans2_get_dfs_referral);
4227 case TRANSACT2_IOCTL:
4228 START_PROFILE_NESTED(Trans2_ioctl);
4229 outsize = call_trans2ioctl(conn,inbuf,outbuf,length, bufsize,
4230 ¶ms, total_params, &data, total_data);
4231 END_PROFILE_NESTED(Trans2_ioctl);
4234 /* Error in request */
4235 DEBUG(2,("Unknown request %d in trans2 call\n", tran_call));
4238 END_PROFILE(SMBtrans2);
4239 srv_signing_trans_stop();
4240 return ERROR_DOS(ERRSRV,ERRerror);
4243 /* As we do not know how many data packets will need to be
4244 returned here the various call_trans2xxxx calls
4245 must send their own. Thus a call_trans2xxx routine only
4246 returns a value other than -1 when it wants to send
4250 srv_signing_trans_stop();
4254 END_PROFILE(SMBtrans2);
4255 return outsize; /* If a correct response was needed the
4256 call_trans2xxx calls have already sent
4257 it. If outsize != -1 then it is returning */
4261 srv_signing_trans_stop();
4264 END_PROFILE(SMBtrans2);
4265 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);