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 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRnoaccess);
633 size = get_file_size(sbuf);
634 fmode = dos_mode(conn,fname,&sbuf);
635 mtime = sbuf.st_mtime;
638 close_file(fsp,False);
639 return(ERROR_DOS(ERRDOS,ERRnoaccess));
642 /* Realloc the size of parameters and data we will return */
643 params = Realloc(*pparams, 28);
645 return(ERROR_DOS(ERRDOS,ERRnomem));
648 memset((char *)params,'\0',28);
649 SSVAL(params,0,fsp->fnum);
650 SSVAL(params,2,fmode);
651 put_dos_date2(params,4, mtime);
652 SIVAL(params,8, (uint32)size);
653 SSVAL(params,12,rmode);
655 if (oplock_request && lp_fake_oplocks(SNUM(conn)))
656 smb_action |= EXTENDED_OPLOCK_GRANTED;
658 SSVAL(params,18,smb_action);
661 * WARNING - this may need to be changed if SMB_INO_T <> 4 bytes.
663 SIVAL(params,20,inode);
665 /* Send the required number of replies */
666 send_trans2_replies(outbuf, bufsize, params, 28, *ppdata, 0);
671 /*********************************************************
672 Routine to check if a given string matches exactly.
673 as a special case a mask of "." does NOT match. That
674 is required for correct wildcard semantics
675 Case can be significant or not.
676 **********************************************************/
678 static BOOL exact_match(char *str,char *mask, BOOL case_sig)
680 if (mask[0] == '.' && mask[1] == 0)
683 return strcmp(str,mask)==0;
684 if (StrCaseCmp(str,mask) != 0) {
687 if (ms_has_wild(str)) {
693 /****************************************************************************
694 Return the filetype for UNIX extensions.
695 ****************************************************************************/
697 static uint32 unix_filetype(mode_t mode)
700 return UNIX_TYPE_FILE;
701 else if(S_ISDIR(mode))
702 return UNIX_TYPE_DIR;
704 else if(S_ISLNK(mode))
705 return UNIX_TYPE_SYMLINK;
708 else if(S_ISCHR(mode))
709 return UNIX_TYPE_CHARDEV;
712 else if(S_ISBLK(mode))
713 return UNIX_TYPE_BLKDEV;
716 else if(S_ISFIFO(mode))
717 return UNIX_TYPE_FIFO;
720 else if(S_ISSOCK(mode))
721 return UNIX_TYPE_SOCKET;
724 DEBUG(0,("unix_filetype: unknown filetype %u", (unsigned)mode));
725 return UNIX_TYPE_UNKNOWN;
728 /****************************************************************************
729 Return the major devicenumber for UNIX extensions.
730 ****************************************************************************/
732 static uint32 unix_dev_major(SMB_DEV_T dev)
734 #if defined(HAVE_DEVICE_MAJOR_FN)
735 return (uint32)major(dev);
737 return (uint32)(dev >> 8);
741 /****************************************************************************
742 Return the minor devicenumber for UNIX extensions.
743 ****************************************************************************/
745 static uint32 unix_dev_minor(SMB_DEV_T dev)
747 #if defined(HAVE_DEVICE_MINOR_FN)
748 return (uint32)minor(dev);
750 return (uint32)(dev & 0xff);
754 /****************************************************************************
755 Map wire perms onto standard UNIX permissions. Obey share restrictions.
756 ****************************************************************************/
758 static mode_t unix_perms_from_wire( connection_struct *conn, SMB_STRUCT_STAT *pst, uint32 perms)
762 if (perms == SMB_MODE_NO_CHANGE)
765 ret |= ((perms & UNIX_X_OTH ) ? S_IXOTH : 0);
766 ret |= ((perms & UNIX_W_OTH ) ? S_IWOTH : 0);
767 ret |= ((perms & UNIX_R_OTH ) ? S_IROTH : 0);
768 ret |= ((perms & UNIX_X_GRP ) ? S_IXGRP : 0);
769 ret |= ((perms & UNIX_W_GRP ) ? S_IWGRP : 0);
770 ret |= ((perms & UNIX_R_GRP ) ? S_IRGRP : 0);
771 ret |= ((perms & UNIX_X_USR ) ? S_IXUSR : 0);
772 ret |= ((perms & UNIX_W_USR ) ? S_IWUSR : 0);
773 ret |= ((perms & UNIX_R_USR ) ? S_IRUSR : 0);
775 ret |= ((perms & UNIX_STICKY ) ? S_ISVTX : 0);
778 ret |= ((perms & UNIX_SET_GID ) ? S_ISGID : 0);
781 ret |= ((perms & UNIX_SET_UID ) ? S_ISUID : 0);
784 if (VALID_STAT(*pst) && S_ISDIR(pst->st_mode)) {
785 ret &= lp_dir_mask(SNUM(conn));
786 /* Add in force bits */
787 ret |= lp_force_dir_mode(SNUM(conn));
789 /* Apply mode mask */
790 ret &= lp_create_mask(SNUM(conn));
791 /* Add in force bits */
792 ret |= lp_force_create_mode(SNUM(conn));
798 /****************************************************************************
799 Checks for SMB_TIME_NO_CHANGE and if not found calls interpret_long_date.
800 ****************************************************************************/
802 time_t interpret_long_unix_date(char *p)
804 DEBUG(10,("interpret_long_unix_date\n"));
805 if(IVAL(p,0) == SMB_TIME_NO_CHANGE_LO &&
806 IVAL(p,4) == SMB_TIME_NO_CHANGE_HI) {
809 return interpret_long_date(p);
813 /****************************************************************************
814 Get a level dependent lanman2 dir entry.
815 ****************************************************************************/
817 static BOOL get_lanman2_dir_entry(connection_struct *conn,
818 void *inbuf, void *outbuf,
819 char *path_mask,int dirtype,int info_level,
820 int requires_resume_key,
821 BOOL dont_descend,char **ppdata,
822 char *base_data, int space_remaining,
823 BOOL *out_of_space, BOOL *got_exact_match,
828 SMB_STRUCT_STAT sbuf;
832 char *p, *q, *pdata = *ppdata;
836 SMB_OFF_T file_size = 0;
837 SMB_BIG_UINT allocation_size = 0;
839 time_t mdate=0, adate=0, cdate=0;
842 int nt_extmode; /* Used for NT connections instead of mode */
843 BOOL needslash = ( conn->dirpath[strlen(conn->dirpath) -1] != '/');
846 *out_of_space = False;
847 *got_exact_match = False;
852 p = strrchr_m(path_mask,'/');
859 pstrcpy(mask, path_mask);
864 /* Needed if we run out of space */
865 prev_dirpos = TellDir(conn->dirptr);
866 dname = ReadDirName(conn->dirptr);
869 * Due to bugs in NT client redirectors we are not using
870 * resume keys any more - set them to zero.
871 * Check out the related comments in findfirst/findnext.
877 DEBUG(8,("get_lanman2_dir_entry:readdir on dirptr 0x%lx now at offset %d\n",
878 (long)conn->dirptr,TellDir(conn->dirptr)));
883 pstrcpy(fname,dname);
885 if(!(got_match = *got_exact_match = exact_match(fname, mask, conn->case_sensitive)))
886 got_match = mask_match(fname, mask, conn->case_sensitive);
888 if(!got_match && !mangle_is_8_3(fname, False)) {
891 * It turns out that NT matches wildcards against
892 * both long *and* short names. This may explain some
893 * of the wildcard wierdness from old DOS clients
894 * that some people have been seeing.... JRA.
898 pstrcpy( newname, fname);
899 mangle_map( newname, True, False, SNUM(conn));
900 if(!(got_match = *got_exact_match = exact_match(newname, mask, conn->case_sensitive)))
901 got_match = mask_match(newname, mask, conn->case_sensitive);
905 BOOL isdots = (strequal(fname,"..") || strequal(fname,"."));
906 if (dont_descend && !isdots)
909 pstrcpy(pathreal,conn->dirpath);
911 pstrcat(pathreal,"/");
912 pstrcat(pathreal,dname);
914 if (INFO_LEVEL_IS_UNIX(info_level)) {
915 if (SMB_VFS_LSTAT(conn,pathreal,&sbuf) != 0) {
916 DEBUG(5,("get_lanman2_dir_entry:Couldn't lstat [%s] (%s)\n",
917 pathreal,strerror(errno)));
920 } else if (SMB_VFS_STAT(conn,pathreal,&sbuf) != 0) {
922 /* Needed to show the msdfs symlinks as
925 if(lp_host_msdfs() &&
926 lp_msdfs_root(SNUM(conn)) &&
927 is_msdfs_link(conn, pathreal, NULL, NULL,
930 DEBUG(5,("get_lanman2_dir_entry: Masquerading msdfs link %s as a directory\n", pathreal));
931 sbuf.st_mode = (sbuf.st_mode & 0xFFF) | S_IFDIR;
935 DEBUG(5,("get_lanman2_dir_entry:Couldn't stat [%s] (%s)\n",
936 pathreal,strerror(errno)));
941 mode = dos_mode(conn,pathreal,&sbuf);
943 if (!dir_check_ftype(conn,mode,&sbuf,dirtype)) {
944 DEBUG(5,("[%s] attribs didn't match %x\n",fname,dirtype));
948 file_size = get_file_size(sbuf);
949 allocation_size = get_allocation_size(NULL,&sbuf);
950 mdate = sbuf.st_mtime;
951 adate = sbuf.st_atime;
952 cdate = get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(conn)));
954 if (lp_dos_filetime_resolution(SNUM(conn))) {
963 DEBUG(5,("get_lanman2_dir_entry found %s fname=%s\n",pathreal,fname));
969 mangle_map(fname,False,True,SNUM(conn));
974 nt_extmode = mode ? mode : FILE_ATTRIBUTE_NORMAL;
976 switch (info_level) {
977 case SMB_INFO_STANDARD:
978 DEBUG(10,("get_lanman2_dir_entry: SMB_INFO_STANDARD\n"));
979 if(requires_resume_key) {
983 put_dos_date2(p,l1_fdateCreation,cdate);
984 put_dos_date2(p,l1_fdateLastAccess,adate);
985 put_dos_date2(p,l1_fdateLastWrite,mdate);
986 SIVAL(p,l1_cbFile,(uint32)file_size);
987 SIVAL(p,l1_cbFileAlloc,(uint32)allocation_size);
988 SSVAL(p,l1_attrFile,mode);
991 p += align_string(outbuf, p, 0);
992 len = srvstr_push(outbuf, p, fname, -1, STR_TERMINATE);
993 if (SVAL(outbuf, smb_flg2) & FLAGS2_UNICODE_STRINGS) {
995 SCVAL(nameptr, -1, len - 2);
997 SCVAL(nameptr, -1, 0);
1001 SCVAL(nameptr, -1, len - 1);
1003 SCVAL(nameptr, -1, 0);
1009 case SMB_INFO_QUERY_EA_SIZE:
1010 DEBUG(10,("get_lanman2_dir_entry: SMB_INFO_QUERY_EA_SIZE\n"));
1011 if(requires_resume_key) {
1015 put_dos_date2(p,l2_fdateCreation,cdate);
1016 put_dos_date2(p,l2_fdateLastAccess,adate);
1017 put_dos_date2(p,l2_fdateLastWrite,mdate);
1018 SIVAL(p,l2_cbFile,(uint32)file_size);
1019 SIVAL(p,l2_cbFileAlloc,(uint32)allocation_size);
1020 SSVAL(p,l2_attrFile,mode);
1022 unsigned int ea_size = estimate_ea_size(conn, NULL, pathreal);
1023 SIVAL(p,l2_cbList,ea_size); /* Extended attributes */
1027 len = srvstr_push(outbuf, p, fname, -1, STR_TERMINATE | STR_NOALIGN);
1028 if (SVAL(outbuf, smb_flg2) & FLAGS2_UNICODE_STRINGS) {
1041 SCVAL(nameptr,0,len);
1043 SCVAL(p,0,0); p += 1; /* Extra zero byte ? - why.. */
1046 case SMB_FIND_FILE_BOTH_DIRECTORY_INFO:
1047 DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_FILE_BOTH_DIRECTORY_INFO\n"));
1048 was_8_3 = mangle_is_8_3(fname, True);
1050 SIVAL(p,0,reskey); p += 4;
1051 put_long_date(p,cdate); p += 8;
1052 put_long_date(p,adate); p += 8;
1053 put_long_date(p,mdate); p += 8;
1054 put_long_date(p,mdate); p += 8;
1055 SOFF_T(p,0,file_size); p += 8;
1056 SOFF_T(p,0,allocation_size); p += 8;
1057 SIVAL(p,0,nt_extmode); p += 4;
1058 q = p; p += 4; /* q is placeholder for name length. */
1060 unsigned int ea_size = estimate_ea_size(conn, NULL, pathreal);
1061 SIVAL(p,0,ea_size); /* Extended attributes */
1064 /* Clear the short name buffer. This is
1065 * IMPORTANT as not doing so will trigger
1066 * a Win2k client bug. JRA.
1069 if (!was_8_3 && lp_manglednames(SNUM(conn))) {
1070 pstring mangled_name;
1071 pstrcpy(mangled_name, fname);
1072 mangle_map(mangled_name,True,True,SNUM(conn));
1073 mangled_name[12] = 0;
1074 len = srvstr_push(outbuf, p+2, mangled_name, 24, STR_UPPER|STR_UNICODE);
1081 len = srvstr_push(outbuf, p, fname, -1, STR_TERMINATE_ASCII);
1084 len = PTR_DIFF(p, pdata);
1085 len = (len + 3) & ~3;
1090 case SMB_FIND_FILE_DIRECTORY_INFO:
1091 DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_FILE_DIRECTORY_INFO\n"));
1093 SIVAL(p,0,reskey); p += 4;
1094 put_long_date(p,cdate); p += 8;
1095 put_long_date(p,adate); p += 8;
1096 put_long_date(p,mdate); p += 8;
1097 put_long_date(p,mdate); p += 8;
1098 SOFF_T(p,0,file_size); p += 8;
1099 SOFF_T(p,0,allocation_size); p += 8;
1100 SIVAL(p,0,nt_extmode); p += 4;
1101 len = srvstr_push(outbuf, p + 4, fname, -1, STR_TERMINATE_ASCII);
1104 len = PTR_DIFF(p, pdata);
1105 len = (len + 3) & ~3;
1110 case SMB_FIND_FILE_FULL_DIRECTORY_INFO:
1111 DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_FILE_FULL_DIRECTORY_INFO\n"));
1113 SIVAL(p,0,reskey); p += 4;
1114 put_long_date(p,cdate); p += 8;
1115 put_long_date(p,adate); p += 8;
1116 put_long_date(p,mdate); p += 8;
1117 put_long_date(p,mdate); p += 8;
1118 SOFF_T(p,0,file_size); p += 8;
1119 SOFF_T(p,0,allocation_size); p += 8;
1120 SIVAL(p,0,nt_extmode); p += 4;
1121 q = p; p += 4; /* q is placeholder for name length. */
1123 unsigned int ea_size = estimate_ea_size(conn, NULL, pathreal);
1124 SIVAL(p,0,ea_size); /* Extended attributes */
1127 len = srvstr_push(outbuf, p, fname, -1, STR_TERMINATE_ASCII);
1131 len = PTR_DIFF(p, pdata);
1132 len = (len + 3) & ~3;
1137 case SMB_FIND_FILE_NAMES_INFO:
1138 DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_FILE_NAMES_INFO\n"));
1140 SIVAL(p,0,reskey); p += 4;
1142 /* this must *not* be null terminated or w2k gets in a loop trying to set an
1143 acl on a dir (tridge) */
1144 len = srvstr_push(outbuf, p, fname, -1, STR_TERMINATE_ASCII);
1147 len = PTR_DIFF(p, pdata);
1148 len = (len + 3) & ~3;
1153 case SMB_FIND_ID_FULL_DIRECTORY_INFO:
1154 DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_ID_FULL_DIRECTORY_INFO\n"));
1156 SIVAL(p,0,reskey); p += 4;
1157 put_long_date(p,cdate); p += 8;
1158 put_long_date(p,adate); p += 8;
1159 put_long_date(p,mdate); p += 8;
1160 put_long_date(p,mdate); p += 8;
1161 SOFF_T(p,0,file_size); p += 8;
1162 SOFF_T(p,0,allocation_size); p += 8;
1163 SIVAL(p,0,nt_extmode); p += 4;
1164 q = p; p += 4; /* q is placeholder for name length. */
1166 unsigned int ea_size = estimate_ea_size(conn, NULL, pathreal);
1167 SIVAL(p,0,ea_size); /* Extended attributes */
1170 SIVAL(p,0,0); p += 4; /* Unknown - reserved ? */
1171 SIVAL(p,0,sbuf.st_dev); p += 4;
1172 SIVAL(p,0,sbuf.st_ino); p += 4;
1173 len = srvstr_push(outbuf, p, fname, -1, STR_TERMINATE_ASCII);
1176 len = PTR_DIFF(p, pdata);
1177 len = (len + 3) & ~3;
1182 case SMB_FIND_ID_BOTH_DIRECTORY_INFO:
1183 DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_ID_BOTH_DIRECTORY_INFO\n"));
1184 was_8_3 = mangle_is_8_3(fname, True);
1186 SIVAL(p,0,reskey); p += 4;
1187 put_long_date(p,cdate); p += 8;
1188 put_long_date(p,adate); p += 8;
1189 put_long_date(p,mdate); p += 8;
1190 put_long_date(p,mdate); p += 8;
1191 SOFF_T(p,0,file_size); p += 8;
1192 SOFF_T(p,0,allocation_size); p += 8;
1193 SIVAL(p,0,nt_extmode); p += 4;
1194 q = p; p += 4; /* q is placeholder for name length */
1196 unsigned int ea_size = estimate_ea_size(conn, NULL, pathreal);
1197 SIVAL(p,0,ea_size); /* Extended attributes */
1200 /* Clear the short name buffer. This is
1201 * IMPORTANT as not doing so will trigger
1202 * a Win2k client bug. JRA.
1205 if (!was_8_3 && lp_manglednames(SNUM(conn))) {
1206 pstring mangled_name;
1207 pstrcpy(mangled_name, fname);
1208 mangle_map(mangled_name,True,True,SNUM(conn));
1209 mangled_name[12] = 0;
1210 len = srvstr_push(outbuf, p+2, mangled_name, 24, STR_UPPER|STR_UNICODE);
1217 SSVAL(p,0,0); p += 2; /* Reserved ? */
1218 SIVAL(p,0,sbuf.st_dev); p += 4;
1219 SIVAL(p,0,sbuf.st_ino); p += 4;
1220 len = srvstr_push(outbuf, p, fname, -1, STR_TERMINATE_ASCII);
1223 len = PTR_DIFF(p, pdata);
1224 len = (len + 3) & ~3;
1229 /* CIFS UNIX Extension. */
1231 case SMB_FIND_FILE_UNIX:
1232 DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_FILE_UNIX\n"));
1234 SIVAL(p,0,reskey); p+= 4; /* Used for continuing search. */
1236 /* Begin of SMB_QUERY_FILE_UNIX_BASIC */
1237 SOFF_T(p,0,get_file_size(sbuf)); /* File size 64 Bit */
1240 SOFF_T(p,0,get_allocation_size(NULL,&sbuf)); /* Number of bytes used on disk - 64 Bit */
1243 put_long_date(p,sbuf.st_ctime); /* Inode change Time 64 Bit */
1244 put_long_date(p+8,sbuf.st_atime); /* Last access time 64 Bit */
1245 put_long_date(p+16,sbuf.st_mtime); /* Last modification time 64 Bit */
1248 SIVAL(p,0,sbuf.st_uid); /* user id for the owner */
1252 SIVAL(p,0,sbuf.st_gid); /* group id of owner */
1256 SIVAL(p,0,unix_filetype(sbuf.st_mode));
1259 SIVAL(p,0,unix_dev_major(sbuf.st_rdev)); /* Major device number if type is device */
1263 SIVAL(p,0,unix_dev_minor(sbuf.st_rdev)); /* Minor device number if type is device */
1267 SINO_T(p,0,(SMB_INO_T)sbuf.st_ino); /* inode number */
1270 SIVAL(p,0, unix_perms_to_wire(sbuf.st_mode)); /* Standard UNIX file permissions */
1274 SIVAL(p,0,sbuf.st_nlink); /* number of hard links */
1278 len = srvstr_push(outbuf, p, fname, -1, STR_TERMINATE);
1281 len = PTR_DIFF(p, pdata);
1282 len = (len + 3) & ~3;
1283 SIVAL(pdata,0,len); /* Offset from this structure to the beginning of the next one */
1285 /* End of SMB_QUERY_FILE_UNIX_BASIC */
1294 if (PTR_DIFF(p,pdata) > space_remaining) {
1295 /* Move the dirptr back to prev_dirpos */
1296 SeekDir(conn->dirptr, prev_dirpos);
1297 *out_of_space = True;
1298 DEBUG(9,("get_lanman2_dir_entry: out of space\n"));
1299 return False; /* Not finished - just out of space */
1302 /* Setup the last_filename pointer, as an offset from base_data */
1303 *last_name_off = PTR_DIFF(nameptr,base_data);
1304 /* Advance the data pointer to the next slot */
1310 /****************************************************************************
1311 Reply to a TRANS2_FINDFIRST.
1312 ****************************************************************************/
1314 static int call_trans2findfirst(connection_struct *conn, char *inbuf, char *outbuf, int bufsize,
1315 char **pparams, int total_params, char **ppdata, int total_data)
1317 /* We must be careful here that we don't return more than the
1318 allowed number of data bytes. If this means returning fewer than
1319 maxentries then so be it. We assume that the redirector has
1320 enough room for the fixed number of parameter bytes it has
1322 uint32 max_data_bytes = SVAL(inbuf, smb_mdrcnt);
1323 char *params = *pparams;
1324 char *pdata = *ppdata;
1325 int dirtype = SVAL(params,0);
1326 int maxentries = SVAL(params,2);
1327 BOOL close_after_first = BITSETW(params+4,0);
1328 BOOL close_if_end = BITSETW(params+4,1);
1329 BOOL requires_resume_key = BITSETW(params+4,2);
1330 int info_level = SVAL(params,6);
1334 int last_name_off=0;
1338 BOOL finished = False;
1339 BOOL dont_descend = False;
1340 BOOL out_of_space = False;
1341 int space_remaining;
1342 BOOL bad_path = False;
1343 SMB_STRUCT_STAT sbuf;
1344 NTSTATUS ntstatus = NT_STATUS_OK;
1346 if (total_params < 12)
1347 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
1349 *directory = *mask = 0;
1351 DEBUG(3,("call_trans2findfirst: dirtype = %d, maxentries = %d, close_after_first=%d, \
1352 close_if_end = %d requires_resume_key = %d level = 0x%x, max_data_bytes = %d\n",
1353 dirtype, maxentries, close_after_first, close_if_end, requires_resume_key,
1354 info_level, max_data_bytes));
1356 switch (info_level) {
1357 case SMB_INFO_STANDARD:
1358 case SMB_INFO_QUERY_EA_SIZE:
1359 case SMB_FIND_FILE_DIRECTORY_INFO:
1360 case SMB_FIND_FILE_FULL_DIRECTORY_INFO:
1361 case SMB_FIND_FILE_NAMES_INFO:
1362 case SMB_FIND_FILE_BOTH_DIRECTORY_INFO:
1363 case SMB_FIND_ID_FULL_DIRECTORY_INFO:
1364 case SMB_FIND_ID_BOTH_DIRECTORY_INFO:
1366 case SMB_FIND_FILE_UNIX:
1367 if (!lp_unix_extensions())
1368 return(ERROR_DOS(ERRDOS,ERRunknownlevel));
1371 return(ERROR_DOS(ERRDOS,ERRunknownlevel));
1374 srvstr_get_path(inbuf, directory, params+12, sizeof(directory), -1, STR_TERMINATE, &ntstatus);
1375 if (!NT_STATUS_IS_OK(ntstatus)) {
1376 return ERROR_NT(ntstatus);
1379 RESOLVE_FINDFIRST_DFSPATH(directory, conn, inbuf, outbuf);
1381 unix_convert(directory,conn,0,&bad_path,&sbuf);
1382 if(!check_name(directory,conn)) {
1383 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRbadpath);
1386 p = strrchr_m(directory,'/');
1388 /* Windows and OS/2 systems treat search on the root '\' as if it were '\*' */
1389 if((directory[0] == '.') && (directory[1] == '\0'))
1392 pstrcpy(mask,directory);
1393 pstrcpy(directory,"./");
1399 DEBUG(5,("dir=%s, mask = %s\n",directory, mask));
1401 pdata = Realloc(*ppdata, max_data_bytes + 1024);
1403 return(ERROR_DOS(ERRDOS,ERRnomem));
1406 memset((char *)pdata,'\0',max_data_bytes + 1024);
1408 /* Realloc the params space */
1409 params = Realloc(*pparams, 10);
1411 return ERROR_DOS(ERRDOS,ERRnomem);
1414 dptr_num = dptr_create(conn,directory, False, True ,SVAL(inbuf,smb_pid));
1416 return(UNIXERROR(ERRDOS,ERRbadfile));
1418 /* Save the wildcard match and attribs we are using on this directory -
1419 needed as lanman2 assumes these are being saved between calls */
1421 if(!(wcard = strdup(mask))) {
1422 dptr_close(&dptr_num);
1423 return ERROR_DOS(ERRDOS,ERRnomem);
1426 dptr_set_wcard(dptr_num, wcard);
1427 dptr_set_attr(dptr_num, dirtype);
1429 DEBUG(4,("dptr_num is %d, wcard = %s, attr = %d\n",dptr_num, wcard, dirtype));
1431 /* We don't need to check for VOL here as this is returned by
1432 a different TRANS2 call. */
1434 DEBUG(8,("dirpath=<%s> dontdescend=<%s>\n", conn->dirpath,lp_dontdescend(SNUM(conn))));
1435 if (in_list(conn->dirpath,lp_dontdescend(SNUM(conn)),conn->case_sensitive))
1436 dont_descend = True;
1439 space_remaining = max_data_bytes;
1440 out_of_space = False;
1442 for (i=0;(i<maxentries) && !finished && !out_of_space;i++) {
1443 BOOL got_exact_match = False;
1445 /* this is a heuristic to avoid seeking the dirptr except when
1446 absolutely necessary. It allows for a filename of about 40 chars */
1447 if (space_remaining < DIRLEN_GUESS && numentries > 0) {
1448 out_of_space = True;
1451 finished = !get_lanman2_dir_entry(conn,
1453 mask,dirtype,info_level,
1454 requires_resume_key,dont_descend,
1455 &p,pdata,space_remaining, &out_of_space, &got_exact_match,
1459 if (finished && out_of_space)
1462 if (!finished && !out_of_space)
1466 * As an optimisation if we know we aren't looking
1467 * for a wildcard name (ie. the name matches the wildcard exactly)
1468 * then we can finish on any (first) match.
1469 * This speeds up large directory searches. JRA.
1475 space_remaining = max_data_bytes - PTR_DIFF(p,pdata);
1478 /* Check if we can close the dirptr */
1479 if(close_after_first || (finished && close_if_end)) {
1480 DEBUG(5,("call_trans2findfirst - (2) closing dptr_num %d\n", dptr_num));
1481 dptr_close(&dptr_num);
1485 * If there are no matching entries we must return ERRDOS/ERRbadfile -
1486 * from observation of NT.
1489 if(numentries == 0) {
1490 dptr_close(&dptr_num);
1491 return ERROR_DOS(ERRDOS,ERRbadfile);
1494 /* At this point pdata points to numentries directory entries. */
1496 /* Set up the return parameter block */
1497 SSVAL(params,0,dptr_num);
1498 SSVAL(params,2,numentries);
1499 SSVAL(params,4,finished);
1500 SSVAL(params,6,0); /* Never an EA error */
1501 SSVAL(params,8,last_name_off);
1503 send_trans2_replies( outbuf, bufsize, params, 10, pdata, PTR_DIFF(p,pdata));
1505 if ((! *directory) && dptr_path(dptr_num))
1506 slprintf(directory,sizeof(directory)-1, "(%s)",dptr_path(dptr_num));
1508 DEBUG( 4, ( "%s mask=%s directory=%s dirtype=%d numentries=%d\n",
1509 smb_fn_name(CVAL(inbuf,smb_com)),
1510 mask, directory, dirtype, numentries ) );
1513 * Force a name mangle here to ensure that the
1514 * mask as an 8.3 name is top of the mangled cache.
1515 * The reasons for this are subtle. Don't remove
1516 * this code unless you know what you are doing
1517 * (see PR#13758). JRA.
1520 if(!mangle_is_8_3_wildcards( mask, False))
1521 mangle_map(mask, True, True, SNUM(conn));
1526 /****************************************************************************
1527 Reply to a TRANS2_FINDNEXT.
1528 ****************************************************************************/
1530 static int call_trans2findnext(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize,
1531 char **pparams, int total_params, char **ppdata, int total_data)
1533 /* We must be careful here that we don't return more than the
1534 allowed number of data bytes. If this means returning fewer than
1535 maxentries then so be it. We assume that the redirector has
1536 enough room for the fixed number of parameter bytes it has
1538 int max_data_bytes = SVAL(inbuf, smb_mdrcnt);
1539 char *params = *pparams;
1540 char *pdata = *ppdata;
1541 int dptr_num = SVAL(params,0);
1542 int maxentries = SVAL(params,2);
1543 uint16 info_level = SVAL(params,4);
1544 uint32 resume_key = IVAL(params,6);
1545 BOOL close_after_request = BITSETW(params+10,0);
1546 BOOL close_if_end = BITSETW(params+10,1);
1547 BOOL requires_resume_key = BITSETW(params+10,2);
1548 BOOL continue_bit = BITSETW(params+10,3);
1549 pstring resume_name;
1555 int i, last_name_off=0;
1556 BOOL finished = False;
1557 BOOL dont_descend = False;
1558 BOOL out_of_space = False;
1559 int space_remaining;
1560 NTSTATUS ntstatus = NT_STATUS_OK;
1562 if (total_params < 12)
1563 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
1565 *mask = *directory = *resume_name = 0;
1567 srvstr_get_path(inbuf, resume_name, params+12, sizeof(resume_name), -1, STR_TERMINATE, &ntstatus);
1568 if (!NT_STATUS_IS_OK(ntstatus)) {
1569 return ERROR_NT(ntstatus);
1572 DEBUG(3,("call_trans2findnext: dirhandle = %d, max_data_bytes = %d, maxentries = %d, \
1573 close_after_request=%d, close_if_end = %d requires_resume_key = %d \
1574 resume_key = %d resume name = %s continue=%d level = %d\n",
1575 dptr_num, max_data_bytes, maxentries, close_after_request, close_if_end,
1576 requires_resume_key, resume_key, resume_name, continue_bit, info_level));
1578 switch (info_level) {
1579 case SMB_INFO_STANDARD:
1580 case SMB_INFO_QUERY_EA_SIZE:
1581 case SMB_FIND_FILE_DIRECTORY_INFO:
1582 case SMB_FIND_FILE_FULL_DIRECTORY_INFO:
1583 case SMB_FIND_FILE_NAMES_INFO:
1584 case SMB_FIND_FILE_BOTH_DIRECTORY_INFO:
1586 case SMB_FIND_FILE_UNIX:
1587 if (!lp_unix_extensions())
1588 return(ERROR_DOS(ERRDOS,ERRunknownlevel));
1591 return ERROR_DOS(ERRDOS,ERRunknownlevel);
1594 pdata = Realloc( *ppdata, max_data_bytes + 1024);
1596 return ERROR_DOS(ERRDOS,ERRnomem);
1599 memset((char *)pdata,'\0',max_data_bytes + 1024);
1601 /* Realloc the params space */
1602 params = Realloc(*pparams, 6*SIZEOFWORD);
1603 if( params == NULL )
1604 return ERROR_DOS(ERRDOS,ERRnomem);
1608 /* Check that the dptr is valid */
1609 if(!(conn->dirptr = dptr_fetch_lanman2(dptr_num)))
1610 return ERROR_DOS(ERRDOS,ERRnofiles);
1612 string_set(&conn->dirpath,dptr_path(dptr_num));
1614 /* Get the wildcard mask from the dptr */
1615 if((p = dptr_wcard(dptr_num))== NULL) {
1616 DEBUG(2,("dptr_num %d has no wildcard\n", dptr_num));
1617 return ERROR_DOS(ERRDOS,ERRnofiles);
1621 pstrcpy(directory,conn->dirpath);
1623 /* Get the attr mask from the dptr */
1624 dirtype = dptr_attr(dptr_num);
1626 DEBUG(3,("dptr_num is %d, mask = %s, attr = %x, dirptr=(0x%lX,%d)\n",
1627 dptr_num, mask, dirtype,
1629 TellDir(conn->dirptr)));
1631 /* We don't need to check for VOL here as this is returned by
1632 a different TRANS2 call. */
1634 DEBUG(8,("dirpath=<%s> dontdescend=<%s>\n",conn->dirpath,lp_dontdescend(SNUM(conn))));
1635 if (in_list(conn->dirpath,lp_dontdescend(SNUM(conn)),conn->case_sensitive))
1636 dont_descend = True;
1639 space_remaining = max_data_bytes;
1640 out_of_space = False;
1643 * Seek to the correct position. We no longer use the resume key but
1644 * depend on the last file name instead.
1647 if(requires_resume_key && *resume_name && !continue_bit) {
1650 * Fix for NT redirector problem triggered by resume key indexes
1651 * changing between directory scans. We now return a resume key of 0
1652 * and instead look for the filename to continue from (also given
1653 * to us by NT/95/smbfs/smbclient). If no other scans have been done between the
1654 * findfirst/findnext (as is usual) then the directory pointer
1655 * should already be at the correct place. Check this by scanning
1656 * backwards looking for an exact (ie. case sensitive) filename match.
1657 * If we get to the beginning of the directory and haven't found it then scan
1658 * forwards again looking for a match. JRA.
1661 int current_pos, start_pos;
1662 const char *dname = NULL;
1663 pstring dname_pstring;
1664 void *dirptr = conn->dirptr;
1665 start_pos = TellDir(dirptr);
1666 for(current_pos = start_pos; current_pos >= 0; current_pos--) {
1667 DEBUG(7,("call_trans2findnext: seeking to pos %d\n", current_pos));
1669 SeekDir(dirptr, current_pos);
1670 dname = ReadDirName(dirptr);
1673 * Remember, mangle_map is called by
1674 * get_lanman2_dir_entry(), so the resume name
1675 * could be mangled. Ensure we do the same
1679 /* make sure we get a copy that mangle_map can modify */
1681 pstrcpy(dname_pstring, dname);
1682 mangle_map( dname_pstring, False, True, SNUM(conn));
1684 if(strcsequal( resume_name, dname_pstring)) {
1685 SeekDir(dirptr, current_pos+1);
1686 DEBUG(7,("call_trans2findnext: got match at pos %d\n", current_pos+1 ));
1693 * Scan forward from start if not found going backwards.
1696 if(current_pos < 0) {
1697 DEBUG(7,("call_trans2findnext: notfound: seeking to pos %d\n", start_pos));
1698 SeekDir(dirptr, start_pos);
1699 for(current_pos = start_pos; (dname = ReadDirName(dirptr)) != NULL; SeekDir(dirptr,++current_pos)) {
1702 * Remember, mangle_map is called by
1703 * get_lanman2_dir_entry(), so the resume name
1704 * could be mangled. Ensure we do the same
1709 /* make sure we get a copy that mangle_map can modify */
1711 pstrcpy(dname_pstring, dname);
1712 mangle_map(dname_pstring, False, True, SNUM(conn));
1714 if(strcsequal( resume_name, dname_pstring)) {
1715 SeekDir(dirptr, current_pos+1);
1716 DEBUG(7,("call_trans2findnext: got match at pos %d\n", current_pos+1 ));
1721 } /* end if current_pos */
1722 } /* end if requires_resume_key && !continue_bit */
1724 for (i=0;(i<(int)maxentries) && !finished && !out_of_space ;i++) {
1725 BOOL got_exact_match = False;
1727 /* this is a heuristic to avoid seeking the dirptr except when
1728 absolutely necessary. It allows for a filename of about 40 chars */
1729 if (space_remaining < DIRLEN_GUESS && numentries > 0) {
1730 out_of_space = True;
1733 finished = !get_lanman2_dir_entry(conn,
1735 mask,dirtype,info_level,
1736 requires_resume_key,dont_descend,
1737 &p,pdata,space_remaining, &out_of_space, &got_exact_match,
1741 if (finished && out_of_space)
1744 if (!finished && !out_of_space)
1748 * As an optimisation if we know we aren't looking
1749 * for a wildcard name (ie. the name matches the wildcard exactly)
1750 * then we can finish on any (first) match.
1751 * This speeds up large directory searches. JRA.
1757 space_remaining = max_data_bytes - PTR_DIFF(p,pdata);
1760 /* Check if we can close the dirptr */
1761 if(close_after_request || (finished && close_if_end)) {
1762 DEBUG(5,("call_trans2findnext: closing dptr_num = %d\n", dptr_num));
1763 dptr_close(&dptr_num); /* This frees up the saved mask */
1766 /* Set up the return parameter block */
1767 SSVAL(params,0,numentries);
1768 SSVAL(params,2,finished);
1769 SSVAL(params,4,0); /* Never an EA error */
1770 SSVAL(params,6,last_name_off);
1772 send_trans2_replies( outbuf, bufsize, params, 8, pdata, PTR_DIFF(p,pdata));
1774 if ((! *directory) && dptr_path(dptr_num))
1775 slprintf(directory,sizeof(directory)-1, "(%s)",dptr_path(dptr_num));
1777 DEBUG( 3, ( "%s mask=%s directory=%s dirtype=%d numentries=%d\n",
1778 smb_fn_name(CVAL(inbuf,smb_com)),
1779 mask, directory, dirtype, numentries ) );
1784 /****************************************************************************
1785 Reply to a TRANS2_QFSINFO (query filesystem info).
1786 ****************************************************************************/
1788 static int call_trans2qfsinfo(connection_struct *conn, char *inbuf, char *outbuf,
1789 int length, int bufsize,
1790 char **pparams, int total_params, char **ppdata, int total_data)
1792 int max_data_bytes = SVAL(inbuf, smb_mdrcnt);
1793 char *pdata = *ppdata;
1794 char *params = *pparams;
1795 uint16 info_level = SVAL(params,0);
1798 char *vname = volume_label(SNUM(conn));
1799 int snum = SNUM(conn);
1800 char *fstype = lp_fstype(SNUM(conn));
1803 DEBUG(3,("call_trans2qfsinfo: level = %d\n", info_level));
1805 if(SMB_VFS_STAT(conn,".",&st)!=0) {
1806 DEBUG(2,("call_trans2qfsinfo: stat of . failed (%s)\n", strerror(errno)));
1807 return ERROR_DOS(ERRSRV,ERRinvdevice);
1810 pdata = Realloc(*ppdata, max_data_bytes + 1024);
1811 if ( pdata == NULL )
1812 return ERROR_DOS(ERRDOS,ERRnomem);
1815 memset((char *)pdata,'\0',max_data_bytes + 1024);
1817 switch (info_level) {
1818 case SMB_INFO_ALLOCATION:
1820 SMB_BIG_UINT dfree,dsize,bsize,block_size,sectors_per_unit,bytes_per_sector;
1822 SMB_VFS_DISK_FREE(conn,".",False,&bsize,&dfree,&dsize);
1823 block_size = lp_block_size(snum);
1824 if (bsize < block_size) {
1825 SMB_BIG_UINT factor = block_size/bsize;
1830 if (bsize > block_size) {
1831 SMB_BIG_UINT factor = bsize/block_size;
1836 bytes_per_sector = 512;
1837 sectors_per_unit = bsize/bytes_per_sector;
1839 DEBUG(5,("call_trans2qfsinfo : SMB_INFO_ALLOCATION id=%x, bsize=%u, cSectorUnit=%u, \
1840 cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)st.st_dev, (unsigned int)bsize, (unsigned int)sectors_per_unit,
1841 (unsigned int)bytes_per_sector, (unsigned int)dsize, (unsigned int)dfree));
1843 SIVAL(pdata,l1_idFileSystem,st.st_dev);
1844 SIVAL(pdata,l1_cSectorUnit,sectors_per_unit);
1845 SIVAL(pdata,l1_cUnit,dsize);
1846 SIVAL(pdata,l1_cUnitAvail,dfree);
1847 SSVAL(pdata,l1_cbSector,bytes_per_sector);
1851 case SMB_INFO_VOLUME:
1852 /* Return volume name */
1854 * Add volume serial number - hash of a combination of
1855 * the called hostname and the service name.
1857 SIVAL(pdata,0,str_checksum(lp_servicename(snum)) ^ (str_checksum(local_machine)<<16) );
1858 len = srvstr_push(outbuf, pdata+l2_vol_szVolLabel, vname, -1, STR_NOALIGN);
1859 SCVAL(pdata,l2_vol_cch,len);
1860 data_len = l2_vol_szVolLabel + len;
1861 DEBUG(5,("call_trans2qfsinfo : time = %x, namelen = %d, name = %s\n",
1862 (unsigned)st.st_ctime, len, vname));
1865 case SMB_QUERY_FS_ATTRIBUTE_INFO:
1866 case SMB_FS_ATTRIBUTE_INFORMATION:
1869 #if defined(HAVE_SYS_QUOTAS)
1870 quota_flag = FILE_VOLUME_QUOTAS;
1873 SIVAL(pdata,0,FILE_CASE_PRESERVED_NAMES|FILE_CASE_SENSITIVE_SEARCH|
1874 (lp_nt_acl_support(SNUM(conn)) ? FILE_PERSISTENT_ACLS : 0)|
1875 quota_flag); /* FS ATTRIBUTES */
1877 SIVAL(pdata,4,255); /* Max filename component length */
1878 /* NOTE! the fstype must *not* be null terminated or win98 won't recognise it
1879 and will think we can't do long filenames */
1880 len = srvstr_push(outbuf, pdata+12, fstype, -1, STR_UNICODE);
1882 data_len = 12 + len;
1885 case SMB_QUERY_FS_LABEL_INFO:
1886 case SMB_FS_LABEL_INFORMATION:
1887 len = srvstr_push(outbuf, pdata+4, vname, -1, 0);
1892 case SMB_QUERY_FS_VOLUME_INFO:
1893 case SMB_FS_VOLUME_INFORMATION:
1896 * Add volume serial number - hash of a combination of
1897 * the called hostname and the service name.
1899 SIVAL(pdata,8,str_checksum(lp_servicename(snum)) ^
1900 (str_checksum(local_machine)<<16));
1902 len = srvstr_push(outbuf, pdata+18, vname, -1, STR_UNICODE);
1903 SIVAL(pdata,12,len);
1905 DEBUG(5,("call_trans2qfsinfo : SMB_QUERY_FS_VOLUME_INFO namelen = %d, vol=%s serv=%s\n",
1906 (int)strlen(vname),vname, lp_servicename(snum)));
1909 case SMB_QUERY_FS_SIZE_INFO:
1910 case SMB_FS_SIZE_INFORMATION:
1912 SMB_BIG_UINT dfree,dsize,bsize,block_size,sectors_per_unit,bytes_per_sector;
1914 SMB_VFS_DISK_FREE(conn,".",False,&bsize,&dfree,&dsize);
1915 block_size = lp_block_size(snum);
1916 if (bsize < block_size) {
1917 SMB_BIG_UINT factor = block_size/bsize;
1922 if (bsize > block_size) {
1923 SMB_BIG_UINT factor = bsize/block_size;
1928 bytes_per_sector = 512;
1929 sectors_per_unit = bsize/bytes_per_sector;
1930 DEBUG(5,("call_trans2qfsinfo : SMB_QUERY_FS_SIZE_INFO bsize=%u, cSectorUnit=%u, \
1931 cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize, (unsigned int)sectors_per_unit,
1932 (unsigned int)bytes_per_sector, (unsigned int)dsize, (unsigned int)dfree));
1933 SBIG_UINT(pdata,0,dsize);
1934 SBIG_UINT(pdata,8,dfree);
1935 SIVAL(pdata,16,sectors_per_unit);
1936 SIVAL(pdata,20,bytes_per_sector);
1940 case SMB_FS_FULL_SIZE_INFORMATION:
1942 SMB_BIG_UINT dfree,dsize,bsize,block_size,sectors_per_unit,bytes_per_sector;
1944 SMB_VFS_DISK_FREE(conn,".",False,&bsize,&dfree,&dsize);
1945 block_size = lp_block_size(snum);
1946 if (bsize < block_size) {
1947 SMB_BIG_UINT factor = block_size/bsize;
1952 if (bsize > block_size) {
1953 SMB_BIG_UINT factor = bsize/block_size;
1958 bytes_per_sector = 512;
1959 sectors_per_unit = bsize/bytes_per_sector;
1960 DEBUG(5,("call_trans2qfsinfo : SMB_QUERY_FS_FULL_SIZE_INFO bsize=%u, cSectorUnit=%u, \
1961 cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize, (unsigned int)sectors_per_unit,
1962 (unsigned int)bytes_per_sector, (unsigned int)dsize, (unsigned int)dfree));
1963 SBIG_UINT(pdata,0,dsize); /* Total Allocation units. */
1964 SBIG_UINT(pdata,8,dfree); /* Caller available allocation units. */
1965 SBIG_UINT(pdata,16,dfree); /* Actual available allocation units. */
1966 SIVAL(pdata,24,sectors_per_unit); /* Sectors per allocation unit. */
1967 SIVAL(pdata,28,bytes_per_sector); /* Bytes per sector. */
1971 case SMB_QUERY_FS_DEVICE_INFO:
1972 case SMB_FS_DEVICE_INFORMATION:
1974 SIVAL(pdata,0,0); /* dev type */
1975 SIVAL(pdata,4,0); /* characteristics */
1978 #ifdef HAVE_SYS_QUOTAS
1979 case SMB_FS_QUOTA_INFORMATION:
1981 * what we have to send --metze:
1983 * Unknown1: 24 NULL bytes
1984 * Soft Quota Treshold: 8 bytes seems like SMB_BIG_UINT or so
1985 * Hard Quota Limit: 8 bytes seems like SMB_BIG_UINT or so
1986 * Quota Flags: 2 byte :
1987 * Unknown3: 6 NULL bytes
1991 * details for Quota Flags:
1993 * 0x0020 Log Limit: log if the user exceeds his Hard Quota
1994 * 0x0010 Log Warn: log if the user exceeds his Soft Quota
1995 * 0x0002 Deny Disk: deny disk access when the user exceeds his Hard Quota
1996 * 0x0001 Enable Quotas: enable quota for this fs
2000 /* we need to fake up a fsp here,
2001 * because its not send in this call
2004 SMB_NTQUOTA_STRUCT quotas;
2007 ZERO_STRUCT(quotas);
2014 if (current_user.uid != 0) {
2015 DEBUG(0,("set_user_quota: access_denied service [%s] user [%s]\n",
2016 lp_servicename(SNUM(conn)),conn->user));
2017 return ERROR_DOS(ERRDOS,ERRnoaccess);
2020 if (vfs_get_ntquota(&fsp, SMB_USER_FS_QUOTA_TYPE, NULL, "as)!=0) {
2021 DEBUG(0,("vfs_get_ntquota() failed for service [%s]\n",lp_servicename(SNUM(conn))));
2022 return ERROR_DOS(ERRSRV,ERRerror);
2027 DEBUG(10,("SMB_FS_QUOTA_INFORMATION: for service [%s]\n",lp_servicename(SNUM(conn))));
2029 /* Unknown1 24 NULL bytes*/
2030 SBIG_UINT(pdata,0,(SMB_BIG_UINT)0);
2031 SBIG_UINT(pdata,8,(SMB_BIG_UINT)0);
2032 SBIG_UINT(pdata,16,(SMB_BIG_UINT)0);
2034 /* Default Soft Quota 8 bytes */
2035 SBIG_UINT(pdata,24,quotas.softlim);
2037 /* Default Hard Quota 8 bytes */
2038 SBIG_UINT(pdata,32,quotas.hardlim);
2040 /* Quota flag 2 bytes */
2041 SSVAL(pdata,40,quotas.qflags);
2043 /* Unknown3 6 NULL bytes */
2049 #endif /* HAVE_SYS_QUOTAS */
2050 case SMB_FS_OBJECTID_INFORMATION:
2055 * Query the version and capabilities of the CIFS UNIX extensions
2059 case SMB_QUERY_CIFS_UNIX_INFO:
2060 if (!lp_unix_extensions())
2061 return ERROR_DOS(ERRDOS,ERRunknownlevel);
2063 SSVAL(pdata,0,CIFS_UNIX_MAJOR_VERSION);
2064 SSVAL(pdata,2,CIFS_UNIX_MINOR_VERSION);
2065 SBIG_UINT(pdata,4,((SMB_BIG_UINT)0)); /* No capabilities for now... */
2068 case SMB_MAC_QUERY_FS_INFO:
2070 * Thursby MAC extension... ONLY on NTFS filesystems
2071 * once we do streams then we don't need this
2073 if (strequal(lp_fstype(SNUM(conn)),"NTFS")) {
2075 SIVAL(pdata,84,0x100); /* Don't support mac... */
2080 return ERROR_DOS(ERRDOS,ERRunknownlevel);
2084 send_trans2_replies( outbuf, bufsize, params, 0, pdata, data_len);
2086 DEBUG( 4, ( "%s info_level = %d\n", smb_fn_name(CVAL(inbuf,smb_com)), info_level) );
2091 #ifdef HAVE_SYS_QUOTAS
2092 /****************************************************************************
2093 Reply to a TRANS2_SETFSINFO (set filesystem info).
2094 ****************************************************************************/
2096 static int call_trans2setfsinfo(connection_struct *conn,
2097 char *inbuf, char *outbuf, int length, int bufsize,
2098 char **pparams, int total_params, char **ppdata, int total_data)
2100 char *pdata = *ppdata;
2101 char *params = *pparams;
2102 files_struct *fsp = NULL;
2105 SMB_NTQUOTA_STRUCT quotas;
2107 ZERO_STRUCT(quotas);
2109 DEBUG(10,("call_trans2setfsinfo: SET_FS_QUOTA: for service [%s]\n",lp_servicename(SNUM(conn))));
2112 if ((current_user.uid != 0)||!CAN_WRITE(conn)) {
2113 DEBUG(0,("set_user_quota: access_denied service [%s] user [%s]\n",
2114 lp_servicename(SNUM(conn)),conn->user));
2115 return ERROR_DOS(ERRSRV,ERRaccess);
2119 if (total_params < 4) {
2120 DEBUG(0,("call_trans2setfsinfo: requires total_params(%d) >= 4 bytes!\n",
2122 return ERROR_DOS(ERRDOS,ERRinvalidparam);
2125 fsp = file_fsp(params,0);
2127 if (!CHECK_NTQUOTA_HANDLE_OK(fsp,conn)) {
2128 DEBUG(3,("TRANSACT_GET_USER_QUOTA: no valid QUOTA HANDLE\n"));
2129 return ERROR_NT(NT_STATUS_INVALID_HANDLE);
2132 info_level = SVAL(params,2);
2134 switch(info_level) {
2135 case SMB_FS_QUOTA_INFORMATION:
2136 /* note: normaly there're 48 bytes,
2137 * but we didn't use the last 6 bytes for now
2140 if (total_data < 42) {
2141 DEBUG(0,("call_trans2setfsinfo: SET_FS_QUOTA: requires total_data(%d) >= 42 bytes!\n",
2143 return ERROR_DOS(ERRDOS,ERRunknownlevel);
2146 /* unknown_1 24 NULL bytes in pdata*/
2148 /* the soft quotas 8 bytes (SMB_BIG_UINT)*/
2149 quotas.softlim = (SMB_BIG_UINT)IVAL(pdata,24);
2150 #ifdef LARGE_SMB_OFF_T
2151 quotas.softlim |= (((SMB_BIG_UINT)IVAL(pdata,28)) << 32);
2152 #else /* LARGE_SMB_OFF_T */
2153 if ((IVAL(pdata,28) != 0)&&
2154 ((quotas.softlim != 0xFFFFFFFF)||
2155 (IVAL(pdata,28)!=0xFFFFFFFF))) {
2156 /* more than 32 bits? */
2157 return ERROR_DOS(ERRDOS,ERRunknownlevel);
2159 #endif /* LARGE_SMB_OFF_T */
2161 /* the hard quotas 8 bytes (SMB_BIG_UINT)*/
2162 quotas.hardlim = (SMB_BIG_UINT)IVAL(pdata,32);
2163 #ifdef LARGE_SMB_OFF_T
2164 quotas.hardlim |= (((SMB_BIG_UINT)IVAL(pdata,36)) << 32);
2165 #else /* LARGE_SMB_OFF_T */
2166 if ((IVAL(pdata,36) != 0)&&
2167 ((quotas.hardlim != 0xFFFFFFFF)||
2168 (IVAL(pdata,36)!=0xFFFFFFFF))) {
2169 /* more than 32 bits? */
2170 return ERROR_DOS(ERRDOS,ERRunknownlevel);
2172 #endif /* LARGE_SMB_OFF_T */
2174 /* quota_flags 2 bytes **/
2175 quotas.qflags = SVAL(pdata,40);
2177 /* unknown_2 6 NULL bytes follow*/
2179 /* now set the quotas */
2180 if (vfs_set_ntquota(fsp, SMB_USER_FS_QUOTA_TYPE, NULL, "as)!=0) {
2181 DEBUG(0,("vfs_set_ntquota() failed for service [%s]\n",lp_servicename(SNUM(conn))));
2182 return ERROR_DOS(ERRSRV,ERRerror);
2187 DEBUG(3,("call_trans2setfsinfo: unknown level (0x%X) not implemented yet.\n",
2189 return ERROR_DOS(ERRDOS,ERRunknownlevel);
2194 * sending this reply works fine,
2195 * but I'm not sure it's the same
2196 * like windows do...
2199 outsize = set_message(outbuf,10,0,True);
2203 #endif /* HAVE_SYS_QUOTAS */
2205 /****************************************************************************
2206 * Utility function to set bad path error.
2207 ****************************************************************************/
2209 int set_bad_path_error(int err, BOOL bad_path, char *outbuf, int def_class, uint32 def_code)
2211 DEBUG(10,("set_bad_path_error: err = %d bad_path = %d\n",
2212 err, (int)bad_path ));
2216 return ERROR_NT(NT_STATUS_OBJECT_PATH_NOT_FOUND);
2218 return ERROR_NT(NT_STATUS_OBJECT_NAME_NOT_FOUND);
2221 return UNIXERROR(def_class,def_code);
2224 /****************************************************************************
2225 Reply to a TRANS2_QFILEPATHINFO or TRANSACT2_QFILEINFO (query file info by
2226 file name or file id).
2227 ****************************************************************************/
2229 static int call_trans2qfilepathinfo(connection_struct *conn,
2230 char *inbuf, char *outbuf, int length,
2232 char **pparams, int total_params, char **ppdata, int total_data)
2234 int max_data_bytes = SVAL(inbuf, smb_mdrcnt);
2235 char *params = *pparams;
2236 char *pdata = *ppdata;
2237 uint16 tran_call = SVAL(inbuf, smb_setup0);
2240 SMB_OFF_T file_size=0;
2241 SMB_BIG_UINT allocation_size=0;
2242 unsigned int data_size;
2243 unsigned int param_size = 2;
2244 SMB_STRUCT_STAT sbuf;
2245 pstring fname, dos_fname;
2250 BOOL bad_path = False;
2251 BOOL delete_pending = False;
2254 files_struct *fsp = NULL;
2255 uint32 desired_access = 0x12019F; /* Default - GENERIC_EXECUTE mapping from Windows */
2258 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
2260 if (tran_call == TRANSACT2_QFILEINFO) {
2261 if (total_params < 4)
2262 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
2264 fsp = file_fsp(params,0);
2265 info_level = SVAL(params,2);
2267 DEBUG(3,("call_trans2qfilepathinfo: TRANSACT2_QFILEINFO: level = %d\n", info_level));
2269 if(fsp && (fsp->fake_file_handle)) {
2271 * This is actually for the QUOTA_FAKE_FILE --metze
2274 pstrcpy(fname, fsp->fsp_name);
2275 unix_convert(fname,conn,0,&bad_path,&sbuf);
2276 if (!check_name(fname,conn)) {
2277 DEBUG(3,("call_trans2qfilepathinfo: fileinfo of %s failed for fake_file(%s)\n",fname,strerror(errno)));
2278 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRbadpath);
2281 } else if(fsp && (fsp->is_directory || fsp->fd == -1)) {
2283 * This is actually a QFILEINFO on a directory
2284 * handle (returned from an NT SMB). NT5.0 seems
2285 * to do this call. JRA.
2287 pstrcpy(fname, fsp->fsp_name);
2288 unix_convert(fname,conn,0,&bad_path,&sbuf);
2289 if (!check_name(fname,conn)) {
2290 DEBUG(3,("call_trans2qfilepathinfo: fileinfo of %s failed (%s)\n",fname,strerror(errno)));
2291 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRbadpath);
2294 if (INFO_LEVEL_IS_UNIX(info_level)) {
2295 /* Always do lstat for UNIX calls. */
2296 if (SMB_VFS_LSTAT(conn,fname,&sbuf)) {
2297 DEBUG(3,("call_trans2qfilepathinfo: SMB_VFS_LSTAT of %s failed (%s)\n",fname,strerror(errno)));
2298 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRbadpath);
2300 } else if (!VALID_STAT(sbuf) && SMB_VFS_STAT(conn,fname,&sbuf)) {
2301 DEBUG(3,("call_trans2qfilepathinfo: SMB_VFS_STAT of %s failed (%s)\n",fname,strerror(errno)));
2302 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRbadpath);
2305 delete_pending = fsp->is_directory ? fsp->directory_delete_on_close : 0;
2308 * Original code - this is an open file.
2310 CHECK_FSP(fsp,conn);
2312 pstrcpy(fname, fsp->fsp_name);
2313 if (SMB_VFS_FSTAT(fsp,fsp->fd,&sbuf) != 0) {
2314 DEBUG(3,("fstat of fnum %d failed (%s)\n", fsp->fnum, strerror(errno)));
2315 return(UNIXERROR(ERRDOS,ERRbadfid));
2317 pos = fsp->position_information;
2318 delete_pending = fsp->delete_on_close;
2319 desired_access = fsp->desired_access;
2322 NTSTATUS status = NT_STATUS_OK;
2325 if (total_params < 6)
2326 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
2328 info_level = SVAL(params,0);
2330 DEBUG(3,("call_trans2qfilepathinfo: TRANSACT2_QPATHINFO: level = %d\n", info_level));
2332 srvstr_get_path(inbuf, fname, ¶ms[6], sizeof(fname), -1, STR_TERMINATE, &status);
2333 if (!NT_STATUS_IS_OK(status)) {
2334 return ERROR_NT(status);
2337 RESOLVE_DFSPATH(fname, conn, inbuf, outbuf);
2339 unix_convert(fname,conn,0,&bad_path,&sbuf);
2340 if (!check_name(fname,conn)) {
2341 DEBUG(3,("call_trans2qfilepathinfo: fileinfo of %s failed (%s)\n",fname,strerror(errno)));
2342 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRbadpath);
2345 if (INFO_LEVEL_IS_UNIX(info_level)) {
2346 /* Always do lstat for UNIX calls. */
2347 if (SMB_VFS_LSTAT(conn,fname,&sbuf)) {
2348 DEBUG(3,("call_trans2qfilepathinfo: SMB_VFS_LSTAT of %s failed (%s)\n",fname,strerror(errno)));
2349 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRbadpath);
2351 } else if (!VALID_STAT(sbuf) && SMB_VFS_STAT(conn,fname,&sbuf) && (info_level != SMB_INFO_IS_NAME_VALID)) {
2352 DEBUG(3,("call_trans2qfilepathinfo: SMB_VFS_STAT of %s failed (%s)\n",fname,strerror(errno)));
2353 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRbadpath);
2357 if (INFO_LEVEL_IS_UNIX(info_level) && !lp_unix_extensions())
2358 return ERROR_DOS(ERRDOS,ERRunknownlevel);
2360 DEBUG(3,("call_trans2qfilepathinfo %s (fnum = %d) level=%d call=%d total_data=%d\n",
2361 fname,fsp ? fsp->fnum : -1, info_level,tran_call,total_data));
2363 p = strrchr_m(fname,'/');
2369 mode = dos_mode(conn,fname,&sbuf);
2371 mode = FILE_ATTRIBUTE_NORMAL;
2373 fullpathname = fname;
2374 file_size = get_file_size(sbuf);
2375 allocation_size = get_allocation_size(fsp,&sbuf);
2379 params = Realloc(*pparams,2);
2381 return ERROR_DOS(ERRDOS,ERRnomem);
2383 memset((char *)params,'\0',2);
2384 data_size = max_data_bytes + 1024;
2385 pdata = Realloc(*ppdata, data_size);
2386 if ( pdata == NULL )
2387 return ERROR_DOS(ERRDOS,ERRnomem);
2390 if (total_data > 0 && IVAL(pdata,0) == total_data) {
2391 /* uggh, EAs for OS2 */
2392 DEBUG(4,("Rejecting EA request with total_data=%d\n",total_data));
2393 return ERROR_DOS(ERRDOS,ERReasnotsupported);
2396 memset((char *)pdata,'\0',data_size);
2398 c_time = get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(conn)));
2400 if (lp_dos_filetime_resolution(SNUM(conn))) {
2402 sbuf.st_atime &= ~1;
2403 sbuf.st_ctime &= ~1;
2404 sbuf.st_mtime &= ~1;
2407 /* NT expects the name to be in an exact form of the *full*
2408 filename. See the trans2 torture test */
2409 if (strequal(base_name,".")) {
2410 pstrcpy(dos_fname, "\\");
2412 pstr_sprintf(dos_fname, "\\%s", fname);
2413 string_replace(dos_fname, '/', '\\');
2416 switch (info_level) {
2417 case SMB_INFO_STANDARD:
2418 DEBUG(10,("call_trans2qfilepathinfo: SMB_INFO_STANDARD\n"));
2420 put_dos_date2(pdata,l1_fdateCreation,c_time);
2421 put_dos_date2(pdata,l1_fdateLastAccess,sbuf.st_atime);
2422 put_dos_date2(pdata,l1_fdateLastWrite,sbuf.st_mtime); /* write time */
2423 SIVAL(pdata,l1_cbFile,(uint32)file_size);
2424 SIVAL(pdata,l1_cbFileAlloc,(uint32)allocation_size);
2425 SSVAL(pdata,l1_attrFile,mode);
2428 case SMB_INFO_QUERY_EA_SIZE:
2430 unsigned int ea_size = estimate_ea_size(conn, fsp, fname);
2431 DEBUG(10,("call_trans2qfilepathinfo: SMB_INFO_QUERY_EA_SIZE\n"));
2433 put_dos_date2(pdata,l1_fdateCreation,c_time);
2434 put_dos_date2(pdata,l1_fdateLastAccess,sbuf.st_atime);
2435 put_dos_date2(pdata,l1_fdateLastWrite,sbuf.st_mtime); /* write time */
2436 SIVAL(pdata,l1_cbFile,(uint32)file_size);
2437 SIVAL(pdata,l1_cbFileAlloc,(uint32)allocation_size);
2438 SSVAL(pdata,l1_attrFile,mode);
2439 SIVAL(pdata,l1_attrFile+2,ea_size);
2443 case SMB_INFO_IS_NAME_VALID:
2444 DEBUG(10,("call_trans2qfilepathinfo: SMB_INFO_IS_NAME_VALID\n"));
2445 if (tran_call == TRANSACT2_QFILEINFO) {
2446 /* os/2 needs this ? really ?*/
2447 return ERROR_DOS(ERRDOS,ERRbadfunc);
2453 case SMB_INFO_QUERY_EAS_FROM_LIST:
2454 DEBUG(10,("call_trans2qfilepathinfo: SMB_INFO_QUERY_EAS_FROM_LIST\n"));
2456 put_dos_date2(pdata,0,c_time);
2457 put_dos_date2(pdata,4,sbuf.st_atime);
2458 put_dos_date2(pdata,8,sbuf.st_mtime);
2459 SIVAL(pdata,12,(uint32)file_size);
2460 SIVAL(pdata,16,(uint32)allocation_size);
2461 SIVAL(pdata,20,mode);
2464 case SMB_INFO_QUERY_ALL_EAS:
2465 DEBUG(10,("call_trans2qfilepathinfo: SMB_INFO_QUERY_ALL_EAS\n"));
2466 /* We have data_size bytes to put EA's into. */
2467 data_size = fill_ea_buffer(pdata, data_size, conn, fsp, fname);
2470 case SMB_FILE_BASIC_INFORMATION:
2471 case SMB_QUERY_FILE_BASIC_INFO:
2473 if (info_level == SMB_QUERY_FILE_BASIC_INFO) {
2474 DEBUG(10,("call_trans2qfilepathinfo: SMB_QUERY_FILE_BASIC_INFO\n"));
2475 data_size = 36; /* w95 returns 40 bytes not 36 - why ?. */
2477 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_BASIC_INFORMATION\n"));
2481 put_long_date(pdata,c_time);
2482 put_long_date(pdata+8,sbuf.st_atime);
2483 put_long_date(pdata+16,sbuf.st_mtime); /* write time */
2484 put_long_date(pdata+24,sbuf.st_mtime); /* change time */
2485 SIVAL(pdata,32,mode);
2487 DEBUG(5,("SMB_QFBI - "));
2489 time_t create_time = c_time;
2490 DEBUG(5,("create: %s ", ctime(&create_time)));
2492 DEBUG(5,("access: %s ", ctime(&sbuf.st_atime)));
2493 DEBUG(5,("write: %s ", ctime(&sbuf.st_mtime)));
2494 DEBUG(5,("change: %s ", ctime(&sbuf.st_mtime)));
2495 DEBUG(5,("mode: %x\n", mode));
2499 case SMB_FILE_STANDARD_INFORMATION:
2500 case SMB_QUERY_FILE_STANDARD_INFO:
2502 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_STANDARD_INFORMATION\n"));
2504 SOFF_T(pdata,0,allocation_size);
2505 SOFF_T(pdata,8,file_size);
2506 if (delete_pending & sbuf.st_nlink)
2507 SIVAL(pdata,16,sbuf.st_nlink - 1);
2509 SIVAL(pdata,16,sbuf.st_nlink);
2511 SCVAL(pdata,21,(mode&aDIR)?1:0);
2514 case SMB_FILE_EA_INFORMATION:
2515 case SMB_QUERY_FILE_EA_INFO:
2517 unsigned int ea_size = estimate_ea_size(conn, fsp, fname);
2518 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_EA_INFORMATION\n"));
2520 SIVAL(pdata,0,ea_size);
2524 /* Get the 8.3 name - used if NT SMB was negotiated. */
2525 case SMB_QUERY_FILE_ALT_NAME_INFO:
2526 case SMB_FILE_ALTERNATE_NAME_INFORMATION:
2530 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_ALTERNATE_NAME_INFORMATION\n"));
2531 pstrcpy(short_name,base_name);
2532 /* Mangle if not already 8.3 */
2533 if(!mangle_is_8_3(short_name, True)) {
2534 mangle_map(short_name,True,True,SNUM(conn));
2536 len = srvstr_push(outbuf, pdata+4, short_name, -1, STR_UNICODE);
2537 data_size = 4 + len;
2542 case SMB_QUERY_FILE_NAME_INFO:
2544 this must be *exactly* right for ACLs on mapped drives to work
2546 len = srvstr_push(outbuf, pdata+4, dos_fname, -1, STR_UNICODE);
2547 DEBUG(10,("call_trans2qfilepathinfo: SMB_QUERY_FILE_NAME_INFO\n"));
2548 data_size = 4 + len;
2552 case SMB_FILE_ALLOCATION_INFORMATION:
2553 case SMB_QUERY_FILE_ALLOCATION_INFO:
2554 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_ALLOCATION_INFORMATION\n"));
2556 SOFF_T(pdata,0,allocation_size);
2559 case SMB_FILE_END_OF_FILE_INFORMATION:
2560 case SMB_QUERY_FILE_END_OF_FILEINFO:
2561 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_END_OF_FILE_INFORMATION\n"));
2563 SOFF_T(pdata,0,file_size);
2566 case SMB_QUERY_FILE_ALL_INFO:
2567 case SMB_FILE_ALL_INFORMATION:
2569 unsigned int ea_size = estimate_ea_size(conn, fsp, fname);
2570 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_ALL_INFORMATION\n"));
2571 put_long_date(pdata,c_time);
2572 put_long_date(pdata+8,sbuf.st_atime);
2573 put_long_date(pdata+16,sbuf.st_mtime); /* write time */
2574 put_long_date(pdata+24,sbuf.st_mtime); /* change time */
2575 SIVAL(pdata,32,mode);
2577 SOFF_T(pdata,0,allocation_size);
2578 SOFF_T(pdata,8,file_size);
2579 if (delete_pending && sbuf.st_nlink)
2580 SIVAL(pdata,16,sbuf.st_nlink - 1);
2582 SIVAL(pdata,16,sbuf.st_nlink);
2583 SCVAL(pdata,20,delete_pending);
2584 SCVAL(pdata,21,(mode&aDIR)?1:0);
2586 SIVAL(pdata,0,ea_size);
2587 pdata += 4; /* EA info */
2588 len = srvstr_push(outbuf, pdata+4, dos_fname, -1, STR_UNICODE);
2591 data_size = PTR_DIFF(pdata,(*ppdata));
2594 case SMB_FILE_INTERNAL_INFORMATION:
2595 /* This should be an index number - looks like
2598 I think this causes us to fail the IFSKIT
2599 BasicFileInformationTest. -tpot */
2601 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_INTERNAL_INFORMATION\n"));
2602 SIVAL(pdata,0,sbuf.st_dev);
2603 SIVAL(pdata,4,sbuf.st_ino);
2607 case SMB_FILE_ACCESS_INFORMATION:
2608 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_ACCESS_INFORMATION\n"));
2609 SIVAL(pdata,0,desired_access);
2613 case SMB_FILE_NAME_INFORMATION:
2614 /* Pathname with leading '\'. */
2617 byte_len = dos_PutUniCode(pdata+4,dos_fname,max_data_bytes,False);
2618 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_NAME_INFORMATION\n"));
2619 SIVAL(pdata,0,byte_len);
2620 data_size = 4 + byte_len;
2624 case SMB_FILE_DISPOSITION_INFORMATION:
2625 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_DISPOSITION_INFORMATION\n"));
2627 SCVAL(pdata,0,delete_pending);
2630 case SMB_FILE_POSITION_INFORMATION:
2631 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_POSITION_INFORMATION\n"));
2633 SOFF_T(pdata,0,pos);
2636 case SMB_FILE_MODE_INFORMATION:
2637 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_MODE_INFORMATION\n"));
2638 SIVAL(pdata,0,mode);
2642 case SMB_FILE_ALIGNMENT_INFORMATION:
2643 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_ALIGNMENT_INFORMATION\n"));
2644 SIVAL(pdata,0,0); /* No alignment needed. */
2650 * NT4 server just returns "invalid query" to this - if we try to answer
2651 * it then NTws gets a BSOD! (tridge).
2652 * W2K seems to want this. JRA.
2654 case SMB_QUERY_FILE_STREAM_INFO:
2656 case SMB_FILE_STREAM_INFORMATION:
2657 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_STREAM_INFORMATION\n"));
2661 size_t byte_len = dos_PutUniCode(pdata+24,"::$DATA", 0xE, False);
2662 SIVAL(pdata,0,0); /* ??? */
2663 SIVAL(pdata,4,byte_len); /* Byte length of unicode string ::$DATA */
2664 SOFF_T(pdata,8,file_size);
2665 SIVAL(pdata,16,allocation_size);
2666 SIVAL(pdata,20,0); /* ??? */
2667 data_size = 24 + byte_len;
2671 case SMB_QUERY_COMPRESSION_INFO:
2672 case SMB_FILE_COMPRESSION_INFORMATION:
2673 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_COMPRESSION_INFORMATION\n"));
2674 SOFF_T(pdata,0,file_size);
2675 SIVAL(pdata,8,0); /* ??? */
2676 SIVAL(pdata,12,0); /* ??? */
2680 case SMB_FILE_NETWORK_OPEN_INFORMATION:
2681 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_NETWORK_OPEN_INFORMATION\n"));
2682 put_long_date(pdata,c_time);
2683 put_long_date(pdata+8,sbuf.st_atime);
2684 put_long_date(pdata+16,sbuf.st_mtime); /* write time */
2685 put_long_date(pdata+24,sbuf.st_mtime); /* change time */
2686 SIVAL(pdata,32,allocation_size);
2687 SOFF_T(pdata,40,file_size);
2688 SIVAL(pdata,48,mode);
2689 SIVAL(pdata,52,0); /* ??? */
2693 case SMB_FILE_ATTRIBUTE_TAG_INFORMATION:
2694 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_ATTRIBUTE_TAG_INFORMATION\n"));
2695 SIVAL(pdata,0,mode);
2701 * CIFS UNIX Extensions.
2704 case SMB_QUERY_FILE_UNIX_BASIC:
2706 DEBUG(10,("call_trans2qfilepathinfo: SMB_QUERY_FILE_UNIX_BASIC\n"));
2707 DEBUG(4,("call_trans2qfilepathinfo: st_mode=%o\n",(int)sbuf.st_mode));
2709 SOFF_T(pdata,0,get_file_size(sbuf)); /* File size 64 Bit */
2712 SOFF_T(pdata,0,get_allocation_size(fsp,&sbuf)); /* Number of bytes used on disk - 64 Bit */
2715 put_long_date(pdata,sbuf.st_ctime); /* Creation Time 64 Bit */
2716 put_long_date(pdata+8,sbuf.st_atime); /* Last access time 64 Bit */
2717 put_long_date(pdata+16,sbuf.st_mtime); /* Last modification time 64 Bit */
2720 SIVAL(pdata,0,sbuf.st_uid); /* user id for the owner */
2724 SIVAL(pdata,0,sbuf.st_gid); /* group id of owner */
2728 SIVAL(pdata,0,unix_filetype(sbuf.st_mode));
2731 SIVAL(pdata,0,unix_dev_major(sbuf.st_rdev)); /* Major device number if type is device */
2735 SIVAL(pdata,0,unix_dev_minor(sbuf.st_rdev)); /* Minor device number if type is device */
2739 SINO_T(pdata,0,(SMB_INO_T)sbuf.st_ino); /* inode number */
2742 SIVAL(pdata,0, unix_perms_to_wire(sbuf.st_mode)); /* Standard UNIX file permissions */
2746 SIVAL(pdata,0,sbuf.st_nlink); /* number of hard links */
2749 data_size = PTR_DIFF(pdata,(*ppdata));
2753 DEBUG(4,("call_trans2qfilepathinfo: SMB_QUERY_FILE_UNIX_BASIC"));
2755 for (i=0; i<100; i++)
2756 DEBUG(4,("%d=%x, ",i, (*ppdata)[i]));
2762 case SMB_QUERY_FILE_UNIX_LINK:
2766 DEBUG(10,("call_trans2qfilepathinfo: SMB_QUERY_FILE_UNIX_LINK\n"));
2768 if(!S_ISLNK(sbuf.st_mode))
2769 return(UNIXERROR(ERRSRV,ERRbadlink));
2771 return(UNIXERROR(ERRDOS,ERRbadlink));
2773 len = SMB_VFS_READLINK(conn,fullpathname, buffer, sizeof(pstring)-1); /* read link */
2775 return(UNIXERROR(ERRDOS,ERRnoaccess));
2777 len = srvstr_push(outbuf, pdata, buffer, -1, STR_TERMINATE);
2779 data_size = PTR_DIFF(pdata,(*ppdata));
2785 return ERROR_DOS(ERRDOS,ERRunknownlevel);
2788 send_trans2_replies(outbuf, bufsize, params, param_size, *ppdata, data_size);
2793 /****************************************************************************
2794 Deal with the internal needs of setting the delete on close flag. Note that
2795 as the tdb locking is recursive, it is safe to call this from within
2796 open_file_shared. JRA.
2797 ****************************************************************************/
2799 NTSTATUS set_delete_on_close_internal(files_struct *fsp, BOOL delete_on_close)
2802 * Only allow delete on close for writable shares.
2805 if (delete_on_close && !CAN_WRITE(fsp->conn)) {
2806 DEBUG(10,("set_delete_on_close_internal: file %s delete on close flag set but write access denied on share.\n",
2808 return NT_STATUS_ACCESS_DENIED;
2811 * Only allow delete on close for files/directories opened with delete intent.
2814 if (delete_on_close && !(fsp->desired_access & DELETE_ACCESS)) {
2815 DEBUG(10,("set_delete_on_close_internal: file %s delete on close flag set but delete access denied.\n",
2817 return NT_STATUS_ACCESS_DENIED;
2820 if(fsp->is_directory) {
2821 fsp->directory_delete_on_close = delete_on_close;
2822 DEBUG(10, ("set_delete_on_close_internal: %s delete on close flag for fnum = %d, directory %s\n",
2823 delete_on_close ? "Added" : "Removed", fsp->fnum, fsp->fsp_name ));
2825 fsp->delete_on_close = delete_on_close;
2826 DEBUG(10, ("set_delete_on_close_internal: %s delete on close flag for fnum = %d, file %s\n",
2827 delete_on_close ? "Added" : "Removed", fsp->fnum, fsp->fsp_name ));
2830 return NT_STATUS_OK;
2833 /****************************************************************************
2834 Sets the delete on close flag over all share modes on this file.
2835 Modify the share mode entry for all files open
2836 on this device and inode to tell other smbds we have
2837 changed the delete on close flag. This will be noticed
2838 in the close code, the last closer will delete the file
2840 ****************************************************************************/
2842 NTSTATUS set_delete_on_close_over_all(files_struct *fsp, BOOL delete_on_close)
2844 DEBUG(10,("set_delete_on_close_over_all: %s delete on close flag for fnum = %d, file %s\n",
2845 delete_on_close ? "Adding" : "Removing", fsp->fnum, fsp->fsp_name ));
2847 if (fsp->is_directory || fsp->is_stat)
2848 return NT_STATUS_OK;
2850 if (lock_share_entry_fsp(fsp) == False)
2851 return NT_STATUS_ACCESS_DENIED;
2853 if (!modify_delete_flag(fsp->dev, fsp->inode, delete_on_close)) {
2854 DEBUG(0,("set_delete_on_close_internal: failed to change delete on close flag for file %s\n",
2856 unlock_share_entry_fsp(fsp);
2857 return NT_STATUS_ACCESS_DENIED;
2860 unlock_share_entry_fsp(fsp);
2861 return NT_STATUS_OK;
2864 /****************************************************************************
2865 Set a hard link (called by UNIX extensions and by NT rename with HARD link
2867 ****************************************************************************/
2869 NTSTATUS hardlink_internals(connection_struct *conn, char *oldname, char *newname)
2871 BOOL bad_path_oldname = False;
2872 BOOL bad_path_newname = False;
2873 SMB_STRUCT_STAT sbuf1, sbuf2;
2875 pstring last_component_oldname;
2876 pstring last_component_newname;
2877 NTSTATUS status = NT_STATUS_OK;
2883 if (ms_has_wild(newname) || ms_has_wild(oldname)) {
2884 return NT_STATUS_OBJECT_PATH_SYNTAX_BAD;
2887 rc = unix_convert(oldname,conn,last_component_oldname,&bad_path_oldname,&sbuf1);
2888 if (!rc && bad_path_oldname) {
2889 return NT_STATUS_OBJECT_PATH_NOT_FOUND;
2892 /* Quick check for "." and ".." */
2893 if (last_component_oldname[0] == '.') {
2894 if (!last_component_oldname[1] || (last_component_oldname[1] == '.' && !last_component_oldname[2])) {
2895 return NT_STATUS_OBJECT_NAME_INVALID;
2899 /* source must already exist. */
2900 if (!VALID_STAT(sbuf1)) {
2901 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2904 if (!check_name(oldname,conn)) {
2905 return NT_STATUS_ACCESS_DENIED;
2908 rcdest = unix_convert(newname,conn,last_component_newname,&bad_path_newname,&sbuf2);
2909 if (!rcdest && bad_path_newname) {
2910 return NT_STATUS_OBJECT_PATH_NOT_FOUND;
2913 /* Quick check for "." and ".." */
2914 if (last_component_newname[0] == '.') {
2915 if (!last_component_newname[1] || (last_component_newname[1] == '.' && !last_component_newname[2])) {
2916 return NT_STATUS_OBJECT_NAME_INVALID;
2920 /* Disallow if newname already exists. */
2921 if (VALID_STAT(sbuf2)) {
2922 return NT_STATUS_OBJECT_NAME_COLLISION;
2925 if (!check_name(newname,conn)) {
2926 return NT_STATUS_ACCESS_DENIED;
2929 /* No links from a directory. */
2930 if (S_ISDIR(sbuf1.st_mode)) {
2931 return NT_STATUS_FILE_IS_A_DIRECTORY;
2934 /* Ensure this is within the share. */
2935 if (!reduce_name(conn, oldname) != 0)
2936 return NT_STATUS_ACCESS_DENIED;
2938 DEBUG(10,("hardlink_internals: doing hard link %s -> %s\n", newname, oldname ));
2940 if (SMB_VFS_LINK(conn,oldname,newname) != 0) {
2941 status = map_nt_error_from_unix(errno);
2942 DEBUG(3,("hardlink_internals: Error %s hard link %s -> %s\n",
2943 nt_errstr(status), newname, oldname));
2949 /****************************************************************************
2950 Reply to a TRANS2_SETFILEINFO (set file info by fileid).
2951 ****************************************************************************/
2953 static int call_trans2setfilepathinfo(connection_struct *conn,
2954 char *inbuf, char *outbuf, int length, int bufsize,
2955 char **pparams, int total_params, char **ppdata, int total_data)
2957 char *params = *pparams;
2958 char *pdata = *ppdata;
2959 uint16 tran_call = SVAL(inbuf, smb_setup0);
2964 SMB_STRUCT_STAT sbuf;
2967 BOOL bad_path = False;
2968 files_struct *fsp = NULL;
2969 uid_t set_owner = (uid_t)SMB_UID_NO_CHANGE;
2970 gid_t set_grp = (uid_t)SMB_GID_NO_CHANGE;
2971 mode_t unixmode = 0;
2972 NTSTATUS status = NT_STATUS_OK;
2975 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
2977 if (tran_call == TRANSACT2_SETFILEINFO) {
2978 if (total_params < 4)
2979 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
2981 fsp = file_fsp(params,0);
2982 info_level = SVAL(params,2);
2984 if(fsp && (fsp->is_directory || fsp->fd == -1)) {
2986 * This is actually a SETFILEINFO on a directory
2987 * handle (returned from an NT SMB). NT5.0 seems
2988 * to do this call. JRA.
2990 pstrcpy(fname, fsp->fsp_name);
2991 unix_convert(fname,conn,0,&bad_path,&sbuf);
2992 if (!check_name(fname,conn) || (!VALID_STAT(sbuf))) {
2993 DEBUG(3,("call_trans2setfilepathinfo: fileinfo of %s failed (%s)\n",fname,strerror(errno)));
2994 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRbadpath);
2996 } else if (fsp && fsp->print_file) {
2998 * Doing a DELETE_ON_CLOSE should cancel a print job.
3000 if ((info_level == SMB_SET_FILE_DISPOSITION_INFO) && CVAL(pdata,0)) {
3001 fsp->share_mode = FILE_DELETE_ON_CLOSE;
3003 DEBUG(3,("call_trans2setfilepathinfo: Cancelling print job (%s)\n", fsp->fsp_name ));
3006 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
3009 return (UNIXERROR(ERRDOS,ERRbadpath));
3012 * Original code - this is an open file.
3014 CHECK_FSP(fsp,conn);
3016 pstrcpy(fname, fsp->fsp_name);
3019 if (SMB_VFS_FSTAT(fsp,fd,&sbuf) != 0) {
3020 DEBUG(3,("call_trans2setfilepathinfo: fstat of fnum %d failed (%s)\n",fsp->fnum, strerror(errno)));
3021 return(UNIXERROR(ERRDOS,ERRbadfid));
3026 if (total_params < 6)
3027 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
3029 info_level = SVAL(params,0);
3030 srvstr_get_path(inbuf, fname, ¶ms[6], sizeof(fname), -1, STR_TERMINATE, &status);
3031 if (!NT_STATUS_IS_OK(status)) {
3032 return ERROR_NT(status);
3034 unix_convert(fname,conn,0,&bad_path,&sbuf);
3037 * For CIFS UNIX extensions the target name may not exist.
3040 if(!VALID_STAT(sbuf) && !INFO_LEVEL_IS_UNIX(info_level)) {
3041 DEBUG(3,("call_trans2setfilepathinfo: stat of %s failed (%s)\n", fname, strerror(errno)));
3042 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRbadpath);
3045 if(!check_name(fname, conn)) {
3046 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRbadpath);
3051 if (!CAN_WRITE(conn))
3052 return ERROR_DOS(ERRSRV,ERRaccess);
3054 if (INFO_LEVEL_IS_UNIX(info_level) && !lp_unix_extensions())
3055 return ERROR_DOS(ERRDOS,ERRunknownlevel);
3057 if (VALID_STAT(sbuf))
3058 unixmode = sbuf.st_mode;
3060 DEBUG(3,("call_trans2setfilepathinfo(%d) %s (fnum %d) info_level=%d totdata=%d\n",
3061 tran_call,fname, fsp ? fsp->fnum : -1, info_level,total_data));
3063 /* Realloc the parameter and data sizes */
3064 params = Realloc(*pparams,2);
3066 return ERROR_DOS(ERRDOS,ERRnomem);
3072 /* the pending modtime overrides the current modtime */
3073 sbuf.st_mtime = fsp->pending_modtime;
3076 size = get_file_size(sbuf);
3077 tvs.modtime = sbuf.st_mtime;
3078 tvs.actime = sbuf.st_atime;
3079 dosmode = dos_mode(conn,fname,&sbuf);
3080 unixmode = sbuf.st_mode;
3082 set_owner = VALID_STAT(sbuf) ? sbuf.st_uid : (uid_t)SMB_UID_NO_CHANGE;
3083 set_grp = VALID_STAT(sbuf) ? sbuf.st_gid : (gid_t)SMB_GID_NO_CHANGE;
3085 switch (info_level) {
3086 case SMB_INFO_STANDARD:
3088 if (total_data < 12)
3089 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
3092 tvs.actime = make_unix_date2(pdata+l1_fdateLastAccess);
3094 tvs.modtime = make_unix_date2(pdata+l1_fdateLastWrite);
3098 case SMB_INFO_SET_EA:
3099 status = set_ea(conn, fsp, fname, pdata, total_data);
3100 if (NT_STATUS_V(status) != NT_STATUS_V(NT_STATUS_OK))
3101 return ERROR_NT(status);
3104 /* XXXX um, i don't think this is right.
3105 it's also not in the cifs6.txt spec.
3107 case SMB_INFO_QUERY_EAS_FROM_LIST:
3108 if (total_data < 28)
3109 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
3111 tvs.actime = make_unix_date2(pdata+8);
3112 tvs.modtime = make_unix_date2(pdata+12);
3113 size = IVAL(pdata,16);
3114 dosmode = IVAL(pdata,24);
3117 /* XXXX nor this. not in cifs6.txt, either. */
3118 case SMB_INFO_QUERY_ALL_EAS:
3119 if (total_data < 28)
3120 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
3122 tvs.actime = make_unix_date2(pdata+8);
3123 tvs.modtime = make_unix_date2(pdata+12);
3124 size = IVAL(pdata,16);
3125 dosmode = IVAL(pdata,24);
3128 case SMB_SET_FILE_BASIC_INFO:
3129 case SMB_FILE_BASIC_INFORMATION:
3131 /* Patch to do this correctly from Paul Eggert <eggert@twinsun.com>. */
3133 time_t changed_time;
3135 if (total_data < 36)
3136 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
3138 /* Ignore create time at offset pdata. */
3141 tvs.actime = interpret_long_date(pdata+8);
3143 write_time = interpret_long_date(pdata+16);
3144 changed_time = interpret_long_date(pdata+24);
3146 tvs.modtime = MIN(write_time, changed_time);
3148 if (write_time > tvs.modtime && write_time != 0xffffffff) {
3149 tvs.modtime = write_time;
3151 /* Prefer a defined time to an undefined one. */
3152 if (tvs.modtime == (time_t)0 || tvs.modtime == (time_t)-1)
3153 tvs.modtime = (write_time == (time_t)0 || write_time == (time_t)-1
3154 ? changed_time : write_time);
3157 dosmode = IVAL(pdata,32);
3161 case SMB_FILE_ALLOCATION_INFORMATION:
3162 case SMB_SET_FILE_ALLOCATION_INFO:
3165 SMB_BIG_UINT allocation_size;
3168 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
3170 allocation_size = (SMB_BIG_UINT)IVAL(pdata,0);
3171 #ifdef LARGE_SMB_OFF_T
3172 allocation_size |= (((SMB_BIG_UINT)IVAL(pdata,4)) << 32);
3173 #else /* LARGE_SMB_OFF_T */
3174 if (IVAL(pdata,4) != 0) /* more than 32 bits? */
3175 return ERROR_DOS(ERRDOS,ERRunknownlevel);
3176 #endif /* LARGE_SMB_OFF_T */
3177 DEBUG(10,("call_trans2setfilepathinfo: Set file allocation info for file %s to %.0f\n",
3178 fname, (double)allocation_size ));
3180 if (allocation_size)
3181 allocation_size = SMB_ROUNDUP(allocation_size,SMB_ROUNDUP_ALLOCATION_SIZE);
3183 if(allocation_size != get_file_size(sbuf)) {
3184 SMB_STRUCT_STAT new_sbuf;
3186 DEBUG(10,("call_trans2setfilepathinfo: file %s : setting new allocation size to %.0f\n",
3187 fname, (double)allocation_size ));
3190 files_struct *new_fsp = NULL;
3191 int access_mode = 0;
3194 if(global_oplock_break) {
3195 /* Queue this file modify as we are the process of an oplock break. */
3197 DEBUG(2,("call_trans2setfilepathinfo: queueing message due to being "));
3198 DEBUGADD(2,( "in oplock break state.\n"));
3200 push_oplock_pending_smb_message(inbuf, length);
3204 new_fsp = open_file_shared1(conn, fname, &sbuf,FILE_WRITE_DATA,
3205 SET_OPEN_MODE(DOS_OPEN_RDWR),
3206 (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN),
3207 FILE_ATTRIBUTE_NORMAL,
3208 0, &access_mode, &action);
3210 if (new_fsp == NULL)
3211 return(UNIXERROR(ERRDOS,ERRbadpath));
3212 ret = vfs_allocate_file_space(new_fsp, allocation_size);
3213 if (SMB_VFS_FSTAT(new_fsp,new_fsp->fd,&new_sbuf) != 0) {
3214 DEBUG(3,("call_trans2setfilepathinfo: fstat of fnum %d failed (%s)\n",
3215 new_fsp->fnum, strerror(errno)));
3218 close_file(new_fsp,True);
3220 ret = vfs_allocate_file_space(fsp, allocation_size);
3221 if (SMB_VFS_FSTAT(fsp,fd,&new_sbuf) != 0) {
3222 DEBUG(3,("call_trans2setfilepathinfo: fstat of fnum %d failed (%s)\n",
3223 fsp->fnum, strerror(errno)));
3228 return ERROR_NT(NT_STATUS_DISK_FULL);
3230 /* Allocate can truncate size... */
3231 size = get_file_size(new_sbuf);
3237 case SMB_FILE_END_OF_FILE_INFORMATION:
3238 case SMB_SET_FILE_END_OF_FILE_INFO:
3241 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
3243 size = IVAL(pdata,0);
3244 #ifdef LARGE_SMB_OFF_T
3245 size |= (((SMB_OFF_T)IVAL(pdata,4)) << 32);
3246 #else /* LARGE_SMB_OFF_T */
3247 if (IVAL(pdata,4) != 0) /* more than 32 bits? */
3248 return ERROR_DOS(ERRDOS,ERRunknownlevel);
3249 #endif /* LARGE_SMB_OFF_T */
3250 DEBUG(10,("call_trans2setfilepathinfo: Set end of file info for file %s to %.0f\n", fname, (double)size ));
3254 case SMB_FILE_DISPOSITION_INFORMATION:
3255 case SMB_SET_FILE_DISPOSITION_INFO: /* Set delete on close for open file. */
3257 BOOL delete_on_close;
3260 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
3262 delete_on_close = (CVAL(pdata,0) ? True : False);
3264 /* Just ignore this set on a path. */
3265 if (tran_call != TRANSACT2_SETFILEINFO)
3269 return(UNIXERROR(ERRDOS,ERRbadfid));
3271 status = set_delete_on_close_internal(fsp, delete_on_close);
3273 if (NT_STATUS_V(status) != NT_STATUS_V(NT_STATUS_OK))
3274 return ERROR_NT(status);
3276 /* The set is across all open files on this dev/inode pair. */
3277 status =set_delete_on_close_over_all(fsp, delete_on_close);
3278 if (NT_STATUS_V(status) != NT_STATUS_V(NT_STATUS_OK))
3279 return ERROR_NT(status);
3284 case SMB_FILE_POSITION_INFORMATION:
3286 SMB_BIG_UINT position_information;
3289 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
3291 position_information = (SMB_BIG_UINT)IVAL(pdata,0);
3292 #ifdef LARGE_SMB_OFF_T
3293 position_information |= (((SMB_BIG_UINT)IVAL(pdata,4)) << 32);
3294 #else /* LARGE_SMB_OFF_T */
3295 if (IVAL(pdata,4) != 0) /* more than 32 bits? */
3296 return ERROR_DOS(ERRDOS,ERRunknownlevel);
3297 #endif /* LARGE_SMB_OFF_T */
3298 DEBUG(10,("call_trans2setfilepathinfo: Set file position information for file %s to %.0f\n",
3299 fname, (double)position_information ));
3301 fsp->position_information = position_information;
3306 * CIFS UNIX extensions.
3309 case SMB_SET_FILE_UNIX_BASIC:
3311 uint32 raw_unixmode;
3313 if (total_data < 100)
3314 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
3316 if(IVAL(pdata, 0) != SMB_SIZE_NO_CHANGE_LO &&
3317 IVAL(pdata, 4) != SMB_SIZE_NO_CHANGE_HI) {
3318 size=IVAL(pdata,0); /* first 8 Bytes are size */
3319 #ifdef LARGE_SMB_OFF_T
3320 size |= (((SMB_OFF_T)IVAL(pdata,4)) << 32);
3321 #else /* LARGE_SMB_OFF_T */
3322 if (IVAL(pdata,4) != 0) /* more than 32 bits? */
3323 return ERROR_DOS(ERRDOS,ERRunknownlevel);
3324 #endif /* LARGE_SMB_OFF_T */
3326 pdata+=24; /* ctime & st_blocks are not changed */
3327 tvs.actime = interpret_long_unix_date(pdata); /* access_time */
3328 tvs.modtime = interpret_long_unix_date(pdata+8); /* modification_time */
3330 set_owner = (uid_t)IVAL(pdata,0);
3332 set_grp = (gid_t)IVAL(pdata,0);
3334 raw_unixmode = IVAL(pdata,28);
3335 unixmode = unix_perms_from_wire(conn, &sbuf, raw_unixmode);
3336 dosmode = 0; /* Ensure dos mode change doesn't override this. */
3338 DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_BASIC: name = %s \
3339 size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n",
3340 fname, (double)size, (unsigned int)set_owner, (unsigned int)set_grp, (int)raw_unixmode));
3342 if (!VALID_STAT(sbuf)) {
3345 * The only valid use of this is to create character and block
3346 * devices, and named pipes. This is deprecated (IMHO) and
3347 * a new info level should be used for mknod. JRA.
3350 #if !defined(HAVE_MAKEDEV_FN)
3351 return(ERROR_DOS(ERRDOS,ERRnoaccess));
3352 #else /* HAVE_MAKEDEV_FN */
3353 uint32 file_type = IVAL(pdata,0);
3354 uint32 dev_major = IVAL(pdata,4);
3355 uint32 dev_minor = IVAL(pdata,12);
3357 uid_t myuid = geteuid();
3358 gid_t mygid = getegid();
3361 if (tran_call == TRANSACT2_SETFILEINFO)
3362 return(ERROR_DOS(ERRDOS,ERRnoaccess));
3364 if (raw_unixmode == SMB_MODE_NO_CHANGE)
3365 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
3367 dev = makedev(dev_major, dev_minor);
3369 /* We can only create as the owner/group we are. */
3371 if ((set_owner != myuid) && (set_owner != (uid_t)SMB_UID_NO_CHANGE))
3372 return(ERROR_DOS(ERRDOS,ERRnoaccess));
3373 if ((set_grp != mygid) && (set_grp != (gid_t)SMB_GID_NO_CHANGE))
3374 return(ERROR_DOS(ERRDOS,ERRnoaccess));
3376 if (file_type != UNIX_TYPE_CHARDEV && file_type != UNIX_TYPE_BLKDEV &&
3377 file_type != UNIX_TYPE_FIFO &&
3378 file_type != UNIX_TYPE_SOCKET)
3379 return(ERROR_DOS(ERRDOS,ERRnoaccess));
3381 DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_BASIC doing mknod dev %.0f mode \
3382 0%o for file %s\n", (double)dev, unixmode, fname ));
3384 /* Ok - do the mknod. */
3385 if (SMB_VFS_MKNOD(conn,fname, unixmode, dev) != 0)
3386 return(UNIXERROR(ERRDOS,ERRnoaccess));
3388 inherit_access_acl(conn, fname, unixmode);
3391 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
3393 #endif /* HAVE_MAKEDEV_FN */
3398 * Deal with the UNIX specific mode set.
3401 if (raw_unixmode != SMB_MODE_NO_CHANGE) {
3402 DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_BASIC setting mode 0%o for file %s\n",
3403 (unsigned int)unixmode, fname ));
3404 if (SMB_VFS_CHMOD(conn,fname,unixmode) != 0)
3405 return(UNIXERROR(ERRDOS,ERRnoaccess));
3409 * Deal with the UNIX specific uid set.
3412 if ((set_owner != (uid_t)SMB_UID_NO_CHANGE) && (sbuf.st_uid != set_owner)) {
3413 DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_BASIC changing owner %u for file %s\n",
3414 (unsigned int)set_owner, fname ));
3415 if (SMB_VFS_CHOWN(conn,fname,set_owner, (gid_t)-1) != 0)
3416 return(UNIXERROR(ERRDOS,ERRnoaccess));
3420 * Deal with the UNIX specific gid set.
3423 if ((set_grp != (uid_t)SMB_GID_NO_CHANGE) && (sbuf.st_gid != set_grp)) {
3424 DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_BASIC changing group %u for file %s\n",
3425 (unsigned int)set_owner, fname ));
3426 if (SMB_VFS_CHOWN(conn,fname,(uid_t)-1, set_grp) != 0)
3427 return(UNIXERROR(ERRDOS,ERRnoaccess));
3432 case SMB_SET_FILE_UNIX_LINK:
3434 pstring link_target;
3435 char *newname = fname;
3437 /* Set a symbolic link. */
3438 /* Don't allow this if follow links is false. */
3440 if (!lp_symlinks(SNUM(conn)))
3441 return(ERROR_DOS(ERRDOS,ERRnoaccess));
3443 srvstr_pull(inbuf, link_target, pdata, sizeof(link_target), -1, STR_TERMINATE);
3445 /* !widelinks forces the target path to be within the share. */
3446 /* This means we can interpret the target as a pathname. */
3447 if (!lp_widelinks(SNUM(conn))) {
3449 char *last_dirp = NULL;
3451 unix_format(link_target);
3452 if (*link_target == '/') {
3453 /* No absolute paths allowed. */
3454 return(UNIXERROR(ERRDOS,ERRnoaccess));
3456 pstrcpy(rel_name, newname);
3457 last_dirp = strrchr_m(rel_name, '/');
3459 last_dirp[1] = '\0';
3461 pstrcpy(rel_name, "./");
3463 pstrcat(rel_name, link_target);
3465 if (!check_name(rel_name, conn)) {
3466 return(UNIXERROR(ERRDOS,ERRnoaccess));
3470 DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_LINK doing symlink %s -> %s\n",
3471 fname, link_target ));
3473 if (SMB_VFS_SYMLINK(conn,link_target,newname) != 0)
3474 return(UNIXERROR(ERRDOS,ERRnoaccess));
3476 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
3480 case SMB_SET_FILE_UNIX_HLINK:
3483 char *newname = fname;
3485 /* Set a hard link. */
3486 srvstr_get_path(inbuf, oldname, pdata, sizeof(oldname), -1, STR_TERMINATE, &status);
3487 if (!NT_STATUS_IS_OK(status)) {
3488 return ERROR_NT(status);
3491 DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_LINK doing hard link %s -> %s\n",
3494 status = hardlink_internals(conn, oldname, newname);
3495 if (!NT_STATUS_IS_OK(status)) {
3496 return ERROR_NT(status);
3500 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
3504 case SMB_FILE_RENAME_INFORMATION:
3513 if (total_data < 12)
3514 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
3516 overwrite = (CVAL(pdata,0) ? True : False);
3517 root_fid = IVAL(pdata,4);
3518 len = IVAL(pdata,8);
3519 srvstr_get_path(inbuf, newname, &pdata[12], sizeof(newname), len, 0, &status);
3520 if (!NT_STATUS_IS_OK(status)) {
3521 return ERROR_NT(status);
3524 /* Check the new name has no '/' characters. */
3525 if (strchr_m(newname, '/'))
3526 return ERROR_NT(NT_STATUS_NOT_SUPPORTED);
3528 RESOLVE_DFSPATH(newname, conn, inbuf, outbuf);
3530 /* Create the base directory. */
3531 pstrcpy(base_name, fname);
3532 p = strrchr_m(base_name, '/');
3535 /* Append the new name. */
3536 pstrcat(base_name, "/");
3537 pstrcat(base_name, newname);
3540 DEBUG(10,("call_trans2setfilepathinfo: SMB_FILE_RENAME_INFORMATION (fnum %d) %s -> %s\n",
3541 fsp->fnum, fsp->fsp_name, base_name ));
3542 status = rename_internals_fsp(conn, fsp, base_name, overwrite);
3544 DEBUG(10,("call_trans2setfilepathinfo: SMB_FILE_RENAME_INFORMATION %s -> %s\n",
3546 status = rename_internals(conn, fname, base_name, 0, overwrite);
3548 if (!NT_STATUS_IS_OK(status)) {
3549 return ERROR_NT(status);
3551 process_pending_change_notify_queue((time_t)0);
3553 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
3557 return ERROR_DOS(ERRDOS,ERRunknownlevel);
3560 /* get some defaults (no modifications) if any info is zero or -1. */
3561 if (tvs.actime == (time_t)0 || tvs.actime == (time_t)-1)
3562 tvs.actime = sbuf.st_atime;
3564 if (tvs.modtime == (time_t)0 || tvs.modtime == (time_t)-1)
3565 tvs.modtime = sbuf.st_mtime;
3567 DEBUG(6,("actime: %s " , ctime(&tvs.actime)));
3568 DEBUG(6,("modtime: %s ", ctime(&tvs.modtime)));
3569 DEBUG(6,("size: %.0f ", (double)size));
3572 if (S_ISDIR(sbuf.st_mode))
3578 DEBUG(6,("dosmode: %x\n" , dosmode));
3580 if(!((info_level == SMB_SET_FILE_END_OF_FILE_INFO) ||
3581 (info_level == SMB_SET_FILE_ALLOCATION_INFO) ||
3582 (info_level == SMB_FILE_ALLOCATION_INFORMATION) ||
3583 (info_level == SMB_FILE_END_OF_FILE_INFORMATION))) {
3586 * Only do this test if we are not explicitly
3587 * changing the size of a file.
3590 size = get_file_size(sbuf);
3594 * Try and set the times, size and mode of this file -
3595 * if they are different from the current values
3597 if (sbuf.st_mtime != tvs.modtime || sbuf.st_atime != tvs.actime) {
3600 * This was a setfileinfo on an open file.
3601 * NT does this a lot. It's actually pointless
3602 * setting the time here, as it will be overwritten
3603 * on the next write, so we save the request
3604 * away and will set it on file close. JRA.
3607 if (tvs.modtime != (time_t)0 && tvs.modtime != (time_t)-1) {
3608 DEBUG(10,("call_trans2setfilepathinfo: setting pending modtime to %s\n", ctime(&tvs.modtime) ));
3609 fsp->pending_modtime = tvs.modtime;
3614 DEBUG(10,("call_trans2setfilepathinfo: setting utimes to modified values.\n"));
3616 if(file_utime(conn, fname, &tvs)!=0)
3617 return(UNIXERROR(ERRDOS,ERRnoaccess));
3621 /* check the mode isn't different, before changing it */
3622 if ((dosmode != 0) && (dosmode != dos_mode(conn, fname, &sbuf))) {
3624 DEBUG(10,("call_trans2setfilepathinfo: file %s : setting dos mode %x\n", fname, dosmode ));
3626 if(file_set_dosmode(conn, fname, dosmode, NULL)) {
3627 DEBUG(2,("file_set_dosmode of %s failed (%s)\n", fname, strerror(errno)));
3628 return(UNIXERROR(ERRDOS,ERRnoaccess));
3632 if (size != get_file_size(sbuf)) {
3636 DEBUG(10,("call_trans2setfilepathinfo: file %s : setting new size to %.0f\n",
3637 fname, (double)size ));
3640 files_struct *new_fsp = NULL;
3641 int access_mode = 0;
3644 if(global_oplock_break) {
3645 /* Queue this file modify as we are the process of an oplock break. */
3647 DEBUG(2,("call_trans2setfilepathinfo: queueing message due to being "));
3648 DEBUGADD(2,( "in oplock break state.\n"));
3650 push_oplock_pending_smb_message(inbuf, length);
3654 new_fsp = open_file_shared(conn, fname, &sbuf,
3655 SET_OPEN_MODE(DOS_OPEN_RDWR),
3656 (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN),
3657 FILE_ATTRIBUTE_NORMAL,
3658 0, &access_mode, &action);
3660 if (new_fsp == NULL)
3661 return(UNIXERROR(ERRDOS,ERRbadpath));
3662 ret = vfs_set_filelen(new_fsp, size);
3663 close_file(new_fsp,True);
3665 ret = vfs_set_filelen(fsp, size);
3669 return (UNIXERROR(ERRHRD,ERRdiskfull));
3673 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
3678 /****************************************************************************
3679 Reply to a TRANS2_MKDIR (make directory with extended attributes).
3680 ****************************************************************************/
3682 static int call_trans2mkdir(connection_struct *conn,
3683 char *inbuf, char *outbuf, int length, int bufsize,
3684 char **pparams, int total_params, char **ppdata, int total_data)
3686 char *params = *pparams;
3689 SMB_STRUCT_STAT sbuf;
3690 BOOL bad_path = False;
3691 NTSTATUS status = NT_STATUS_OK;
3693 if (!CAN_WRITE(conn))
3694 return ERROR_DOS(ERRSRV,ERRaccess);
3696 if (total_params < 4)
3697 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
3699 srvstr_get_path(inbuf, directory, ¶ms[4], sizeof(directory), -1, STR_TERMINATE, &status);
3700 if (!NT_STATUS_IS_OK(status)) {
3701 return ERROR_NT(status);
3704 DEBUG(3,("call_trans2mkdir : name = %s\n", directory));
3706 unix_convert(directory,conn,0,&bad_path,&sbuf);
3707 if (check_name(directory,conn))
3708 ret = vfs_MkDir(conn,directory,unix_mode(conn,aDIR,directory));
3711 DEBUG(5,("call_trans2mkdir error (%s)\n", strerror(errno)));
3712 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRnoaccess);
3715 /* Realloc the parameter and data sizes */
3716 params = Realloc(*pparams,2);
3718 return ERROR_DOS(ERRDOS,ERRnomem);
3723 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
3728 /****************************************************************************
3729 Reply to a TRANS2_FINDNOTIFYFIRST (start monitoring a directory for changes).
3730 We don't actually do this - we just send a null response.
3731 ****************************************************************************/
3733 static int call_trans2findnotifyfirst(connection_struct *conn,
3734 char *inbuf, char *outbuf, int length, int bufsize,
3735 char **pparams, int total_params, char **ppdata, int total_data)
3737 static uint16 fnf_handle = 257;
3738 char *params = *pparams;
3741 if (total_params < 6)
3742 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
3744 info_level = SVAL(params,4);
3745 DEBUG(3,("call_trans2findnotifyfirst - info_level %d\n", info_level));
3747 switch (info_level) {
3752 return ERROR_DOS(ERRDOS,ERRunknownlevel);
3755 /* Realloc the parameter and data sizes */
3756 params = Realloc(*pparams,6);
3758 return ERROR_DOS(ERRDOS,ERRnomem);
3761 SSVAL(params,0,fnf_handle);
3762 SSVAL(params,2,0); /* No changes */
3763 SSVAL(params,4,0); /* No EA errors */
3770 send_trans2_replies(outbuf, bufsize, params, 6, *ppdata, 0);
3775 /****************************************************************************
3776 Reply to a TRANS2_FINDNOTIFYNEXT (continue monitoring a directory for
3777 changes). Currently this does nothing.
3778 ****************************************************************************/
3780 static int call_trans2findnotifynext(connection_struct *conn,
3781 char *inbuf, char *outbuf, int length, int bufsize,
3782 char **pparams, int total_params, char **ppdata, int total_data)
3784 char *params = *pparams;
3786 DEBUG(3,("call_trans2findnotifynext\n"));
3788 /* Realloc the parameter and data sizes */
3789 params = Realloc(*pparams,4);
3791 return ERROR_DOS(ERRDOS,ERRnomem);
3794 SSVAL(params,0,0); /* No changes */
3795 SSVAL(params,2,0); /* No EA errors */
3797 send_trans2_replies(outbuf, bufsize, params, 4, *ppdata, 0);
3802 /****************************************************************************
3803 Reply to a TRANS2_GET_DFS_REFERRAL - Shirish Kalele <kalele@veritas.com>.
3804 ****************************************************************************/
3806 static int call_trans2getdfsreferral(connection_struct *conn, char* inbuf,
3807 char* outbuf, int length, int bufsize,
3808 char **pparams, int total_params, char **ppdata, int total_data)
3810 char *params = *pparams;
3813 int max_referral_level;
3815 DEBUG(10,("call_trans2getdfsreferral\n"));
3817 if (total_params < 2)
3818 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
3820 max_referral_level = SVAL(params,0);
3822 if(!lp_host_msdfs())
3823 return ERROR_DOS(ERRDOS,ERRbadfunc);
3825 srvstr_pull(inbuf, pathname, ¶ms[2], sizeof(pathname), -1, STR_TERMINATE);
3826 if((reply_size = setup_dfs_referral(conn, pathname,max_referral_level,ppdata)) < 0)
3827 return UNIXERROR(ERRDOS,ERRbadfile);
3829 SSVAL(outbuf,smb_flg2,SVAL(outbuf,smb_flg2) | FLAGS2_DFS_PATHNAMES);
3830 send_trans2_replies(outbuf,bufsize,0,0,*ppdata,reply_size);
3835 #define LMCAT_SPL 0x53
3836 #define LMFUNC_GETJOBID 0x60
3838 /****************************************************************************
3839 Reply to a TRANS2_IOCTL - used for OS/2 printing.
3840 ****************************************************************************/
3842 static int call_trans2ioctl(connection_struct *conn, char* inbuf,
3843 char* outbuf, int length, int bufsize,
3844 char **pparams, int total_params, char **ppdata, int total_data)
3846 char *pdata = *ppdata;
3847 files_struct *fsp = file_fsp(inbuf,smb_vwv15);
3849 /* check for an invalid fid before proceeding */
3852 return(ERROR_DOS(ERRDOS,ERRbadfid));
3854 if ((SVAL(inbuf,(smb_setup+4)) == LMCAT_SPL) &&
3855 (SVAL(inbuf,(smb_setup+6)) == LMFUNC_GETJOBID)) {
3856 pdata = Realloc(*ppdata, 32);
3858 return ERROR_DOS(ERRDOS,ERRnomem);
3861 /* NOTE - THIS IS ASCII ONLY AT THE MOMENT - NOT SURE IF OS/2
3862 CAN ACCEPT THIS IN UNICODE. JRA. */
3864 SSVAL(pdata,0,fsp->rap_print_jobid); /* Job number */
3865 srvstr_push( outbuf, pdata + 2, global_myname(), 15, STR_ASCII|STR_TERMINATE); /* Our NetBIOS name */
3866 srvstr_push( outbuf, pdata+18, lp_servicename(SNUM(conn)), 13, STR_ASCII|STR_TERMINATE); /* Service name */
3867 send_trans2_replies(outbuf,bufsize,*pparams,0,*ppdata,32);
3870 DEBUG(2,("Unknown TRANS2_IOCTL\n"));
3871 return ERROR_DOS(ERRSRV,ERRerror);
3875 /****************************************************************************
3876 Reply to a SMBfindclose (stop trans2 directory search).
3877 ****************************************************************************/
3879 int reply_findclose(connection_struct *conn,
3880 char *inbuf,char *outbuf,int length,int bufsize)
3883 int dptr_num=SVALS(inbuf,smb_vwv0);
3884 START_PROFILE(SMBfindclose);
3886 DEBUG(3,("reply_findclose, dptr_num = %d\n", dptr_num));
3888 dptr_close(&dptr_num);
3890 outsize = set_message(outbuf,0,0,True);
3892 DEBUG(3,("SMBfindclose dptr_num = %d\n", dptr_num));
3894 END_PROFILE(SMBfindclose);
3898 /****************************************************************************
3899 Reply to a SMBfindnclose (stop FINDNOTIFYFIRST directory search).
3900 ****************************************************************************/
3902 int reply_findnclose(connection_struct *conn,
3903 char *inbuf,char *outbuf,int length,int bufsize)
3907 START_PROFILE(SMBfindnclose);
3909 dptr_num = SVAL(inbuf,smb_vwv0);
3911 DEBUG(3,("reply_findnclose, dptr_num = %d\n", dptr_num));
3913 /* We never give out valid handles for a
3914 findnotifyfirst - so any dptr_num is ok here.
3917 outsize = set_message(outbuf,0,0,True);
3919 DEBUG(3,("SMB_findnclose dptr_num = %d\n", dptr_num));
3921 END_PROFILE(SMBfindnclose);
3925 /****************************************************************************
3926 Reply to a SMBtranss2 - just ignore it!
3927 ****************************************************************************/
3929 int reply_transs2(connection_struct *conn,
3930 char *inbuf,char *outbuf,int length,int bufsize)
3932 START_PROFILE(SMBtranss2);
3933 DEBUG(4,("Ignoring transs2 of length %d\n",length));
3934 END_PROFILE(SMBtranss2);
3938 /****************************************************************************
3939 Reply to a SMBtrans2.
3940 ****************************************************************************/
3942 int reply_trans2(connection_struct *conn,
3943 char *inbuf,char *outbuf,int length,int bufsize)
3946 unsigned int total_params = SVAL(inbuf, smb_tpscnt);
3947 unsigned int total_data =SVAL(inbuf, smb_tdscnt);
3949 unsigned int max_param_reply = SVAL(inbuf, smb_mprcnt);
3950 unsigned int max_data_reply = SVAL(inbuf, smb_mdrcnt);
3951 unsigned int max_setup_fields = SVAL(inbuf, smb_msrcnt);
3952 BOOL close_tid = BITSETW(inbuf+smb_flags,0);
3953 BOOL no_final_response = BITSETW(inbuf+smb_flags,1);
3954 int32 timeout = IVALS(inbuf,smb_timeout);
3956 unsigned int suwcnt = SVAL(inbuf, smb_suwcnt);
3957 unsigned int tran_call = SVAL(inbuf, smb_setup0);
3958 char *params = NULL, *data = NULL;
3959 unsigned int num_params, num_params_sofar, num_data, num_data_sofar;
3960 START_PROFILE(SMBtrans2);
3962 if(global_oplock_break && (tran_call == TRANSACT2_OPEN)) {
3963 /* Queue this open message as we are the process of an
3966 DEBUG(2,("reply_trans2: queueing message trans2open due to being "));
3967 DEBUGADD(2,( "in oplock break state.\n"));
3969 push_oplock_pending_smb_message(inbuf, length);
3970 END_PROFILE(SMBtrans2);
3974 if (IS_IPC(conn) && (tran_call != TRANSACT2_OPEN)
3975 && (tran_call != TRANSACT2_GET_DFS_REFERRAL)) {
3976 END_PROFILE(SMBtrans2);
3977 return ERROR_DOS(ERRSRV,ERRaccess);
3980 outsize = set_message(outbuf,0,0,True);
3982 /* All trans2 messages we handle have smb_sucnt == 1 - ensure this
3983 is so as a sanity check */
3986 * Need to have rc=0 for ioctl to get job id for OS/2.
3987 * Network printing will fail if function is not successful.
3988 * Similar function in reply.c will be used if protocol
3989 * is LANMAN1.0 instead of LM1.2X002.
3990 * Until DosPrintSetJobInfo with PRJINFO3 is supported,
3991 * outbuf doesn't have to be set(only job id is used).
3993 if ( (suwcnt == 4) && (tran_call == TRANSACT2_IOCTL) &&
3994 (SVAL(inbuf,(smb_setup+4)) == LMCAT_SPL) &&
3995 (SVAL(inbuf,(smb_setup+6)) == LMFUNC_GETJOBID)) {
3996 DEBUG(2,("Got Trans2 DevIOctl jobid\n"));
3998 DEBUG(2,("Invalid smb_sucnt in trans2 call(%u)\n",suwcnt));
3999 DEBUG(2,("Transaction is %d\n",tran_call));
4000 END_PROFILE(SMBtrans2);
4001 ERROR_DOS(ERRDOS,ERRinvalidparam);
4005 /* Allocate the space for the maximum needed parameters and data */
4006 if (total_params > 0)
4007 params = (char *)malloc(total_params);
4009 data = (char *)malloc(total_data);
4011 if ((total_params && !params) || (total_data && !data)) {
4012 DEBUG(2,("Out of memory in reply_trans2\n"));
4015 END_PROFILE(SMBtrans2);
4016 return ERROR_DOS(ERRDOS,ERRnomem);
4019 /* Copy the param and data bytes sent with this request into
4020 the params buffer */
4021 num_params = num_params_sofar = SVAL(inbuf,smb_pscnt);
4022 num_data = num_data_sofar = SVAL(inbuf, smb_dscnt);
4024 if (num_params > total_params || num_data > total_data)
4025 exit_server("invalid params in reply_trans2");
4028 unsigned int psoff = SVAL(inbuf, smb_psoff);
4029 if ((psoff + num_params < psoff) || (psoff + num_params < num_params))
4031 if ((smb_base(inbuf) + psoff + num_params > inbuf + length) ||
4032 (smb_base(inbuf) + psoff + num_params < smb_base(inbuf)))
4034 memcpy( params, smb_base(inbuf) + psoff, num_params);
4037 unsigned int dsoff = SVAL(inbuf, smb_dsoff);
4038 if ((dsoff + num_data < dsoff) || (dsoff + num_data < num_data))
4040 if ((smb_base(inbuf) + dsoff + num_data > inbuf + length) ||
4041 (smb_base(inbuf) + dsoff + num_data < smb_base(inbuf)))
4043 memcpy( data, smb_base(inbuf) + dsoff, num_data);
4046 srv_signing_trans_start(SVAL(inbuf,smb_mid));
4048 if(num_data_sofar < total_data || num_params_sofar < total_params) {
4049 /* We need to send an interim response then receive the rest
4050 of the parameter/data bytes */
4051 outsize = set_message(outbuf,0,0,True);
4052 srv_signing_trans_stop();
4053 if (!send_smb(smbd_server_fd(),outbuf))
4054 exit_server("reply_trans2: send_smb failed.");
4056 while (num_data_sofar < total_data ||
4057 num_params_sofar < total_params) {
4059 unsigned int param_disp;
4060 unsigned int param_off;
4061 unsigned int data_disp;
4062 unsigned int data_off;
4064 ret = receive_next_smb(inbuf,bufsize,SMB_SECONDARY_WAIT);
4067 * The sequence number for the trans reply is always
4068 * based on the last secondary received.
4071 srv_signing_trans_start(SVAL(inbuf,smb_mid));
4074 (CVAL(inbuf, smb_com) != SMBtranss2)) || !ret) {
4075 outsize = set_message(outbuf,0,0,True);
4077 DEBUG(0,("reply_trans2: Invalid secondary trans2 packet\n"));
4079 DEBUG(0,("reply_trans2: %s in getting secondary trans2 response.\n",
4080 (smb_read_error == READ_ERROR) ? "error" : "timeout" ));
4084 /* Revise total_params and total_data in case
4085 they have changed downwards */
4086 if (SVAL(inbuf, smb_tpscnt) < total_params)
4087 total_params = SVAL(inbuf, smb_tpscnt);
4088 if (SVAL(inbuf, smb_tdscnt) < total_data)
4089 total_data = SVAL(inbuf, smb_tdscnt);
4091 num_params = SVAL(inbuf,smb_spscnt);
4092 param_off = SVAL(inbuf, smb_spsoff);
4093 param_disp = SVAL(inbuf, smb_spsdisp);
4094 num_params_sofar += num_params;
4096 num_data = SVAL(inbuf, smb_sdscnt);
4097 data_off = SVAL(inbuf, smb_sdsoff);
4098 data_disp = SVAL(inbuf, smb_sdsdisp);
4099 num_data_sofar += num_data;
4101 if (num_params_sofar > total_params || num_data_sofar > total_data)
4105 if (param_disp + num_params >= total_params)
4107 if ((param_disp + num_params < param_disp) ||
4108 (param_disp + num_params < num_params))
4110 if (param_disp > total_params)
4112 if ((smb_base(inbuf) + param_off + num_params >= inbuf + bufsize) ||
4113 (smb_base(inbuf) + param_off + num_params < smb_base(inbuf)))
4115 if (params + param_disp < params)
4118 memcpy( ¶ms[param_disp], smb_base(inbuf) + param_off, num_params);
4121 if (data_disp + num_data >= total_data)
4123 if ((data_disp + num_data < data_disp) ||
4124 (data_disp + num_data < num_data))
4126 if (data_disp > total_data)
4128 if ((smb_base(inbuf) + data_off + num_data >= inbuf + bufsize) ||
4129 (smb_base(inbuf) + data_off + num_data < smb_base(inbuf)))
4131 if (data + data_disp < data)
4134 memcpy( &data[data_disp], smb_base(inbuf) + data_off, num_data);
4139 if (Protocol >= PROTOCOL_NT1) {
4140 SSVAL(outbuf,smb_flg2,SVAL(outbuf,smb_flg2) | 0x40); /* IS_LONG_NAME */
4143 /* Now we must call the relevant TRANS2 function */
4145 case TRANSACT2_OPEN:
4146 START_PROFILE_NESTED(Trans2_open);
4147 outsize = call_trans2open(conn, inbuf, outbuf, bufsize,
4148 ¶ms, total_params, &data, total_data);
4149 END_PROFILE_NESTED(Trans2_open);
4152 case TRANSACT2_FINDFIRST:
4153 START_PROFILE_NESTED(Trans2_findfirst);
4154 outsize = call_trans2findfirst(conn, inbuf, outbuf, bufsize,
4155 ¶ms, total_params, &data, total_data);
4156 END_PROFILE_NESTED(Trans2_findfirst);
4159 case TRANSACT2_FINDNEXT:
4160 START_PROFILE_NESTED(Trans2_findnext);
4161 outsize = call_trans2findnext(conn, inbuf, outbuf, length, bufsize,
4162 ¶ms, total_params, &data, total_data);
4163 END_PROFILE_NESTED(Trans2_findnext);
4166 case TRANSACT2_QFSINFO:
4167 START_PROFILE_NESTED(Trans2_qfsinfo);
4168 outsize = call_trans2qfsinfo(conn, inbuf, outbuf, length, bufsize,
4169 ¶ms, total_params, &data, total_data);
4170 END_PROFILE_NESTED(Trans2_qfsinfo);
4173 #ifdef HAVE_SYS_QUOTAS
4174 case TRANSACT2_SETFSINFO:
4175 START_PROFILE_NESTED(Trans2_setfsinfo);
4176 outsize = call_trans2setfsinfo(conn, inbuf, outbuf, length, bufsize,
4177 ¶ms, total_params, &data, total_data);
4178 END_PROFILE_NESTED(Trans2_setfsinfo);
4181 case TRANSACT2_QPATHINFO:
4182 case TRANSACT2_QFILEINFO:
4183 START_PROFILE_NESTED(Trans2_qpathinfo);
4184 outsize = call_trans2qfilepathinfo(conn, inbuf, outbuf, length, bufsize,
4185 ¶ms, total_params, &data, total_data);
4186 END_PROFILE_NESTED(Trans2_qpathinfo);
4188 case TRANSACT2_SETPATHINFO:
4189 case TRANSACT2_SETFILEINFO:
4190 START_PROFILE_NESTED(Trans2_setpathinfo);
4191 outsize = call_trans2setfilepathinfo(conn, inbuf, outbuf, length, bufsize,
4192 ¶ms, total_params, &data, total_data);
4193 END_PROFILE_NESTED(Trans2_setpathinfo);
4196 case TRANSACT2_FINDNOTIFYFIRST:
4197 START_PROFILE_NESTED(Trans2_findnotifyfirst);
4198 outsize = call_trans2findnotifyfirst(conn, inbuf, outbuf, length, bufsize,
4199 ¶ms, total_params, &data, total_data);
4200 END_PROFILE_NESTED(Trans2_findnotifyfirst);
4203 case TRANSACT2_FINDNOTIFYNEXT:
4204 START_PROFILE_NESTED(Trans2_findnotifynext);
4205 outsize = call_trans2findnotifynext(conn, inbuf, outbuf, length, bufsize,
4206 ¶ms, total_params, &data, total_data);
4207 END_PROFILE_NESTED(Trans2_findnotifynext);
4209 case TRANSACT2_MKDIR:
4210 START_PROFILE_NESTED(Trans2_mkdir);
4211 outsize = call_trans2mkdir(conn, inbuf, outbuf, length, bufsize,
4212 ¶ms, total_params, &data, total_data);
4213 END_PROFILE_NESTED(Trans2_mkdir);
4216 case TRANSACT2_GET_DFS_REFERRAL:
4217 START_PROFILE_NESTED(Trans2_get_dfs_referral);
4218 outsize = call_trans2getdfsreferral(conn,inbuf,outbuf,length, bufsize,
4219 ¶ms, total_params, &data, total_data);
4220 END_PROFILE_NESTED(Trans2_get_dfs_referral);
4222 case TRANSACT2_IOCTL:
4223 START_PROFILE_NESTED(Trans2_ioctl);
4224 outsize = call_trans2ioctl(conn,inbuf,outbuf,length, bufsize,
4225 ¶ms, total_params, &data, total_data);
4226 END_PROFILE_NESTED(Trans2_ioctl);
4229 /* Error in request */
4230 DEBUG(2,("Unknown request %d in trans2 call\n", tran_call));
4233 END_PROFILE(SMBtrans2);
4234 srv_signing_trans_stop();
4235 return ERROR_DOS(ERRSRV,ERRerror);
4238 /* As we do not know how many data packets will need to be
4239 returned here the various call_trans2xxxx calls
4240 must send their own. Thus a call_trans2xxx routine only
4241 returns a value other than -1 when it wants to send
4245 srv_signing_trans_stop();
4249 END_PROFILE(SMBtrans2);
4250 return outsize; /* If a correct response was needed the
4251 call_trans2xxx calls have already sent
4252 it. If outsize != -1 then it is returning */
4256 srv_signing_trans_stop();
4259 END_PROFILE(SMBtrans2);
4260 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);