2 Unix SMB/CIFS implementation.
3 SMB transaction2 handling
4 Copyright (C) Jeremy Allison 1994-2003
5 Copyright (C) Stefan (metze) Metzmacher 2003
6 Copyright (C) Volker Lendecke 2005
7 Copyright (C) Steve French 2005
9 Extensively modified by Andrew Tridgell, 1995
11 This program is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation; either version 2 of the License, or
14 (at your option) any later version.
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU General Public License for more details.
21 You should have received a copy of the GNU General Public License
22 along with this program; if not, write to the Free Software
23 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
29 extern enum protocol_types Protocol;
30 extern int smb_read_error;
31 extern uint32 global_client_caps;
32 extern struct current_user current_user;
34 #define get_file_size(sbuf) ((sbuf).st_size)
35 #define DIR_ENTRY_SAFETY_MARGIN 4096
37 /********************************************************************
38 Roundup a value to the nearest allocation roundup size boundary.
39 Only do this for Windows clients.
40 ********************************************************************/
42 SMB_BIG_UINT smb_roundup(connection_struct *conn, SMB_BIG_UINT val)
44 SMB_BIG_UINT rval = lp_allocation_roundup_size(SNUM(conn));
46 /* Only roundup for Windows clients. */
47 enum remote_arch_types ra_type = get_remote_arch();
48 if (rval && (ra_type != RA_SAMBA) && (ra_type != RA_CIFSFS)) {
49 val = SMB_ROUNDUP(val,rval);
54 /********************************************************************
55 Given a stat buffer return the allocated size on disk, taking into
57 ********************************************************************/
59 SMB_BIG_UINT get_allocation_size(connection_struct *conn, files_struct *fsp, SMB_STRUCT_STAT *sbuf)
63 if(S_ISDIR(sbuf->st_mode)) {
67 #if defined(HAVE_STAT_ST_BLOCKS) && defined(STAT_ST_BLOCKSIZE)
68 ret = (SMB_BIG_UINT)STAT_ST_BLOCKSIZE * (SMB_BIG_UINT)sbuf->st_blocks;
70 ret = (SMB_BIG_UINT)get_file_size(*sbuf);
73 if (fsp && fsp->initial_allocation_size)
74 ret = MAX(ret,fsp->initial_allocation_size);
76 return smb_roundup(conn, ret);
79 /****************************************************************************
80 Utility functions for dealing with extended attributes.
81 ****************************************************************************/
83 static const char *prohibited_ea_names[] = {
84 SAMBA_POSIX_INHERITANCE_EA_NAME,
85 SAMBA_XATTR_DOS_ATTRIB,
89 /****************************************************************************
90 Refuse to allow clients to overwrite our private xattrs.
91 ****************************************************************************/
93 static BOOL samba_private_attr_name(const char *unix_ea_name)
97 for (i = 0; prohibited_ea_names[i]; i++) {
98 if (strequal( prohibited_ea_names[i], unix_ea_name))
104 /****************************************************************************
105 Get one EA value. Fill in a struct ea_struct.
106 ****************************************************************************/
108 static BOOL get_ea_value(TALLOC_CTX *mem_ctx, connection_struct *conn, files_struct *fsp,
109 const char *fname, char *ea_name, struct ea_struct *pea)
111 /* Get the value of this xattr. Max size is 64k. */
112 size_t attr_size = 256;
118 val = TALLOC_REALLOC_ARRAY(mem_ctx, val, char, attr_size);
123 if (fsp && fsp->fh->fd != -1) {
124 sizeret = SMB_VFS_FGETXATTR(fsp, fsp->fh->fd, ea_name, val, attr_size);
126 sizeret = SMB_VFS_GETXATTR(conn, fname, ea_name, val, attr_size);
129 if (sizeret == -1 && errno == ERANGE && attr_size != 65536) {
138 DEBUG(10,("get_ea_value: EA %s is of length %u: ", ea_name, (unsigned int)sizeret));
139 dump_data(10, val, sizeret);
142 if (strnequal(ea_name, "user.", 5)) {
143 pea->name = &ea_name[5];
147 pea->value.data = (unsigned char *)val;
148 pea->value.length = (size_t)sizeret;
152 /****************************************************************************
153 Return a linked list of the total EA's. Plus the total size
154 ****************************************************************************/
156 static struct ea_list *get_ea_list_from_file(TALLOC_CTX *mem_ctx, connection_struct *conn, files_struct *fsp,
157 const char *fname, size_t *pea_total_len)
159 /* Get a list of all xattrs. Max namesize is 64k. */
160 size_t ea_namelist_size = 1024;
165 struct ea_list *ea_list_head = NULL;
169 if (!lp_ea_support(SNUM(conn))) {
173 for (i = 0, ea_namelist = TALLOC_ARRAY(mem_ctx, char, ea_namelist_size); i < 6;
174 ea_namelist = TALLOC_REALLOC_ARRAY(mem_ctx, ea_namelist, char, ea_namelist_size), i++) {
180 if (fsp && fsp->fh->fd != -1) {
181 sizeret = SMB_VFS_FLISTXATTR(fsp, fsp->fh->fd, ea_namelist, ea_namelist_size);
183 sizeret = SMB_VFS_LISTXATTR(conn, fname, ea_namelist, ea_namelist_size);
186 if (sizeret == -1 && errno == ERANGE) {
187 ea_namelist_size *= 2;
196 DEBUG(10,("get_ea_list_from_file: ea_namelist size = %u\n", (unsigned int)sizeret ));
199 for (p = ea_namelist; p - ea_namelist < sizeret; p += strlen(p) + 1) {
200 struct ea_list *listp, *tmp;
202 if (strnequal(p, "system.", 7) || samba_private_attr_name(p))
205 listp = TALLOC_P(mem_ctx, struct ea_list);
209 if (!get_ea_value(mem_ctx, conn, fsp, fname, p, &listp->ea)) {
215 push_ascii_fstring(dos_ea_name, listp->ea.name);
216 *pea_total_len += 4 + strlen(dos_ea_name) + 1 + listp->ea.value.length;
217 DEBUG(10,("get_ea_list_from_file: total_len = %u, %s, val len = %u\n",
218 (unsigned int)*pea_total_len, dos_ea_name,
219 (unsigned int)listp->ea.value.length ));
221 DLIST_ADD_END(ea_list_head, listp, tmp);
223 /* Add on 4 for total length. */
224 if (*pea_total_len) {
229 DEBUG(10,("get_ea_list_from_file: total_len = %u\n", (unsigned int)*pea_total_len));
233 /****************************************************************************
234 Fill a qfilepathinfo buffer with EA's. Returns the length of the buffer
236 ****************************************************************************/
238 static unsigned int fill_ea_buffer(TALLOC_CTX *mem_ctx, char *pdata, unsigned int total_data_size,
239 connection_struct *conn, struct ea_list *ea_list)
241 unsigned int ret_data_size = 4;
244 SMB_ASSERT(total_data_size >= 4);
246 if (!lp_ea_support(SNUM(conn))) {
251 for (p = pdata + 4; ea_list; ea_list = ea_list->next) {
254 push_ascii_fstring(dos_ea_name, ea_list->ea.name);
255 dos_namelen = strlen(dos_ea_name);
256 if (dos_namelen > 255 || dos_namelen == 0) {
259 if (ea_list->ea.value.length > 65535) {
262 if (4 + dos_namelen + 1 + ea_list->ea.value.length > total_data_size) {
266 /* We know we have room. */
267 SCVAL(p,0,ea_list->ea.flags);
268 SCVAL(p,1,dos_namelen);
269 SSVAL(p,2,ea_list->ea.value.length);
270 fstrcpy(p+4, dos_ea_name);
271 memcpy( p + 4 + dos_namelen + 1, ea_list->ea.value.data, ea_list->ea.value.length);
273 total_data_size -= 4 + dos_namelen + 1 + ea_list->ea.value.length;
274 p += 4 + dos_namelen + 1 + ea_list->ea.value.length;
277 ret_data_size = PTR_DIFF(p, pdata);
278 DEBUG(10,("fill_ea_buffer: data_size = %u\n", ret_data_size ));
279 SIVAL(pdata,0,ret_data_size);
280 return ret_data_size;
283 static unsigned int estimate_ea_size(connection_struct *conn, files_struct *fsp, const char *fname)
285 size_t total_ea_len = 0;
286 TALLOC_CTX *mem_ctx = NULL;
288 if (!lp_ea_support(SNUM(conn))) {
291 mem_ctx = talloc_init("estimate_ea_size");
292 (void)get_ea_list_from_file(mem_ctx, conn, fsp, fname, &total_ea_len);
293 talloc_destroy(mem_ctx);
297 /****************************************************************************
298 Ensure the EA name is case insensitive by matching any existing EA name.
299 ****************************************************************************/
301 static void canonicalize_ea_name(connection_struct *conn, files_struct *fsp, const char *fname, fstring unix_ea_name)
304 TALLOC_CTX *mem_ctx = talloc_init("canonicalize_ea_name");
305 struct ea_list *ea_list = get_ea_list_from_file(mem_ctx, conn, fsp, fname, &total_ea_len);
307 for (; ea_list; ea_list = ea_list->next) {
308 if (strequal(&unix_ea_name[5], ea_list->ea.name)) {
309 DEBUG(10,("canonicalize_ea_name: %s -> %s\n",
310 &unix_ea_name[5], ea_list->ea.name));
311 safe_strcpy(&unix_ea_name[5], ea_list->ea.name, sizeof(fstring)-6);
315 talloc_destroy(mem_ctx);
318 /****************************************************************************
319 Set or delete an extended attribute.
320 ****************************************************************************/
322 NTSTATUS set_ea(connection_struct *conn, files_struct *fsp, const char *fname, struct ea_list *ea_list)
324 if (!lp_ea_support(SNUM(conn))) {
325 return NT_STATUS_EAS_NOT_SUPPORTED;
328 for (;ea_list; ea_list = ea_list->next) {
330 fstring unix_ea_name;
332 fstrcpy(unix_ea_name, "user."); /* All EA's must start with user. */
333 fstrcat(unix_ea_name, ea_list->ea.name);
335 canonicalize_ea_name(conn, fsp, fname, unix_ea_name);
337 DEBUG(10,("set_ea: ea_name %s ealen = %u\n", unix_ea_name, (unsigned int)ea_list->ea.value.length));
339 if (samba_private_attr_name(unix_ea_name)) {
340 DEBUG(10,("set_ea: ea name %s is a private Samba name.\n", unix_ea_name));
341 return NT_STATUS_ACCESS_DENIED;
344 if (ea_list->ea.value.length == 0) {
345 /* Remove the attribute. */
346 if (fsp && (fsp->fh->fd != -1)) {
347 DEBUG(10,("set_ea: deleting ea name %s on file %s by file descriptor.\n",
348 unix_ea_name, fsp->fsp_name));
349 ret = SMB_VFS_FREMOVEXATTR(fsp, fsp->fh->fd, unix_ea_name);
351 DEBUG(10,("set_ea: deleting ea name %s on file %s.\n",
352 unix_ea_name, fname));
353 ret = SMB_VFS_REMOVEXATTR(conn, fname, unix_ea_name);
356 /* Removing a non existent attribute always succeeds. */
357 if (ret == -1 && errno == ENOATTR) {
358 DEBUG(10,("set_ea: deleting ea name %s didn't exist - succeeding by default.\n",
364 if (fsp && (fsp->fh->fd != -1)) {
365 DEBUG(10,("set_ea: setting ea name %s on file %s by file descriptor.\n",
366 unix_ea_name, fsp->fsp_name));
367 ret = SMB_VFS_FSETXATTR(fsp, fsp->fh->fd, unix_ea_name,
368 ea_list->ea.value.data, ea_list->ea.value.length, 0);
370 DEBUG(10,("set_ea: setting ea name %s on file %s.\n",
371 unix_ea_name, fname));
372 ret = SMB_VFS_SETXATTR(conn, fname, unix_ea_name,
373 ea_list->ea.value.data, ea_list->ea.value.length, 0);
379 if (errno == ENOTSUP) {
380 return NT_STATUS_EAS_NOT_SUPPORTED;
383 return map_nt_error_from_unix(errno);
389 /****************************************************************************
390 Read a list of EA names from an incoming data buffer. Create an ea_list with them.
391 ****************************************************************************/
393 static struct ea_list *read_ea_name_list(TALLOC_CTX *ctx, const char *pdata, size_t data_size)
395 struct ea_list *ea_list_head = NULL;
398 while (offset + 2 < data_size) {
400 struct ea_list *eal = TALLOC_ZERO_P(ctx, struct ea_list);
401 unsigned int namelen = CVAL(pdata,offset);
403 offset++; /* Go past the namelen byte. */
405 /* integer wrap paranioa. */
406 if ((offset + namelen < offset) || (offset + namelen < namelen) ||
407 (offset > data_size) || (namelen > data_size) ||
408 (offset + namelen >= data_size)) {
411 /* Ensure the name is null terminated. */
412 if (pdata[offset + namelen] != '\0') {
415 pull_ascii_talloc(ctx, &eal->ea.name, &pdata[offset]);
420 offset += (namelen + 1); /* Go past the name + terminating zero. */
421 DLIST_ADD_END(ea_list_head, eal, tmp);
422 DEBUG(10,("read_ea_name_list: read ea name %s\n", eal->ea.name));
428 /****************************************************************************
429 Read one EA list entry from the buffer.
430 ****************************************************************************/
432 struct ea_list *read_ea_list_entry(TALLOC_CTX *ctx, const char *pdata, size_t data_size, size_t *pbytes_used)
434 struct ea_list *eal = TALLOC_ZERO_P(ctx, struct ea_list);
436 unsigned int namelen;
446 eal->ea.flags = CVAL(pdata,0);
447 namelen = CVAL(pdata,1);
448 val_len = SVAL(pdata,2);
450 if (4 + namelen + 1 + val_len > data_size) {
454 /* Ensure the name is null terminated. */
455 if (pdata[namelen + 4] != '\0') {
458 pull_ascii_talloc(ctx, &eal->ea.name, pdata + 4);
463 eal->ea.value = data_blob(NULL, (size_t)val_len + 1);
464 if (!eal->ea.value.data) {
468 memcpy(eal->ea.value.data, pdata + 4 + namelen + 1, val_len);
470 /* Ensure we're null terminated just in case we print the value. */
471 eal->ea.value.data[val_len] = '\0';
472 /* But don't count the null. */
473 eal->ea.value.length--;
476 *pbytes_used = 4 + namelen + 1 + val_len;
479 DEBUG(10,("read_ea_list_entry: read ea name %s\n", eal->ea.name));
480 dump_data(10, (const char *)eal->ea.value.data, eal->ea.value.length);
485 /****************************************************************************
486 Read a list of EA names and data from an incoming data buffer. Create an ea_list with them.
487 ****************************************************************************/
489 static struct ea_list *read_ea_list(TALLOC_CTX *ctx, const char *pdata, size_t data_size)
491 struct ea_list *ea_list_head = NULL;
493 size_t bytes_used = 0;
495 while (offset < data_size) {
497 struct ea_list *eal = read_ea_list_entry(ctx, pdata + offset, data_size - offset, &bytes_used);
503 DLIST_ADD_END(ea_list_head, eal, tmp);
504 offset += bytes_used;
510 /****************************************************************************
511 Count the total EA size needed.
512 ****************************************************************************/
514 static size_t ea_list_size(struct ea_list *ealist)
517 struct ea_list *listp;
520 for (listp = ealist; listp; listp = listp->next) {
521 push_ascii_fstring(dos_ea_name, listp->ea.name);
522 ret += 4 + strlen(dos_ea_name) + 1 + listp->ea.value.length;
524 /* Add on 4 for total length. */
532 /****************************************************************************
533 Return a union of EA's from a file list and a list of names.
534 The TALLOC context for the two lists *MUST* be identical as we steal
535 memory from one list to add to another. JRA.
536 ****************************************************************************/
538 static struct ea_list *ea_list_union(struct ea_list *name_list, struct ea_list *file_list, size_t *total_ea_len)
540 struct ea_list *nlistp, *flistp;
542 for (nlistp = name_list; nlistp; nlistp = nlistp->next) {
543 for (flistp = file_list; flistp; flistp = flistp->next) {
544 if (strequal(nlistp->ea.name, flistp->ea.name)) {
550 /* Copy the data from this entry. */
551 nlistp->ea.flags = flistp->ea.flags;
552 nlistp->ea.value = flistp->ea.value;
555 nlistp->ea.flags = 0;
556 ZERO_STRUCT(nlistp->ea.value);
560 *total_ea_len = ea_list_size(name_list);
564 /****************************************************************************
565 Send the required number of replies back.
566 We assume all fields other than the data fields are
567 set correctly for the type of call.
568 HACK ! Always assumes smb_setup field is zero.
569 ****************************************************************************/
571 int send_trans2_replies(char *outbuf,
579 /* As we are using a protocol > LANMAN1 then the max_send
580 variable must have been set in the sessetupX call.
581 This takes precedence over the max_xmit field in the
582 global struct. These different max_xmit variables should
583 be merged as this is now too confusing */
585 int data_to_send = datasize;
586 int params_to_send = paramsize;
590 int params_sent_thistime, data_sent_thistime, total_sent_thistime;
591 int alignment_offset = 1; /* JRA. This used to be 3. Set to 1 to make netmon parse ok. */
592 int data_alignment_offset = 0;
594 /* Initially set the wcnt area to be 10 - this is true for all trans2 replies */
596 set_message(outbuf,10,0,True);
598 /* Modify the data_to_send and datasize and set the error if
599 we're trying to send more than max_data_bytes. We still send
600 the part of the packet(s) that fit. Strange, but needed
603 if (max_data_bytes > 0 && datasize > max_data_bytes) {
604 DEBUG(5,("send_trans2_replies: max_data_bytes %d exceeded by data %d\n",
605 max_data_bytes, datasize ));
606 datasize = data_to_send = max_data_bytes;
607 error_packet_set(outbuf,ERRDOS,ERRbufferoverflow,STATUS_BUFFER_OVERFLOW,__LINE__,__FILE__);
610 /* If there genuinely are no parameters or data to send just send the empty packet */
612 if(params_to_send == 0 && data_to_send == 0) {
614 if (!send_smb(smbd_server_fd(),outbuf))
615 exit_server("send_trans2_replies: send_smb failed.");
619 /* When sending params and data ensure that both are nicely aligned */
620 /* Only do this alignment when there is also data to send - else
621 can cause NT redirector problems. */
623 if (((params_to_send % 4) != 0) && (data_to_send != 0))
624 data_alignment_offset = 4 - (params_to_send % 4);
626 /* Space is bufsize minus Netbios over TCP header minus SMB header */
627 /* The alignment_offset is to align the param bytes on an even byte
628 boundary. NT 4.0 Beta needs this to work correctly. */
630 useable_space = bufsize - ((smb_buf(outbuf)+ alignment_offset+data_alignment_offset) - outbuf);
632 /* useable_space can never be more than max_send minus the alignment offset. */
634 useable_space = MIN(useable_space, max_send - (alignment_offset+data_alignment_offset));
636 while (params_to_send || data_to_send) {
637 /* Calculate whether we will totally or partially fill this packet */
639 total_sent_thistime = params_to_send + data_to_send + alignment_offset + data_alignment_offset;
641 /* We can never send more than useable_space */
643 * Note that 'useable_space' does not include the alignment offsets,
644 * but we must include the alignment offsets in the calculation of
645 * the length of the data we send over the wire, as the alignment offsets
646 * are sent here. Fix from Marc_Jacobsen@hp.com.
649 total_sent_thistime = MIN(total_sent_thistime, useable_space+ alignment_offset + data_alignment_offset);
651 set_message(outbuf, 10, total_sent_thistime, True);
653 /* Set total params and data to be sent */
654 SSVAL(outbuf,smb_tprcnt,paramsize);
655 SSVAL(outbuf,smb_tdrcnt,datasize);
657 /* Calculate how many parameters and data we can fit into
658 * this packet. Parameters get precedence
661 params_sent_thistime = MIN(params_to_send,useable_space);
662 data_sent_thistime = useable_space - params_sent_thistime;
663 data_sent_thistime = MIN(data_sent_thistime,data_to_send);
665 SSVAL(outbuf,smb_prcnt, params_sent_thistime);
667 /* smb_proff is the offset from the start of the SMB header to the
668 parameter bytes, however the first 4 bytes of outbuf are
669 the Netbios over TCP header. Thus use smb_base() to subtract
670 them from the calculation */
672 SSVAL(outbuf,smb_proff,((smb_buf(outbuf)+alignment_offset) - smb_base(outbuf)));
674 if(params_sent_thistime == 0)
675 SSVAL(outbuf,smb_prdisp,0);
677 /* Absolute displacement of param bytes sent in this packet */
678 SSVAL(outbuf,smb_prdisp,pp - params);
680 SSVAL(outbuf,smb_drcnt, data_sent_thistime);
681 if(data_sent_thistime == 0) {
682 SSVAL(outbuf,smb_droff,0);
683 SSVAL(outbuf,smb_drdisp, 0);
685 /* The offset of the data bytes is the offset of the
686 parameter bytes plus the number of parameters being sent this time */
687 SSVAL(outbuf,smb_droff,((smb_buf(outbuf)+alignment_offset) -
688 smb_base(outbuf)) + params_sent_thistime + data_alignment_offset);
689 SSVAL(outbuf,smb_drdisp, pd - pdata);
692 /* Copy the param bytes into the packet */
694 if(params_sent_thistime)
695 memcpy((smb_buf(outbuf)+alignment_offset),pp,params_sent_thistime);
697 /* Copy in the data bytes */
698 if(data_sent_thistime)
699 memcpy(smb_buf(outbuf)+alignment_offset+params_sent_thistime+
700 data_alignment_offset,pd,data_sent_thistime);
702 DEBUG(9,("t2_rep: params_sent_thistime = %d, data_sent_thistime = %d, useable_space = %d\n",
703 params_sent_thistime, data_sent_thistime, useable_space));
704 DEBUG(9,("t2_rep: params_to_send = %d, data_to_send = %d, paramsize = %d, datasize = %d\n",
705 params_to_send, data_to_send, paramsize, datasize));
707 /* Send the packet */
709 if (!send_smb(smbd_server_fd(),outbuf))
710 exit_server("send_trans2_replies: send_smb failed.");
712 pp += params_sent_thistime;
713 pd += data_sent_thistime;
715 params_to_send -= params_sent_thistime;
716 data_to_send -= data_sent_thistime;
719 if(params_to_send < 0 || data_to_send < 0) {
720 DEBUG(0,("send_trans2_replies failed sanity check pts = %d, dts = %d\n!!!",
721 params_to_send, data_to_send));
729 /****************************************************************************
730 Reply to a TRANSACT2_OPEN.
731 ****************************************************************************/
733 static int call_trans2open(connection_struct *conn, char *inbuf, char *outbuf, int bufsize,
734 char **pparams, int total_params, char **ppdata, int total_data,
735 unsigned int max_data_bytes)
737 char *params = *pparams;
738 char *pdata = *ppdata;
743 BOOL return_additional_info;
754 SMB_STRUCT_STAT sbuf;
756 BOOL bad_path = False;
758 TALLOC_CTX *ctx = NULL;
759 struct ea_list *ea_list = NULL;
764 uint32 create_disposition;
765 uint32 create_options = 0;
768 * Ensure we have enough parameters to perform the operation.
771 if (total_params < 29) {
772 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
775 flags = SVAL(params, 0);
776 deny_mode = SVAL(params, 2);
777 open_attr = SVAL(params,6);
778 oplock_request = (flags & REQUEST_OPLOCK) ? EXCLUSIVE_OPLOCK : 0;
779 if (oplock_request) {
780 oplock_request |= (flags & REQUEST_BATCH_OPLOCK) ? BATCH_OPLOCK : 0;
784 return_additional_info = BITSETW(params,0);
785 open_sattr = SVAL(params, 4);
786 open_time = make_unix_date3(params+8);
788 open_ofun = SVAL(params,12);
789 open_size = IVAL(params,14);
793 return(ERROR_DOS(ERRSRV,ERRaccess));
796 srvstr_get_path(inbuf, fname, pname, sizeof(fname), -1, STR_TERMINATE, &status);
797 if (!NT_STATUS_IS_OK(status)) {
798 return ERROR_NT(status);
801 DEBUG(3,("call_trans2open %s deny_mode=0x%x attr=%d ofun=0x%x size=%d\n",
802 fname, (unsigned int)deny_mode, (unsigned int)open_attr,
803 (unsigned int)open_ofun, open_size));
805 /* XXXX we need to handle passed times, sattr and flags */
807 unix_convert(fname,conn,0,&bad_path,&sbuf);
809 return ERROR_NT(NT_STATUS_OBJECT_PATH_NOT_FOUND);
812 if (!check_name(fname,conn)) {
813 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRnoaccess);
816 if (!map_open_params_to_ntcreate(fname, deny_mode, open_ofun,
821 return ERROR_DOS(ERRDOS, ERRbadaccess);
824 /* Any data in this call is an EA list. */
825 if (total_data && (total_data != 4) && !lp_ea_support(SNUM(conn))) {
826 return ERROR_NT(NT_STATUS_EAS_NOT_SUPPORTED);
829 if (total_data != 4) {
830 if (total_data < 10) {
831 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
834 if (IVAL(pdata,0) > total_data) {
835 DEBUG(10,("call_trans2open: bad total data size (%u) > %u\n",
836 IVAL(pdata,0), (unsigned int)total_data));
837 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
840 ctx = talloc_init("TRANS2_OPEN_SET_EA");
842 return ERROR_NT(NT_STATUS_NO_MEMORY);
844 ea_list = read_ea_list(ctx, pdata + 4, total_data - 4);
847 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
849 } else if (IVAL(pdata,0) != 4) {
850 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
853 status = open_file_ntcreate(conn,fname,&sbuf,
862 if (!NT_STATUS_IS_OK(status)) {
864 if (open_was_deferred(SVAL(inbuf,smb_mid))) {
865 /* We have re-scheduled this call. */
868 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRnoaccess);
871 size = get_file_size(sbuf);
872 fattr = dos_mode(conn,fname,&sbuf);
873 mtime = sbuf.st_mtime;
877 close_file(fsp,ERROR_CLOSE);
878 return(ERROR_DOS(ERRDOS,ERRnoaccess));
881 /* Save the requested allocation size. */
882 /* Allocate space for the file if a size hint is supplied */
883 if ((smb_action == FILE_WAS_CREATED) || (smb_action == FILE_WAS_OVERWRITTEN)) {
884 SMB_BIG_UINT allocation_size = (SMB_BIG_UINT)open_size;
885 if (allocation_size && (allocation_size > (SMB_BIG_UINT)size)) {
886 fsp->initial_allocation_size = smb_roundup(fsp->conn, allocation_size);
887 if (fsp->is_directory) {
888 close_file(fsp,ERROR_CLOSE);
889 /* Can't set allocation size on a directory. */
890 return ERROR_NT(NT_STATUS_ACCESS_DENIED);
892 if (vfs_allocate_file_space(fsp, fsp->initial_allocation_size) == -1) {
893 close_file(fsp,ERROR_CLOSE);
894 return ERROR_NT(NT_STATUS_DISK_FULL);
897 /* Adjust size here to return the right size in the reply.
898 Windows does it this way. */
899 size = fsp->initial_allocation_size;
901 fsp->initial_allocation_size = smb_roundup(fsp->conn,(SMB_BIG_UINT)size);
905 if (total_data && smb_action == FILE_WAS_CREATED) {
906 status = set_ea(conn, fsp, fname, ea_list);
908 if (!NT_STATUS_IS_OK(status)) {
909 close_file(fsp,ERROR_CLOSE);
910 return ERROR_NT(status);
914 /* Realloc the size of parameters and data we will return */
915 *pparams = (char *)SMB_REALLOC(*pparams, 30);
916 if(*pparams == NULL ) {
917 return ERROR_NT(NT_STATUS_NO_MEMORY);
921 SSVAL(params,0,fsp->fnum);
922 SSVAL(params,2,open_attr);
923 srv_put_dos_date2(params,4, mtime);
924 SIVAL(params,8, (uint32)size);
925 SSVAL(params,12,deny_mode);
926 SSVAL(params,14,0); /* open_type - file or directory. */
927 SSVAL(params,16,0); /* open_state - only valid for IPC device. */
929 if (oplock_request && lp_fake_oplocks(SNUM(conn))) {
930 smb_action |= EXTENDED_OPLOCK_GRANTED;
933 SSVAL(params,18,smb_action);
936 * WARNING - this may need to be changed if SMB_INO_T <> 4 bytes.
938 SIVAL(params,20,inode);
939 SSVAL(params,24,0); /* Padding. */
941 uint32 ea_size = estimate_ea_size(conn, fsp, fname);
942 SIVAL(params, 26, ea_size);
944 SIVAL(params, 26, 0);
947 /* Send the required number of replies */
948 send_trans2_replies(outbuf, bufsize, params, 30, *ppdata, 0, max_data_bytes);
953 /*********************************************************
954 Routine to check if a given string matches exactly.
955 as a special case a mask of "." does NOT match. That
956 is required for correct wildcard semantics
957 Case can be significant or not.
958 **********************************************************/
960 static BOOL exact_match(char *str,char *mask, BOOL case_sig)
962 if (mask[0] == '.' && mask[1] == 0)
965 return strcmp(str,mask)==0;
966 if (StrCaseCmp(str,mask) != 0) {
969 if (ms_has_wild(str)) {
975 /****************************************************************************
976 Return the filetype for UNIX extensions.
977 ****************************************************************************/
979 static uint32 unix_filetype(mode_t mode)
982 return UNIX_TYPE_FILE;
983 else if(S_ISDIR(mode))
984 return UNIX_TYPE_DIR;
986 else if(S_ISLNK(mode))
987 return UNIX_TYPE_SYMLINK;
990 else if(S_ISCHR(mode))
991 return UNIX_TYPE_CHARDEV;
994 else if(S_ISBLK(mode))
995 return UNIX_TYPE_BLKDEV;
998 else if(S_ISFIFO(mode))
999 return UNIX_TYPE_FIFO;
1002 else if(S_ISSOCK(mode))
1003 return UNIX_TYPE_SOCKET;
1006 DEBUG(0,("unix_filetype: unknown filetype %u", (unsigned)mode));
1007 return UNIX_TYPE_UNKNOWN;
1010 /****************************************************************************
1011 Map wire perms onto standard UNIX permissions. Obey share restrictions.
1012 ****************************************************************************/
1014 static mode_t unix_perms_from_wire( connection_struct *conn, SMB_STRUCT_STAT *pst, uint32 perms)
1018 if (perms == SMB_MODE_NO_CHANGE)
1019 return pst->st_mode;
1021 ret |= ((perms & UNIX_X_OTH ) ? S_IXOTH : 0);
1022 ret |= ((perms & UNIX_W_OTH ) ? S_IWOTH : 0);
1023 ret |= ((perms & UNIX_R_OTH ) ? S_IROTH : 0);
1024 ret |= ((perms & UNIX_X_GRP ) ? S_IXGRP : 0);
1025 ret |= ((perms & UNIX_W_GRP ) ? S_IWGRP : 0);
1026 ret |= ((perms & UNIX_R_GRP ) ? S_IRGRP : 0);
1027 ret |= ((perms & UNIX_X_USR ) ? S_IXUSR : 0);
1028 ret |= ((perms & UNIX_W_USR ) ? S_IWUSR : 0);
1029 ret |= ((perms & UNIX_R_USR ) ? S_IRUSR : 0);
1031 ret |= ((perms & UNIX_STICKY ) ? S_ISVTX : 0);
1034 ret |= ((perms & UNIX_SET_GID ) ? S_ISGID : 0);
1037 ret |= ((perms & UNIX_SET_UID ) ? S_ISUID : 0);
1040 if (VALID_STAT(*pst) && S_ISDIR(pst->st_mode)) {
1041 ret &= lp_dir_mask(SNUM(conn));
1042 /* Add in force bits */
1043 ret |= lp_force_dir_mode(SNUM(conn));
1045 /* Apply mode mask */
1046 ret &= lp_create_mask(SNUM(conn));
1047 /* Add in force bits */
1048 ret |= lp_force_create_mode(SNUM(conn));
1054 /****************************************************************************
1055 Get a level dependent lanman2 dir entry.
1056 ****************************************************************************/
1058 static BOOL get_lanman2_dir_entry(connection_struct *conn,
1059 void *inbuf, char *outbuf,
1060 char *path_mask,uint32 dirtype,int info_level,
1061 int requires_resume_key,
1062 BOOL dont_descend,char **ppdata,
1063 char *base_data, int space_remaining,
1064 BOOL *out_of_space, BOOL *got_exact_match,
1065 int *last_entry_off, struct ea_list *name_list, TALLOC_CTX *ea_ctx)
1069 SMB_STRUCT_STAT sbuf;
1073 char *p, *q, *pdata = *ppdata;
1077 SMB_OFF_T file_size = 0;
1078 SMB_BIG_UINT allocation_size = 0;
1080 struct timespec mdate_ts, adate_ts, create_date_ts;
1081 time_t mdate = (time_t)0, adate = (time_t)0, create_date = (time_t)0;
1083 char *last_entry_ptr;
1085 uint32 nt_extmode; /* Used for NT connections instead of mode */
1086 BOOL needslash = ( conn->dirpath[strlen(conn->dirpath) -1] != '/');
1087 BOOL check_mangled_names = lp_manglednames(conn->params);
1090 *out_of_space = False;
1091 *got_exact_match = False;
1093 ZERO_STRUCT(mdate_ts);
1094 ZERO_STRUCT(adate_ts);
1095 ZERO_STRUCT(create_date_ts);
1100 p = strrchr_m(path_mask,'/');
1103 pstrcpy(mask,"*.*");
1107 pstrcpy(mask, path_mask);
1112 BOOL ms_dfs_link = False;
1114 /* Needed if we run out of space */
1115 long curr_dirpos = prev_dirpos = dptr_TellDir(conn->dirptr);
1116 dname = dptr_ReadDirName(conn->dirptr,&curr_dirpos,&sbuf);
1119 * Due to bugs in NT client redirectors we are not using
1120 * resume keys any more - set them to zero.
1121 * Check out the related comments in findfirst/findnext.
1127 DEBUG(8,("get_lanman2_dir_entry:readdir on dirptr 0x%lx now at offset %ld\n",
1128 (long)conn->dirptr,curr_dirpos));
1133 pstrcpy(fname,dname);
1135 if(!(got_match = *got_exact_match = exact_match(fname, mask, conn->case_sensitive)))
1136 got_match = mask_match(fname, mask, conn->case_sensitive);
1138 if(!got_match && check_mangled_names &&
1139 !mangle_is_8_3(fname, False, conn->params)) {
1142 * It turns out that NT matches wildcards against
1143 * both long *and* short names. This may explain some
1144 * of the wildcard wierdness from old DOS clients
1145 * that some people have been seeing.... JRA.
1149 pstrcpy( newname, fname);
1150 mangle_map( newname, True, False, conn->params);
1151 if(!(got_match = *got_exact_match = exact_match(newname, mask, conn->case_sensitive)))
1152 got_match = mask_match(newname, mask, conn->case_sensitive);
1156 BOOL isdots = (strequal(fname,"..") || strequal(fname,"."));
1157 if (dont_descend && !isdots)
1160 pstrcpy(pathreal,conn->dirpath);
1162 pstrcat(pathreal,"/");
1163 pstrcat(pathreal,dname);
1165 if (INFO_LEVEL_IS_UNIX(info_level)) {
1166 if (SMB_VFS_LSTAT(conn,pathreal,&sbuf) != 0) {
1167 DEBUG(5,("get_lanman2_dir_entry:Couldn't lstat [%s] (%s)\n",
1168 pathreal,strerror(errno)));
1171 } else if (!VALID_STAT(sbuf) && SMB_VFS_STAT(conn,pathreal,&sbuf) != 0) {
1173 /* Needed to show the msdfs symlinks as
1176 if(lp_host_msdfs() &&
1177 lp_msdfs_root(SNUM(conn)) &&
1178 ((ms_dfs_link = is_msdfs_link(NULL,conn, pathreal, NULL, NULL, &sbuf)) == True)) {
1180 DEBUG(5,("get_lanman2_dir_entry: Masquerading msdfs link %s as a directory\n", pathreal));
1181 sbuf.st_mode = (sbuf.st_mode & 0xFFF) | S_IFDIR;
1185 DEBUG(5,("get_lanman2_dir_entry:Couldn't stat [%s] (%s)\n",
1186 pathreal,strerror(errno)));
1192 mode = dos_mode_msdfs(conn,pathreal,&sbuf);
1194 mode = dos_mode(conn,pathreal,&sbuf);
1197 if (!dir_check_ftype(conn,mode,dirtype)) {
1198 DEBUG(5,("[%s] attribs didn't match %x\n",fname,dirtype));
1203 file_size = get_file_size(sbuf);
1204 allocation_size = get_allocation_size(conn,NULL,&sbuf);
1206 mdate_ts = get_mtimespec(&sbuf);
1207 adate_ts = get_atimespec(&sbuf);
1208 create_date_ts = get_create_timespec(&sbuf,lp_fake_dir_create_times(SNUM(conn)));
1210 if (lp_dos_filetime_resolution(SNUM(conn))) {
1211 dos_filetime_timespec(&create_date_ts);
1212 dos_filetime_timespec(&mdate_ts);
1213 dos_filetime_timespec(&adate_ts);
1216 create_date = convert_timespec_to_time_t(create_date_ts);
1217 mdate = convert_timespec_to_time_t(mdate_ts);
1218 adate = convert_timespec_to_time_t(adate_ts);
1220 DEBUG(5,("get_lanman2_dir_entry found %s fname=%s\n",pathreal,fname));
1224 dptr_DirCacheAdd(conn->dirptr, dname, curr_dirpos);
1228 mangle_map(fname,False,True,conn->params);
1233 nt_extmode = mode ? mode : FILE_ATTRIBUTE_NORMAL;
1235 switch (info_level) {
1236 case SMB_FIND_INFO_STANDARD:
1237 DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_INFO_STANDARD\n"));
1238 if(requires_resume_key) {
1242 srv_put_dos_date2(p,0,create_date);
1243 srv_put_dos_date2(p,4,adate);
1244 srv_put_dos_date2(p,8,mdate);
1245 SIVAL(p,12,(uint32)file_size);
1246 SIVAL(p,16,(uint32)allocation_size);
1250 p += align_string(outbuf, p, 0);
1251 len = srvstr_push(outbuf, p, fname, -1, STR_TERMINATE);
1252 if (SVAL(outbuf, smb_flg2) & FLAGS2_UNICODE_STRINGS) {
1254 SCVAL(nameptr, -1, len - 2);
1256 SCVAL(nameptr, -1, 0);
1260 SCVAL(nameptr, -1, len - 1);
1262 SCVAL(nameptr, -1, 0);
1268 case SMB_FIND_EA_SIZE:
1269 DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_EA_SIZE\n"));
1270 if(requires_resume_key) {
1274 srv_put_dos_date2(p,0,create_date);
1275 srv_put_dos_date2(p,4,adate);
1276 srv_put_dos_date2(p,8,mdate);
1277 SIVAL(p,12,(uint32)file_size);
1278 SIVAL(p,16,(uint32)allocation_size);
1281 unsigned int ea_size = estimate_ea_size(conn, NULL, pathreal);
1282 SIVAL(p,22,ea_size); /* Extended attributes */
1286 len = srvstr_push(outbuf, p, fname, -1, STR_TERMINATE | STR_NOALIGN);
1287 if (SVAL(outbuf, smb_flg2) & FLAGS2_UNICODE_STRINGS) {
1300 SCVAL(nameptr,0,len);
1302 SCVAL(p,0,0); p += 1; /* Extra zero byte ? - why.. */
1305 case SMB_FIND_EA_LIST:
1307 struct ea_list *file_list = NULL;
1310 DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_EA_LIST\n"));
1314 if(requires_resume_key) {
1318 srv_put_dos_date2(p,0,create_date);
1319 srv_put_dos_date2(p,4,adate);
1320 srv_put_dos_date2(p,8,mdate);
1321 SIVAL(p,12,(uint32)file_size);
1322 SIVAL(p,16,(uint32)allocation_size);
1324 p += 22; /* p now points to the EA area. */
1326 file_list = get_ea_list_from_file(ea_ctx, conn, NULL, pathreal, &ea_len);
1327 name_list = ea_list_union(name_list, file_list, &ea_len);
1329 /* We need to determine if this entry will fit in the space available. */
1330 /* Max string size is 255 bytes. */
1331 if (PTR_DIFF(p + 255 + ea_len,pdata) > space_remaining) {
1332 /* Move the dirptr back to prev_dirpos */
1333 dptr_SeekDir(conn->dirptr, prev_dirpos);
1334 *out_of_space = True;
1335 DEBUG(9,("get_lanman2_dir_entry: out of space\n"));
1336 return False; /* Not finished - just out of space */
1339 /* Push the ea_data followed by the name. */
1340 p += fill_ea_buffer(ea_ctx, p, space_remaining, conn, name_list);
1342 len = srvstr_push(outbuf, p + 1, fname, -1, STR_TERMINATE | STR_NOALIGN);
1343 if (SVAL(outbuf, smb_flg2) & FLAGS2_UNICODE_STRINGS) {
1356 SCVAL(nameptr,0,len);
1358 SCVAL(p,0,0); p += 1; /* Extra zero byte ? - why.. */
1362 case SMB_FIND_FILE_BOTH_DIRECTORY_INFO:
1363 DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_FILE_BOTH_DIRECTORY_INFO\n"));
1364 was_8_3 = mangle_is_8_3(fname, True, conn->params);
1366 SIVAL(p,0,reskey); p += 4;
1367 put_long_date_timespec(p,create_date_ts); p += 8;
1368 put_long_date_timespec(p,adate_ts); p += 8;
1369 put_long_date_timespec(p,mdate_ts); p += 8;
1370 put_long_date_timespec(p,mdate_ts); p += 8;
1371 SOFF_T(p,0,file_size); p += 8;
1372 SOFF_T(p,0,allocation_size); p += 8;
1373 SIVAL(p,0,nt_extmode); p += 4;
1374 q = p; p += 4; /* q is placeholder for name length. */
1376 unsigned int ea_size = estimate_ea_size(conn, NULL, pathreal);
1377 SIVAL(p,0,ea_size); /* Extended attributes */
1380 /* Clear the short name buffer. This is
1381 * IMPORTANT as not doing so will trigger
1382 * a Win2k client bug. JRA.
1384 if (!was_8_3 && check_mangled_names) {
1385 pstring mangled_name;
1386 pstrcpy(mangled_name, fname);
1387 mangle_map(mangled_name,True,True,
1389 mangled_name[12] = 0;
1390 len = srvstr_push(outbuf, p+2, mangled_name, 24, STR_UPPER|STR_UNICODE);
1392 memset(p + 2 + len,'\0',24 - len);
1399 len = srvstr_push(outbuf, p, fname, -1, STR_TERMINATE_ASCII);
1402 SIVAL(p,0,0); /* Ensure any padding is null. */
1403 len = PTR_DIFF(p, pdata);
1404 len = (len + 3) & ~3;
1409 case SMB_FIND_FILE_DIRECTORY_INFO:
1410 DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_FILE_DIRECTORY_INFO\n"));
1412 SIVAL(p,0,reskey); p += 4;
1413 put_long_date_timespec(p,create_date_ts); p += 8;
1414 put_long_date_timespec(p,adate_ts); p += 8;
1415 put_long_date_timespec(p,mdate_ts); p += 8;
1416 put_long_date_timespec(p,mdate_ts); p += 8;
1417 SOFF_T(p,0,file_size); p += 8;
1418 SOFF_T(p,0,allocation_size); p += 8;
1419 SIVAL(p,0,nt_extmode); p += 4;
1420 len = srvstr_push(outbuf, p + 4, fname, -1, STR_TERMINATE_ASCII);
1423 SIVAL(p,0,0); /* Ensure any padding is null. */
1424 len = PTR_DIFF(p, pdata);
1425 len = (len + 3) & ~3;
1430 case SMB_FIND_FILE_FULL_DIRECTORY_INFO:
1431 DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_FILE_FULL_DIRECTORY_INFO\n"));
1433 SIVAL(p,0,reskey); p += 4;
1434 put_long_date_timespec(p,create_date_ts); p += 8;
1435 put_long_date_timespec(p,adate_ts); p += 8;
1436 put_long_date_timespec(p,mdate_ts); p += 8;
1437 put_long_date_timespec(p,mdate_ts); p += 8;
1438 SOFF_T(p,0,file_size); p += 8;
1439 SOFF_T(p,0,allocation_size); p += 8;
1440 SIVAL(p,0,nt_extmode); p += 4;
1441 q = p; p += 4; /* q is placeholder for name length. */
1443 unsigned int ea_size = estimate_ea_size(conn, NULL, pathreal);
1444 SIVAL(p,0,ea_size); /* Extended attributes */
1447 len = srvstr_push(outbuf, p, fname, -1, STR_TERMINATE_ASCII);
1451 SIVAL(p,0,0); /* Ensure any padding is null. */
1452 len = PTR_DIFF(p, pdata);
1453 len = (len + 3) & ~3;
1458 case SMB_FIND_FILE_NAMES_INFO:
1459 DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_FILE_NAMES_INFO\n"));
1461 SIVAL(p,0,reskey); p += 4;
1463 /* this must *not* be null terminated or w2k gets in a loop trying to set an
1464 acl on a dir (tridge) */
1465 len = srvstr_push(outbuf, p, fname, -1, STR_TERMINATE_ASCII);
1468 SIVAL(p,0,0); /* Ensure any padding is null. */
1469 len = PTR_DIFF(p, pdata);
1470 len = (len + 3) & ~3;
1475 case SMB_FIND_ID_FULL_DIRECTORY_INFO:
1476 DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_ID_FULL_DIRECTORY_INFO\n"));
1478 SIVAL(p,0,reskey); p += 4;
1479 put_long_date_timespec(p,create_date_ts); p += 8;
1480 put_long_date_timespec(p,adate_ts); p += 8;
1481 put_long_date_timespec(p,mdate_ts); p += 8;
1482 put_long_date_timespec(p,mdate_ts); p += 8;
1483 SOFF_T(p,0,file_size); p += 8;
1484 SOFF_T(p,0,allocation_size); p += 8;
1485 SIVAL(p,0,nt_extmode); p += 4;
1486 q = p; p += 4; /* q is placeholder for name length. */
1488 unsigned int ea_size = estimate_ea_size(conn, NULL, pathreal);
1489 SIVAL(p,0,ea_size); /* Extended attributes */
1492 SIVAL(p,0,0); p += 4; /* Unknown - reserved ? */
1493 SIVAL(p,0,sbuf.st_ino); p += 4; /* FileIndexLow */
1494 SIVAL(p,0,sbuf.st_dev); p += 4; /* FileIndexHigh */
1495 len = srvstr_push(outbuf, p, fname, -1, STR_TERMINATE_ASCII);
1498 SIVAL(p,0,0); /* Ensure any padding is null. */
1499 len = PTR_DIFF(p, pdata);
1500 len = (len + 3) & ~3;
1505 case SMB_FIND_ID_BOTH_DIRECTORY_INFO:
1506 DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_ID_BOTH_DIRECTORY_INFO\n"));
1507 was_8_3 = mangle_is_8_3(fname, True, conn->params);
1509 SIVAL(p,0,reskey); p += 4;
1510 put_long_date_timespec(p,create_date_ts); p += 8;
1511 put_long_date_timespec(p,adate_ts); p += 8;
1512 put_long_date_timespec(p,mdate_ts); p += 8;
1513 put_long_date_timespec(p,mdate_ts); p += 8;
1514 SOFF_T(p,0,file_size); p += 8;
1515 SOFF_T(p,0,allocation_size); p += 8;
1516 SIVAL(p,0,nt_extmode); p += 4;
1517 q = p; p += 4; /* q is placeholder for name length */
1519 unsigned int ea_size = estimate_ea_size(conn, NULL, pathreal);
1520 SIVAL(p,0,ea_size); /* Extended attributes */
1523 /* Clear the short name buffer. This is
1524 * IMPORTANT as not doing so will trigger
1525 * a Win2k client bug. JRA.
1527 if (!was_8_3 && check_mangled_names) {
1528 pstring mangled_name;
1529 pstrcpy(mangled_name, fname);
1530 mangle_map(mangled_name,True,True,
1532 mangled_name[12] = 0;
1533 len = srvstr_push(outbuf, p+2, mangled_name, 24, STR_UPPER|STR_UNICODE);
1536 memset(p + 2 + len,'\0',24 - len);
1543 SSVAL(p,0,0); p += 2; /* Reserved ? */
1544 SIVAL(p,0,sbuf.st_ino); p += 4; /* FileIndexLow */
1545 SIVAL(p,0,sbuf.st_dev); p += 4; /* FileIndexHigh */
1546 len = srvstr_push(outbuf, p, fname, -1, STR_TERMINATE_ASCII);
1549 SIVAL(p,0,0); /* Ensure any padding is null. */
1550 len = PTR_DIFF(p, pdata);
1551 len = (len + 3) & ~3;
1556 /* CIFS UNIX Extension. */
1558 case SMB_FIND_FILE_UNIX:
1559 DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_FILE_UNIX\n"));
1561 SIVAL(p,0,reskey); p+= 4; /* Used for continuing search. */
1563 /* Begin of SMB_QUERY_FILE_UNIX_BASIC */
1564 SOFF_T(p,0,get_file_size(sbuf)); /* File size 64 Bit */
1567 SOFF_T(p,0,get_allocation_size(conn,NULL,&sbuf)); /* Number of bytes used on disk - 64 Bit */
1570 put_long_date_timespec(p,get_ctimespec(&sbuf)); /* Inode change Time 64 Bit */
1571 put_long_date_timespec(p+8,get_atimespec(&sbuf)); /* Last access time 64 Bit */
1572 put_long_date_timespec(p+16,get_mtimespec(&sbuf)); /* Last modification time 64 Bit */
1575 SIVAL(p,0,sbuf.st_uid); /* user id for the owner */
1579 SIVAL(p,0,sbuf.st_gid); /* group id of owner */
1583 SIVAL(p,0,unix_filetype(sbuf.st_mode));
1586 SIVAL(p,0,unix_dev_major(sbuf.st_rdev)); /* Major device number if type is device */
1590 SIVAL(p,0,unix_dev_minor(sbuf.st_rdev)); /* Minor device number if type is device */
1594 SINO_T_VAL(p,0,(SMB_INO_T)sbuf.st_ino); /* inode number */
1597 SIVAL(p,0, unix_perms_to_wire(sbuf.st_mode)); /* Standard UNIX file permissions */
1601 SIVAL(p,0,sbuf.st_nlink); /* number of hard links */
1605 len = srvstr_push(outbuf, p, fname, -1, STR_TERMINATE);
1607 SIVAL(p,0,0); /* Ensure any padding is null. */
1609 len = PTR_DIFF(p, pdata);
1610 len = (len + 3) & ~3;
1611 SIVAL(pdata,0,len); /* Offset from this structure to the beginning of the next one */
1613 /* End of SMB_QUERY_FILE_UNIX_BASIC */
1622 if (PTR_DIFF(p,pdata) > space_remaining) {
1623 /* Move the dirptr back to prev_dirpos */
1624 dptr_SeekDir(conn->dirptr, prev_dirpos);
1625 *out_of_space = True;
1626 DEBUG(9,("get_lanman2_dir_entry: out of space\n"));
1627 return False; /* Not finished - just out of space */
1630 /* Setup the last entry pointer, as an offset from base_data */
1631 *last_entry_off = PTR_DIFF(last_entry_ptr,base_data);
1632 /* Advance the data pointer to the next slot */
1638 /****************************************************************************
1639 Reply to a TRANS2_FINDFIRST.
1640 ****************************************************************************/
1642 static int call_trans2findfirst(connection_struct *conn, char *inbuf, char *outbuf, int bufsize,
1643 char **pparams, int total_params, char **ppdata, int total_data,
1644 unsigned int max_data_bytes)
1646 /* We must be careful here that we don't return more than the
1647 allowed number of data bytes. If this means returning fewer than
1648 maxentries then so be it. We assume that the redirector has
1649 enough room for the fixed number of parameter bytes it has
1651 char *params = *pparams;
1652 char *pdata = *ppdata;
1653 uint32 dirtype = SVAL(params,0);
1654 int maxentries = SVAL(params,2);
1655 uint16 findfirst_flags = SVAL(params,4);
1656 BOOL close_after_first = (findfirst_flags & FLAG_TRANS2_FIND_CLOSE);
1657 BOOL close_if_end = (findfirst_flags & FLAG_TRANS2_FIND_CLOSE_IF_END);
1658 BOOL requires_resume_key = (findfirst_flags & FLAG_TRANS2_FIND_REQUIRE_RESUME);
1659 int info_level = SVAL(params,6);
1663 int last_entry_off=0;
1667 BOOL finished = False;
1668 BOOL dont_descend = False;
1669 BOOL out_of_space = False;
1670 int space_remaining;
1671 BOOL bad_path = False;
1672 BOOL mask_contains_wcard = False;
1673 SMB_STRUCT_STAT sbuf;
1674 TALLOC_CTX *ea_ctx = NULL;
1675 struct ea_list *ea_list = NULL;
1676 NTSTATUS ntstatus = NT_STATUS_OK;
1678 if (total_params < 12) {
1679 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
1682 *directory = *mask = 0;
1684 DEBUG(3,("call_trans2findfirst: dirtype = %x, maxentries = %d, close_after_first=%d, \
1685 close_if_end = %d requires_resume_key = %d level = 0x%x, max_data_bytes = %d\n",
1686 (unsigned int)dirtype, maxentries, close_after_first, close_if_end, requires_resume_key,
1687 info_level, max_data_bytes));
1690 /* W2K3 seems to treat zero as 1. */
1694 switch (info_level) {
1695 case SMB_FIND_INFO_STANDARD:
1696 case SMB_FIND_EA_SIZE:
1697 case SMB_FIND_EA_LIST:
1698 case SMB_FIND_FILE_DIRECTORY_INFO:
1699 case SMB_FIND_FILE_FULL_DIRECTORY_INFO:
1700 case SMB_FIND_FILE_NAMES_INFO:
1701 case SMB_FIND_FILE_BOTH_DIRECTORY_INFO:
1702 case SMB_FIND_ID_FULL_DIRECTORY_INFO:
1703 case SMB_FIND_ID_BOTH_DIRECTORY_INFO:
1705 case SMB_FIND_FILE_UNIX:
1706 if (!lp_unix_extensions()) {
1707 return ERROR_NT(NT_STATUS_INVALID_LEVEL);
1711 return ERROR_NT(NT_STATUS_INVALID_LEVEL);
1714 srvstr_get_path_wcard(inbuf, directory, params+12, sizeof(directory), -1, STR_TERMINATE, &ntstatus, &mask_contains_wcard);
1715 if (!NT_STATUS_IS_OK(ntstatus)) {
1716 return ERROR_NT(ntstatus);
1719 RESOLVE_DFSPATH_WCARD(directory, conn, inbuf, outbuf);
1721 unix_convert(directory,conn,0,&bad_path,&sbuf);
1723 return ERROR_NT(NT_STATUS_OBJECT_PATH_NOT_FOUND);
1725 if(!check_name(directory,conn)) {
1726 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRbadpath);
1729 p = strrchr_m(directory,'/');
1731 /* Windows and OS/2 systems treat search on the root '\' as if it were '\*' */
1732 if((directory[0] == '.') && (directory[1] == '\0')) {
1734 mask_contains_wcard = True;
1736 pstrcpy(mask,directory);
1738 pstrcpy(directory,"./");
1744 DEBUG(5,("dir=%s, mask = %s\n",directory, mask));
1746 if (info_level == SMB_FIND_EA_LIST) {
1749 if (total_data < 4) {
1750 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
1753 ea_size = IVAL(pdata,0);
1754 if (ea_size != total_data) {
1755 DEBUG(4,("call_trans2findfirst: Rejecting EA request with incorrect \
1756 total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pdata,0) ));
1757 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
1760 if (!lp_ea_support(SNUM(conn))) {
1761 return ERROR_DOS(ERRDOS,ERReasnotsupported);
1764 if ((ea_ctx = talloc_init("findnext_ea_list")) == NULL) {
1765 return ERROR_NT(NT_STATUS_NO_MEMORY);
1768 /* Pull out the list of names. */
1769 ea_list = read_ea_name_list(ea_ctx, pdata + 4, ea_size - 4);
1771 talloc_destroy(ea_ctx);
1772 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
1776 *ppdata = (char *)SMB_REALLOC(
1777 *ppdata, max_data_bytes + DIR_ENTRY_SAFETY_MARGIN);
1778 if(*ppdata == NULL ) {
1779 talloc_destroy(ea_ctx);
1780 return ERROR_NT(NT_STATUS_NO_MEMORY);
1784 /* Realloc the params space */
1785 *pparams = (char *)SMB_REALLOC(*pparams, 10);
1786 if (*pparams == NULL) {
1787 talloc_destroy(ea_ctx);
1788 return ERROR_NT(NT_STATUS_NO_MEMORY);
1792 /* Save the wildcard match and attribs we are using on this directory -
1793 needed as lanman2 assumes these are being saved between calls */
1795 dptr_num = dptr_create(conn,directory, False, True ,SVAL(inbuf,smb_pid), mask, mask_contains_wcard, dirtype);
1797 talloc_destroy(ea_ctx);
1798 return(UNIXERROR(ERRDOS,ERRbadfile));
1801 DEBUG(4,("dptr_num is %d, wcard = %s, attr = %d\n",dptr_num, mask, dirtype));
1803 /* We don't need to check for VOL here as this is returned by
1804 a different TRANS2 call. */
1806 DEBUG(8,("dirpath=<%s> dontdescend=<%s>\n", conn->dirpath,lp_dontdescend(SNUM(conn))));
1807 if (in_list(conn->dirpath,lp_dontdescend(SNUM(conn)),conn->case_sensitive))
1808 dont_descend = True;
1811 space_remaining = max_data_bytes;
1812 out_of_space = False;
1814 for (i=0;(i<maxentries) && !finished && !out_of_space;i++) {
1815 BOOL got_exact_match = False;
1817 /* this is a heuristic to avoid seeking the dirptr except when
1818 absolutely necessary. It allows for a filename of about 40 chars */
1819 if (space_remaining < DIRLEN_GUESS && numentries > 0) {
1820 out_of_space = True;
1823 finished = !get_lanman2_dir_entry(conn,
1825 mask,dirtype,info_level,
1826 requires_resume_key,dont_descend,
1827 &p,pdata,space_remaining, &out_of_space, &got_exact_match,
1828 &last_entry_off, ea_list, ea_ctx);
1831 if (finished && out_of_space)
1834 if (!finished && !out_of_space)
1838 * As an optimisation if we know we aren't looking
1839 * for a wildcard name (ie. the name matches the wildcard exactly)
1840 * then we can finish on any (first) match.
1841 * This speeds up large directory searches. JRA.
1847 space_remaining = max_data_bytes - PTR_DIFF(p,pdata);
1850 talloc_destroy(ea_ctx);
1852 /* Check if we can close the dirptr */
1853 if(close_after_first || (finished && close_if_end)) {
1854 DEBUG(5,("call_trans2findfirst - (2) closing dptr_num %d\n", dptr_num));
1855 dptr_close(&dptr_num);
1859 * If there are no matching entries we must return ERRDOS/ERRbadfile -
1860 * from observation of NT. NB. This changes to ERRDOS,ERRnofiles if
1861 * the protocol level is less than NT1. Tested with smbclient. JRA.
1862 * This should fix the OS/2 client bug #2335.
1865 if(numentries == 0) {
1866 dptr_close(&dptr_num);
1867 if (Protocol < PROTOCOL_NT1) {
1868 return ERROR_DOS(ERRDOS,ERRnofiles);
1870 return ERROR_BOTH(NT_STATUS_NO_SUCH_FILE,ERRDOS,ERRbadfile);
1874 /* At this point pdata points to numentries directory entries. */
1876 /* Set up the return parameter block */
1877 SSVAL(params,0,dptr_num);
1878 SSVAL(params,2,numentries);
1879 SSVAL(params,4,finished);
1880 SSVAL(params,6,0); /* Never an EA error */
1881 SSVAL(params,8,last_entry_off);
1883 send_trans2_replies( outbuf, bufsize, params, 10, pdata, PTR_DIFF(p,pdata), max_data_bytes);
1885 if ((! *directory) && dptr_path(dptr_num))
1886 slprintf(directory,sizeof(directory)-1, "(%s)",dptr_path(dptr_num));
1888 DEBUG( 4, ( "%s mask=%s directory=%s dirtype=%d numentries=%d\n",
1889 smb_fn_name(CVAL(inbuf,smb_com)),
1890 mask, directory, dirtype, numentries ) );
1893 * Force a name mangle here to ensure that the
1894 * mask as an 8.3 name is top of the mangled cache.
1895 * The reasons for this are subtle. Don't remove
1896 * this code unless you know what you are doing
1897 * (see PR#13758). JRA.
1900 if(!mangle_is_8_3_wildcards( mask, False, conn->params))
1901 mangle_map(mask, True, True, conn->params);
1906 /****************************************************************************
1907 Reply to a TRANS2_FINDNEXT.
1908 ****************************************************************************/
1910 static int call_trans2findnext(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize,
1911 char **pparams, int total_params, char **ppdata, int total_data,
1912 unsigned int max_data_bytes)
1914 /* We must be careful here that we don't return more than the
1915 allowed number of data bytes. If this means returning fewer than
1916 maxentries then so be it. We assume that the redirector has
1917 enough room for the fixed number of parameter bytes it has
1919 char *params = *pparams;
1920 char *pdata = *ppdata;
1921 int dptr_num = SVAL(params,0);
1922 int maxentries = SVAL(params,2);
1923 uint16 info_level = SVAL(params,4);
1924 uint32 resume_key = IVAL(params,6);
1925 uint16 findnext_flags = SVAL(params,10);
1926 BOOL close_after_request = (findnext_flags & FLAG_TRANS2_FIND_CLOSE);
1927 BOOL close_if_end = (findnext_flags & FLAG_TRANS2_FIND_CLOSE_IF_END);
1928 BOOL requires_resume_key = (findnext_flags & FLAG_TRANS2_FIND_REQUIRE_RESUME);
1929 BOOL continue_bit = (findnext_flags & FLAG_TRANS2_FIND_CONTINUE);
1930 BOOL mask_contains_wcard = False;
1931 pstring resume_name;
1937 int i, last_entry_off=0;
1938 BOOL finished = False;
1939 BOOL dont_descend = False;
1940 BOOL out_of_space = False;
1941 int space_remaining;
1942 TALLOC_CTX *ea_ctx = NULL;
1943 struct ea_list *ea_list = NULL;
1944 NTSTATUS ntstatus = NT_STATUS_OK;
1946 if (total_params < 12) {
1947 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
1950 *mask = *directory = *resume_name = 0;
1952 srvstr_get_path_wcard(inbuf, resume_name, params+12, sizeof(resume_name), -1, STR_TERMINATE, &ntstatus, &mask_contains_wcard);
1953 if (!NT_STATUS_IS_OK(ntstatus)) {
1954 /* Win9x or OS/2 can send a resume name of ".." or ".". This will cause the parser to
1955 complain (it thinks we're asking for the directory above the shared
1956 path or an invalid name). Catch this as the resume name is only compared, never used in
1957 a file access. JRA. */
1958 if (NT_STATUS_EQUAL(ntstatus,NT_STATUS_OBJECT_PATH_SYNTAX_BAD)) {
1959 pstrcpy(resume_name, "..");
1960 } else if (NT_STATUS_EQUAL(ntstatus,NT_STATUS_OBJECT_NAME_INVALID)) {
1961 pstrcpy(resume_name, ".");
1963 return ERROR_NT(ntstatus);
1967 DEBUG(3,("call_trans2findnext: dirhandle = %d, max_data_bytes = %d, maxentries = %d, \
1968 close_after_request=%d, close_if_end = %d requires_resume_key = %d \
1969 resume_key = %d resume name = %s continue=%d level = %d\n",
1970 dptr_num, max_data_bytes, maxentries, close_after_request, close_if_end,
1971 requires_resume_key, resume_key, resume_name, continue_bit, info_level));
1974 /* W2K3 seems to treat zero as 1. */
1978 switch (info_level) {
1979 case SMB_FIND_INFO_STANDARD:
1980 case SMB_FIND_EA_SIZE:
1981 case SMB_FIND_EA_LIST:
1982 case SMB_FIND_FILE_DIRECTORY_INFO:
1983 case SMB_FIND_FILE_FULL_DIRECTORY_INFO:
1984 case SMB_FIND_FILE_NAMES_INFO:
1985 case SMB_FIND_FILE_BOTH_DIRECTORY_INFO:
1986 case SMB_FIND_ID_FULL_DIRECTORY_INFO:
1987 case SMB_FIND_ID_BOTH_DIRECTORY_INFO:
1989 case SMB_FIND_FILE_UNIX:
1990 if (!lp_unix_extensions()) {
1991 return ERROR_NT(NT_STATUS_INVALID_LEVEL);
1995 return ERROR_NT(NT_STATUS_INVALID_LEVEL);
1998 if (info_level == SMB_FIND_EA_LIST) {
2001 if (total_data < 4) {
2002 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
2005 ea_size = IVAL(pdata,0);
2006 if (ea_size != total_data) {
2007 DEBUG(4,("call_trans2findnext: Rejecting EA request with incorrect \
2008 total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pdata,0) ));
2009 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
2012 if (!lp_ea_support(SNUM(conn))) {
2013 return ERROR_DOS(ERRDOS,ERReasnotsupported);
2016 if ((ea_ctx = talloc_init("findnext_ea_list")) == NULL) {
2017 return ERROR_NT(NT_STATUS_NO_MEMORY);
2020 /* Pull out the list of names. */
2021 ea_list = read_ea_name_list(ea_ctx, pdata + 4, ea_size - 4);
2023 talloc_destroy(ea_ctx);
2024 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
2028 *ppdata = (char *)SMB_REALLOC(
2029 *ppdata, max_data_bytes + DIR_ENTRY_SAFETY_MARGIN);
2030 if(*ppdata == NULL) {
2031 talloc_destroy(ea_ctx);
2032 return ERROR_NT(NT_STATUS_NO_MEMORY);
2037 /* Realloc the params space */
2038 *pparams = (char *)SMB_REALLOC(*pparams, 6*SIZEOFWORD);
2039 if(*pparams == NULL ) {
2040 talloc_destroy(ea_ctx);
2041 return ERROR_NT(NT_STATUS_NO_MEMORY);
2046 /* Check that the dptr is valid */
2047 if(!(conn->dirptr = dptr_fetch_lanman2(dptr_num))) {
2048 talloc_destroy(ea_ctx);
2049 return ERROR_DOS(ERRDOS,ERRnofiles);
2052 string_set(&conn->dirpath,dptr_path(dptr_num));
2054 /* Get the wildcard mask from the dptr */
2055 if((p = dptr_wcard(dptr_num))== NULL) {
2056 DEBUG(2,("dptr_num %d has no wildcard\n", dptr_num));
2057 talloc_destroy(ea_ctx);
2058 return ERROR_DOS(ERRDOS,ERRnofiles);
2062 pstrcpy(directory,conn->dirpath);
2064 /* Get the attr mask from the dptr */
2065 dirtype = dptr_attr(dptr_num);
2067 DEBUG(3,("dptr_num is %d, mask = %s, attr = %x, dirptr=(0x%lX,%ld)\n",
2068 dptr_num, mask, dirtype,
2070 dptr_TellDir(conn->dirptr)));
2072 /* We don't need to check for VOL here as this is returned by
2073 a different TRANS2 call. */
2075 DEBUG(8,("dirpath=<%s> dontdescend=<%s>\n",conn->dirpath,lp_dontdescend(SNUM(conn))));
2076 if (in_list(conn->dirpath,lp_dontdescend(SNUM(conn)),conn->case_sensitive))
2077 dont_descend = True;
2080 space_remaining = max_data_bytes;
2081 out_of_space = False;
2084 * Seek to the correct position. We no longer use the resume key but
2085 * depend on the last file name instead.
2088 if(*resume_name && !continue_bit) {
2091 long current_pos = 0;
2093 * Remember, mangle_map is called by
2094 * get_lanman2_dir_entry(), so the resume name
2095 * could be mangled. Ensure we check the unmangled name.
2098 if (mangle_is_mangled(resume_name, conn->params)) {
2099 mangle_check_cache(resume_name, sizeof(resume_name)-1,
2104 * Fix for NT redirector problem triggered by resume key indexes
2105 * changing between directory scans. We now return a resume key of 0
2106 * and instead look for the filename to continue from (also given
2107 * to us by NT/95/smbfs/smbclient). If no other scans have been done between the
2108 * findfirst/findnext (as is usual) then the directory pointer
2109 * should already be at the correct place.
2112 finished = !dptr_SearchDir(conn->dirptr, resume_name, ¤t_pos, &st);
2113 } /* end if resume_name && !continue_bit */
2115 for (i=0;(i<(int)maxentries) && !finished && !out_of_space ;i++) {
2116 BOOL got_exact_match = False;
2118 /* this is a heuristic to avoid seeking the dirptr except when
2119 absolutely necessary. It allows for a filename of about 40 chars */
2120 if (space_remaining < DIRLEN_GUESS && numentries > 0) {
2121 out_of_space = True;
2124 finished = !get_lanman2_dir_entry(conn,
2126 mask,dirtype,info_level,
2127 requires_resume_key,dont_descend,
2128 &p,pdata,space_remaining, &out_of_space, &got_exact_match,
2129 &last_entry_off, ea_list, ea_ctx);
2132 if (finished && out_of_space)
2135 if (!finished && !out_of_space)
2139 * As an optimisation if we know we aren't looking
2140 * for a wildcard name (ie. the name matches the wildcard exactly)
2141 * then we can finish on any (first) match.
2142 * This speeds up large directory searches. JRA.
2148 space_remaining = max_data_bytes - PTR_DIFF(p,pdata);
2151 talloc_destroy(ea_ctx);
2153 /* Check if we can close the dirptr */
2154 if(close_after_request || (finished && close_if_end)) {
2155 DEBUG(5,("call_trans2findnext: closing dptr_num = %d\n", dptr_num));
2156 dptr_close(&dptr_num); /* This frees up the saved mask */
2159 /* Set up the return parameter block */
2160 SSVAL(params,0,numentries);
2161 SSVAL(params,2,finished);
2162 SSVAL(params,4,0); /* Never an EA error */
2163 SSVAL(params,6,last_entry_off);
2165 send_trans2_replies( outbuf, bufsize, params, 8, pdata, PTR_DIFF(p,pdata), max_data_bytes);
2167 if ((! *directory) && dptr_path(dptr_num))
2168 slprintf(directory,sizeof(directory)-1, "(%s)",dptr_path(dptr_num));
2170 DEBUG( 3, ( "%s mask=%s directory=%s dirtype=%d numentries=%d\n",
2171 smb_fn_name(CVAL(inbuf,smb_com)),
2172 mask, directory, dirtype, numentries ) );
2177 /****************************************************************************
2178 Reply to a TRANS2_QFSINFO (query filesystem info).
2179 ****************************************************************************/
2181 static int call_trans2qfsinfo(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize,
2182 char **pparams, int total_params, char **ppdata, int total_data,
2183 unsigned int max_data_bytes)
2185 char *pdata = *ppdata;
2186 char *params = *pparams;
2187 uint16 info_level = SVAL(params,0);
2190 char *vname = volume_label(SNUM(conn));
2191 int snum = SNUM(conn);
2192 char *fstype = lp_fstype(SNUM(conn));
2195 DEBUG(3,("call_trans2qfsinfo: level = %d\n", info_level));
2197 if(SMB_VFS_STAT(conn,".",&st)!=0) {
2198 DEBUG(2,("call_trans2qfsinfo: stat of . failed (%s)\n", strerror(errno)));
2199 return ERROR_DOS(ERRSRV,ERRinvdevice);
2202 *ppdata = (char *)SMB_REALLOC(
2203 *ppdata, max_data_bytes + DIR_ENTRY_SAFETY_MARGIN);
2204 if (*ppdata == NULL ) {
2205 return ERROR_NT(NT_STATUS_NO_MEMORY);
2209 memset((char *)pdata,'\0',max_data_bytes + DIR_ENTRY_SAFETY_MARGIN);
2211 switch (info_level) {
2212 case SMB_INFO_ALLOCATION:
2214 SMB_BIG_UINT dfree,dsize,bsize,block_size,sectors_per_unit,bytes_per_sector;
2216 if (get_dfree_info(conn,".",False,&bsize,&dfree,&dsize) == (SMB_BIG_UINT)-1) {
2217 return(UNIXERROR(ERRHRD,ERRgeneral));
2220 block_size = lp_block_size(snum);
2221 if (bsize < block_size) {
2222 SMB_BIG_UINT factor = block_size/bsize;
2227 if (bsize > block_size) {
2228 SMB_BIG_UINT factor = bsize/block_size;
2233 bytes_per_sector = 512;
2234 sectors_per_unit = bsize/bytes_per_sector;
2236 DEBUG(5,("call_trans2qfsinfo : SMB_INFO_ALLOCATION id=%x, bsize=%u, cSectorUnit=%u, \
2237 cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)st.st_dev, (unsigned int)bsize, (unsigned int)sectors_per_unit,
2238 (unsigned int)bytes_per_sector, (unsigned int)dsize, (unsigned int)dfree));
2240 SIVAL(pdata,l1_idFileSystem,st.st_dev);
2241 SIVAL(pdata,l1_cSectorUnit,sectors_per_unit);
2242 SIVAL(pdata,l1_cUnit,dsize);
2243 SIVAL(pdata,l1_cUnitAvail,dfree);
2244 SSVAL(pdata,l1_cbSector,bytes_per_sector);
2248 case SMB_INFO_VOLUME:
2249 /* Return volume name */
2251 * Add volume serial number - hash of a combination of
2252 * the called hostname and the service name.
2254 SIVAL(pdata,0,str_checksum(lp_servicename(snum)) ^ (str_checksum(get_local_machine_name())<<16) );
2256 * Win2k3 and previous mess this up by sending a name length
2257 * one byte short. I believe only older clients (OS/2 Win9x) use
2258 * this call so try fixing this by adding a terminating null to
2259 * the pushed string. The change here was adding the STR_TERMINATE. JRA.
2261 len = srvstr_push(outbuf, pdata+l2_vol_szVolLabel, vname, -1, STR_NOALIGN|STR_TERMINATE);
2262 SCVAL(pdata,l2_vol_cch,len);
2263 data_len = l2_vol_szVolLabel + len;
2264 DEBUG(5,("call_trans2qfsinfo : time = %x, namelen = %d, name = %s\n",
2265 (unsigned)st.st_ctime, len, vname));
2268 case SMB_QUERY_FS_ATTRIBUTE_INFO:
2269 case SMB_FS_ATTRIBUTE_INFORMATION:
2272 #if defined(HAVE_SYS_QUOTAS)
2273 quota_flag = FILE_VOLUME_QUOTAS;
2276 SIVAL(pdata,0,FILE_CASE_PRESERVED_NAMES|FILE_CASE_SENSITIVE_SEARCH|
2277 (lp_nt_acl_support(SNUM(conn)) ? FILE_PERSISTENT_ACLS : 0)|
2278 quota_flag); /* FS ATTRIBUTES */
2280 SIVAL(pdata,4,255); /* Max filename component length */
2281 /* NOTE! the fstype must *not* be null terminated or win98 won't recognise it
2282 and will think we can't do long filenames */
2283 len = srvstr_push(outbuf, pdata+12, fstype, -1, STR_UNICODE);
2285 data_len = 12 + len;
2288 case SMB_QUERY_FS_LABEL_INFO:
2289 case SMB_FS_LABEL_INFORMATION:
2290 len = srvstr_push(outbuf, pdata+4, vname, -1, 0);
2295 case SMB_QUERY_FS_VOLUME_INFO:
2296 case SMB_FS_VOLUME_INFORMATION:
2299 * Add volume serial number - hash of a combination of
2300 * the called hostname and the service name.
2302 SIVAL(pdata,8,str_checksum(lp_servicename(snum)) ^
2303 (str_checksum(get_local_machine_name())<<16));
2305 len = srvstr_push(outbuf, pdata+18, vname, -1, STR_UNICODE);
2306 SIVAL(pdata,12,len);
2308 DEBUG(5,("call_trans2qfsinfo : SMB_QUERY_FS_VOLUME_INFO namelen = %d, vol=%s serv=%s\n",
2309 (int)strlen(vname),vname, lp_servicename(snum)));
2312 case SMB_QUERY_FS_SIZE_INFO:
2313 case SMB_FS_SIZE_INFORMATION:
2315 SMB_BIG_UINT dfree,dsize,bsize,block_size,sectors_per_unit,bytes_per_sector;
2317 if (get_dfree_info(conn,".",False,&bsize,&dfree,&dsize) == (SMB_BIG_UINT)-1) {
2318 return(UNIXERROR(ERRHRD,ERRgeneral));
2320 block_size = lp_block_size(snum);
2321 if (bsize < block_size) {
2322 SMB_BIG_UINT factor = block_size/bsize;
2327 if (bsize > block_size) {
2328 SMB_BIG_UINT factor = bsize/block_size;
2333 bytes_per_sector = 512;
2334 sectors_per_unit = bsize/bytes_per_sector;
2335 DEBUG(5,("call_trans2qfsinfo : SMB_QUERY_FS_SIZE_INFO bsize=%u, cSectorUnit=%u, \
2336 cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize, (unsigned int)sectors_per_unit,
2337 (unsigned int)bytes_per_sector, (unsigned int)dsize, (unsigned int)dfree));
2338 SBIG_UINT(pdata,0,dsize);
2339 SBIG_UINT(pdata,8,dfree);
2340 SIVAL(pdata,16,sectors_per_unit);
2341 SIVAL(pdata,20,bytes_per_sector);
2345 case SMB_FS_FULL_SIZE_INFORMATION:
2347 SMB_BIG_UINT dfree,dsize,bsize,block_size,sectors_per_unit,bytes_per_sector;
2349 if (get_dfree_info(conn,".",False,&bsize,&dfree,&dsize) == (SMB_BIG_UINT)-1) {
2350 return(UNIXERROR(ERRHRD,ERRgeneral));
2352 block_size = lp_block_size(snum);
2353 if (bsize < block_size) {
2354 SMB_BIG_UINT factor = block_size/bsize;
2359 if (bsize > block_size) {
2360 SMB_BIG_UINT factor = bsize/block_size;
2365 bytes_per_sector = 512;
2366 sectors_per_unit = bsize/bytes_per_sector;
2367 DEBUG(5,("call_trans2qfsinfo : SMB_QUERY_FS_FULL_SIZE_INFO bsize=%u, cSectorUnit=%u, \
2368 cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize, (unsigned int)sectors_per_unit,
2369 (unsigned int)bytes_per_sector, (unsigned int)dsize, (unsigned int)dfree));
2370 SBIG_UINT(pdata,0,dsize); /* Total Allocation units. */
2371 SBIG_UINT(pdata,8,dfree); /* Caller available allocation units. */
2372 SBIG_UINT(pdata,16,dfree); /* Actual available allocation units. */
2373 SIVAL(pdata,24,sectors_per_unit); /* Sectors per allocation unit. */
2374 SIVAL(pdata,28,bytes_per_sector); /* Bytes per sector. */
2378 case SMB_QUERY_FS_DEVICE_INFO:
2379 case SMB_FS_DEVICE_INFORMATION:
2381 SIVAL(pdata,0,0); /* dev type */
2382 SIVAL(pdata,4,0); /* characteristics */
2385 #ifdef HAVE_SYS_QUOTAS
2386 case SMB_FS_QUOTA_INFORMATION:
2388 * what we have to send --metze:
2390 * Unknown1: 24 NULL bytes
2391 * Soft Quota Treshold: 8 bytes seems like SMB_BIG_UINT or so
2392 * Hard Quota Limit: 8 bytes seems like SMB_BIG_UINT or so
2393 * Quota Flags: 2 byte :
2394 * Unknown3: 6 NULL bytes
2398 * details for Quota Flags:
2400 * 0x0020 Log Limit: log if the user exceeds his Hard Quota
2401 * 0x0010 Log Warn: log if the user exceeds his Soft Quota
2402 * 0x0002 Deny Disk: deny disk access when the user exceeds his Hard Quota
2403 * 0x0001 Enable Quotas: enable quota for this fs
2407 /* we need to fake up a fsp here,
2408 * because its not send in this call
2411 SMB_NTQUOTA_STRUCT quotas;
2414 ZERO_STRUCT(quotas);
2420 if (current_user.ut.uid != 0) {
2421 DEBUG(0,("set_user_quota: access_denied service [%s] user [%s]\n",
2422 lp_servicename(SNUM(conn)),conn->user));
2423 return ERROR_DOS(ERRDOS,ERRnoaccess);
2426 if (vfs_get_ntquota(&fsp, SMB_USER_FS_QUOTA_TYPE, NULL, "as)!=0) {
2427 DEBUG(0,("vfs_get_ntquota() failed for service [%s]\n",lp_servicename(SNUM(conn))));
2428 return ERROR_DOS(ERRSRV,ERRerror);
2433 DEBUG(10,("SMB_FS_QUOTA_INFORMATION: for service [%s]\n",lp_servicename(SNUM(conn))));
2435 /* Unknown1 24 NULL bytes*/
2436 SBIG_UINT(pdata,0,(SMB_BIG_UINT)0);
2437 SBIG_UINT(pdata,8,(SMB_BIG_UINT)0);
2438 SBIG_UINT(pdata,16,(SMB_BIG_UINT)0);
2440 /* Default Soft Quota 8 bytes */
2441 SBIG_UINT(pdata,24,quotas.softlim);
2443 /* Default Hard Quota 8 bytes */
2444 SBIG_UINT(pdata,32,quotas.hardlim);
2446 /* Quota flag 2 bytes */
2447 SSVAL(pdata,40,quotas.qflags);
2449 /* Unknown3 6 NULL bytes */
2455 #endif /* HAVE_SYS_QUOTAS */
2456 case SMB_FS_OBJECTID_INFORMATION:
2461 * Query the version and capabilities of the CIFS UNIX extensions
2465 case SMB_QUERY_CIFS_UNIX_INFO:
2466 if (!lp_unix_extensions()) {
2467 return ERROR_NT(NT_STATUS_INVALID_LEVEL);
2470 SSVAL(pdata,0,CIFS_UNIX_MAJOR_VERSION);
2471 SSVAL(pdata,2,CIFS_UNIX_MINOR_VERSION);
2472 /* We have POSIX ACLs, pathname and locking capability. */
2473 SBIG_UINT(pdata,4,((SMB_BIG_UINT)(
2474 CIFS_UNIX_POSIX_ACLS_CAP|
2475 CIFS_UNIX_POSIX_PATHNAMES_CAP|
2476 CIFS_UNIX_FCNTL_LOCKS_CAP)));
2479 case SMB_QUERY_POSIX_FS_INFO:
2482 vfs_statvfs_struct svfs;
2484 if (!lp_unix_extensions()) {
2485 return ERROR_NT(NT_STATUS_INVALID_LEVEL);
2488 rc = SMB_VFS_STATVFS(conn, ".", &svfs);
2492 SIVAL(pdata,0,svfs.OptimalTransferSize);
2493 SIVAL(pdata,4,svfs.BlockSize);
2494 SBIG_UINT(pdata,8,svfs.TotalBlocks);
2495 SBIG_UINT(pdata,16,svfs.BlocksAvail);
2496 SBIG_UINT(pdata,24,svfs.UserBlocksAvail);
2497 SBIG_UINT(pdata,32,svfs.TotalFileNodes);
2498 SBIG_UINT(pdata,40,svfs.FreeFileNodes);
2499 SBIG_UINT(pdata,48,svfs.FsIdentifier);
2500 DEBUG(5,("call_trans2qfsinfo : SMB_QUERY_POSIX_FS_INFO succsessful\n"));
2502 } else if (rc == EOPNOTSUPP) {
2503 return ERROR_NT(NT_STATUS_INVALID_LEVEL);
2504 #endif /* EOPNOTSUPP */
2506 DEBUG(0,("vfs_statvfs() failed for service [%s]\n",lp_servicename(SNUM(conn))));
2507 return ERROR_DOS(ERRSRV,ERRerror);
2512 case SMB_MAC_QUERY_FS_INFO:
2514 * Thursby MAC extension... ONLY on NTFS filesystems
2515 * once we do streams then we don't need this
2517 if (strequal(lp_fstype(SNUM(conn)),"NTFS")) {
2519 SIVAL(pdata,84,0x100); /* Don't support mac... */
2524 return ERROR_NT(NT_STATUS_INVALID_LEVEL);
2528 send_trans2_replies( outbuf, bufsize, params, 0, pdata, data_len, max_data_bytes);
2530 DEBUG( 4, ( "%s info_level = %d\n", smb_fn_name(CVAL(inbuf,smb_com)), info_level) );
2535 /****************************************************************************
2536 Reply to a TRANS2_SETFSINFO (set filesystem info).
2537 ****************************************************************************/
2539 static int call_trans2setfsinfo(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize,
2540 char **pparams, int total_params, char **ppdata, int total_data,
2541 unsigned int max_data_bytes)
2543 char *pdata = *ppdata;
2544 char *params = *pparams;
2548 DEBUG(10,("call_trans2setfsinfo: for service [%s]\n",lp_servicename(SNUM(conn))));
2551 if (total_params < 4) {
2552 DEBUG(0,("call_trans2setfsinfo: requires total_params(%d) >= 4 bytes!\n",
2554 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
2557 info_level = SVAL(params,2);
2559 switch(info_level) {
2560 case SMB_SET_CIFS_UNIX_INFO:
2562 uint16 client_unix_major;
2563 uint16 client_unix_minor;
2564 uint32 client_unix_cap_low;
2565 uint32 client_unix_cap_high;
2567 if (!lp_unix_extensions()) {
2568 return ERROR_NT(NT_STATUS_INVALID_LEVEL);
2571 /* There should be 12 bytes of capabilities set. */
2572 if (total_data < 8) {
2573 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
2575 client_unix_major = SVAL(pdata,0);
2576 client_unix_minor = SVAL(pdata,2);
2577 client_unix_cap_low = IVAL(pdata,4);
2578 client_unix_cap_high = IVAL(pdata,8);
2579 /* Just print these values for now. */
2580 DEBUG(10,("call_trans2setfsinfo: set unix info. major = %u, minor = %u \
2581 cap_low = 0x%x, cap_high = 0x%x\n",
2582 (unsigned int)client_unix_major,
2583 (unsigned int)client_unix_minor,
2584 (unsigned int)client_unix_cap_low,
2585 (unsigned int)client_unix_cap_high ));
2587 /* Here is where we must switch to posix pathname processing... */
2588 if (client_unix_cap_low & CIFS_UNIX_POSIX_PATHNAMES_CAP) {
2589 lp_set_posix_pathnames();
2590 mangle_change_to_posix();
2593 if (client_unix_cap_low & CIFS_UNIX_FCNTL_LOCKS_CAP) {
2594 lp_set_posix_cifsx_locktype(POSIX_LOCK);
2598 case SMB_FS_QUOTA_INFORMATION:
2600 files_struct *fsp = NULL;
2601 SMB_NTQUOTA_STRUCT quotas;
2603 ZERO_STRUCT(quotas);
2606 if ((current_user.ut.uid != 0)||!CAN_WRITE(conn)) {
2607 DEBUG(0,("set_user_quota: access_denied service [%s] user [%s]\n",
2608 lp_servicename(SNUM(conn)),conn->user));
2609 return ERROR_DOS(ERRSRV,ERRaccess);
2612 /* note: normaly there're 48 bytes,
2613 * but we didn't use the last 6 bytes for now
2616 fsp = file_fsp(params,0);
2617 if (!CHECK_NTQUOTA_HANDLE_OK(fsp,conn)) {
2618 DEBUG(3,("TRANSACT_GET_USER_QUOTA: no valid QUOTA HANDLE\n"));
2619 return ERROR_NT(NT_STATUS_INVALID_HANDLE);
2622 if (total_data < 42) {
2623 DEBUG(0,("call_trans2setfsinfo: SET_FS_QUOTA: requires total_data(%d) >= 42 bytes!\n",
2625 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
2628 /* unknown_1 24 NULL bytes in pdata*/
2630 /* the soft quotas 8 bytes (SMB_BIG_UINT)*/
2631 quotas.softlim = (SMB_BIG_UINT)IVAL(pdata,24);
2632 #ifdef LARGE_SMB_OFF_T
2633 quotas.softlim |= (((SMB_BIG_UINT)IVAL(pdata,28)) << 32);
2634 #else /* LARGE_SMB_OFF_T */
2635 if ((IVAL(pdata,28) != 0)&&
2636 ((quotas.softlim != 0xFFFFFFFF)||
2637 (IVAL(pdata,28)!=0xFFFFFFFF))) {
2638 /* more than 32 bits? */
2639 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
2641 #endif /* LARGE_SMB_OFF_T */
2643 /* the hard quotas 8 bytes (SMB_BIG_UINT)*/
2644 quotas.hardlim = (SMB_BIG_UINT)IVAL(pdata,32);
2645 #ifdef LARGE_SMB_OFF_T
2646 quotas.hardlim |= (((SMB_BIG_UINT)IVAL(pdata,36)) << 32);
2647 #else /* LARGE_SMB_OFF_T */
2648 if ((IVAL(pdata,36) != 0)&&
2649 ((quotas.hardlim != 0xFFFFFFFF)||
2650 (IVAL(pdata,36)!=0xFFFFFFFF))) {
2651 /* more than 32 bits? */
2652 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
2654 #endif /* LARGE_SMB_OFF_T */
2656 /* quota_flags 2 bytes **/
2657 quotas.qflags = SVAL(pdata,40);
2659 /* unknown_2 6 NULL bytes follow*/
2661 /* now set the quotas */
2662 if (vfs_set_ntquota(fsp, SMB_USER_FS_QUOTA_TYPE, NULL, "as)!=0) {
2663 DEBUG(0,("vfs_set_ntquota() failed for service [%s]\n",lp_servicename(SNUM(conn))));
2664 return ERROR_DOS(ERRSRV,ERRerror);
2670 DEBUG(3,("call_trans2setfsinfo: unknown level (0x%X) not implemented yet.\n",
2672 return ERROR_NT(NT_STATUS_INVALID_LEVEL);
2677 * sending this reply works fine,
2678 * but I'm not sure it's the same
2679 * like windows do...
2682 outsize = set_message(outbuf,10,0,True);
2687 /****************************************************************************
2688 Utility function to set bad path error.
2689 ****************************************************************************/
2691 int set_bad_path_error(int err, BOOL bad_path, char *outbuf, int def_class, uint32 def_code)
2693 DEBUG(10,("set_bad_path_error: err = %d bad_path = %d\n",
2694 err, (int)bad_path ));
2698 return ERROR_NT(NT_STATUS_OBJECT_PATH_NOT_FOUND);
2700 return ERROR_NT(NT_STATUS_OBJECT_NAME_NOT_FOUND);
2703 return UNIXERROR(def_class,def_code);
2706 #if defined(HAVE_POSIX_ACLS)
2707 /****************************************************************************
2708 Utility function to count the number of entries in a POSIX acl.
2709 ****************************************************************************/
2711 static unsigned int count_acl_entries(connection_struct *conn, SMB_ACL_T posix_acl)
2713 unsigned int ace_count = 0;
2714 int entry_id = SMB_ACL_FIRST_ENTRY;
2715 SMB_ACL_ENTRY_T entry;
2717 while ( posix_acl && (SMB_VFS_SYS_ACL_GET_ENTRY(conn, posix_acl, entry_id, &entry) == 1)) {
2719 if (entry_id == SMB_ACL_FIRST_ENTRY) {
2720 entry_id = SMB_ACL_NEXT_ENTRY;
2727 /****************************************************************************
2728 Utility function to marshall a POSIX acl into wire format.
2729 ****************************************************************************/
2731 static BOOL marshall_posix_acl(connection_struct *conn, char *pdata, SMB_STRUCT_STAT *pst, SMB_ACL_T posix_acl)
2733 int entry_id = SMB_ACL_FIRST_ENTRY;
2734 SMB_ACL_ENTRY_T entry;
2736 while ( posix_acl && (SMB_VFS_SYS_ACL_GET_ENTRY(conn, posix_acl, entry_id, &entry) == 1)) {
2737 SMB_ACL_TAG_T tagtype;
2738 SMB_ACL_PERMSET_T permset;
2739 unsigned char perms = 0;
2740 unsigned int own_grp;
2743 if (entry_id == SMB_ACL_FIRST_ENTRY) {
2744 entry_id = SMB_ACL_NEXT_ENTRY;
2747 if (SMB_VFS_SYS_ACL_GET_TAG_TYPE(conn, entry, &tagtype) == -1) {
2748 DEBUG(0,("marshall_posix_acl: SMB_VFS_SYS_ACL_GET_TAG_TYPE failed.\n"));
2752 if (SMB_VFS_SYS_ACL_GET_PERMSET(conn, entry, &permset) == -1) {
2753 DEBUG(0,("marshall_posix_acl: SMB_VFS_SYS_ACL_GET_PERMSET failed.\n"));
2757 perms |= (SMB_VFS_SYS_ACL_GET_PERM(conn, permset, SMB_ACL_READ) ? SMB_POSIX_ACL_READ : 0);
2758 perms |= (SMB_VFS_SYS_ACL_GET_PERM(conn, permset, SMB_ACL_WRITE) ? SMB_POSIX_ACL_WRITE : 0);
2759 perms |= (SMB_VFS_SYS_ACL_GET_PERM(conn, permset, SMB_ACL_EXECUTE) ? SMB_POSIX_ACL_EXECUTE : 0);
2761 SCVAL(pdata,1,perms);
2764 case SMB_ACL_USER_OBJ:
2765 SCVAL(pdata,0,SMB_POSIX_ACL_USER_OBJ);
2766 own_grp = (unsigned int)pst->st_uid;
2767 SIVAL(pdata,2,own_grp);
2772 uid_t *puid = (uid_t *)SMB_VFS_SYS_ACL_GET_QUALIFIER(conn, entry);
2774 DEBUG(0,("marshall_posix_acl: SMB_VFS_SYS_ACL_GET_QUALIFIER failed.\n"));
2776 own_grp = (unsigned int)*puid;
2777 SMB_VFS_SYS_ACL_FREE_QUALIFIER(conn, (void *)puid,tagtype);
2778 SCVAL(pdata,0,SMB_POSIX_ACL_USER);
2779 SIVAL(pdata,2,own_grp);
2783 case SMB_ACL_GROUP_OBJ:
2784 SCVAL(pdata,0,SMB_POSIX_ACL_GROUP_OBJ);
2785 own_grp = (unsigned int)pst->st_gid;
2786 SIVAL(pdata,2,own_grp);
2791 gid_t *pgid= (gid_t *)SMB_VFS_SYS_ACL_GET_QUALIFIER(conn, entry);
2793 DEBUG(0,("marshall_posix_acl: SMB_VFS_SYS_ACL_GET_QUALIFIER failed.\n"));
2795 own_grp = (unsigned int)*pgid;
2796 SMB_VFS_SYS_ACL_FREE_QUALIFIER(conn, (void *)pgid,tagtype);
2797 SCVAL(pdata,0,SMB_POSIX_ACL_GROUP);
2798 SIVAL(pdata,2,own_grp);
2803 SCVAL(pdata,0,SMB_POSIX_ACL_MASK);
2804 SIVAL(pdata,2,0xFFFFFFFF);
2805 SIVAL(pdata,6,0xFFFFFFFF);
2808 SCVAL(pdata,0,SMB_POSIX_ACL_OTHER);
2809 SIVAL(pdata,2,0xFFFFFFFF);
2810 SIVAL(pdata,6,0xFFFFFFFF);
2813 DEBUG(0,("marshall_posix_acl: unknown tagtype.\n"));
2816 pdata += SMB_POSIX_ACL_ENTRY_SIZE;
2823 /****************************************************************************
2824 Reply to a TRANS2_QFILEPATHINFO or TRANSACT2_QFILEINFO (query file info by
2825 file name or file id).
2826 ****************************************************************************/
2828 static int call_trans2qfilepathinfo(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize,
2829 unsigned int tran_call,
2830 char **pparams, int total_params, char **ppdata, int total_data,
2831 unsigned int max_data_bytes)
2833 char *params = *pparams;
2834 char *pdata = *ppdata;
2838 SMB_OFF_T file_size=0;
2839 SMB_BIG_UINT allocation_size=0;
2840 unsigned int data_size = 0;
2841 unsigned int param_size = 2;
2842 SMB_STRUCT_STAT sbuf;
2843 pstring fname, dos_fname;
2848 BOOL bad_path = False;
2849 BOOL delete_pending = False;
2851 time_t create_time, mtime, atime;
2852 struct timespec create_time_ts, mtime_ts, atime_ts;
2853 files_struct *fsp = NULL;
2854 TALLOC_CTX *data_ctx = NULL;
2855 struct ea_list *ea_list = NULL;
2856 uint32 access_mask = 0x12019F; /* Default - GENERIC_EXECUTE mapping from Windows */
2857 char *lock_data = NULL;
2860 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
2864 if (tran_call == TRANSACT2_QFILEINFO) {
2865 if (total_params < 4) {
2866 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
2869 fsp = file_fsp(params,0);
2870 info_level = SVAL(params,2);
2872 DEBUG(3,("call_trans2qfilepathinfo: TRANSACT2_QFILEINFO: level = %d\n", info_level));
2874 if(fsp && (fsp->fake_file_handle)) {
2876 * This is actually for the QUOTA_FAKE_FILE --metze
2879 pstrcpy(fname, fsp->fsp_name);
2880 /* We know this name is ok, it's already passed the checks. */
2882 } else if(fsp && (fsp->is_directory || fsp->fh->fd == -1)) {
2884 * This is actually a QFILEINFO on a directory
2885 * handle (returned from an NT SMB). NT5.0 seems
2886 * to do this call. JRA.
2888 /* We know this name is ok, it's already passed the checks. */
2889 pstrcpy(fname, fsp->fsp_name);
2891 if (INFO_LEVEL_IS_UNIX(info_level)) {
2892 /* Always do lstat for UNIX calls. */
2893 if (SMB_VFS_LSTAT(conn,fname,&sbuf)) {
2894 DEBUG(3,("call_trans2qfilepathinfo: SMB_VFS_LSTAT of %s failed (%s)\n",fname,strerror(errno)));
2895 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRbadpath);
2897 } else if (SMB_VFS_STAT(conn,fname,&sbuf)) {
2898 DEBUG(3,("call_trans2qfilepathinfo: SMB_VFS_STAT of %s failed (%s)\n",fname,strerror(errno)));
2899 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRbadpath);
2902 delete_pending = get_delete_on_close_flag(sbuf.st_dev, sbuf.st_ino);
2905 * Original code - this is an open file.
2907 CHECK_FSP(fsp,conn);
2909 pstrcpy(fname, fsp->fsp_name);
2910 if (SMB_VFS_FSTAT(fsp,fsp->fh->fd,&sbuf) != 0) {
2911 DEBUG(3,("fstat of fnum %d failed (%s)\n", fsp->fnum, strerror(errno)));
2912 return(UNIXERROR(ERRDOS,ERRbadfid));
2914 pos = fsp->fh->position_information;
2915 delete_pending = get_delete_on_close_flag(sbuf.st_dev, sbuf.st_ino);
2916 access_mask = fsp->access_mask;
2919 NTSTATUS status = NT_STATUS_OK;
2922 if (total_params < 6) {
2923 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
2926 info_level = SVAL(params,0);
2928 DEBUG(3,("call_trans2qfilepathinfo: TRANSACT2_QPATHINFO: level = %d\n", info_level));
2930 srvstr_get_path(inbuf, fname, ¶ms[6], sizeof(fname), -1, STR_TERMINATE, &status);
2931 if (!NT_STATUS_IS_OK(status)) {
2932 return ERROR_NT(status);
2935 RESOLVE_DFSPATH(fname, conn, inbuf, outbuf);
2937 unix_convert(fname,conn,0,&bad_path,&sbuf);
2939 return ERROR_NT(NT_STATUS_OBJECT_PATH_NOT_FOUND);
2941 if (!check_name(fname,conn)) {
2942 DEBUG(3,("call_trans2qfilepathinfo: fileinfo of %s failed (%s)\n",fname,strerror(errno)));
2943 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRbadpath);
2946 if (INFO_LEVEL_IS_UNIX(info_level)) {
2947 /* Always do lstat for UNIX calls. */
2948 if (SMB_VFS_LSTAT(conn,fname,&sbuf)) {
2949 DEBUG(3,("call_trans2qfilepathinfo: SMB_VFS_LSTAT of %s failed (%s)\n",fname,strerror(errno)));
2950 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRbadpath);
2952 } else if (!VALID_STAT(sbuf) && SMB_VFS_STAT(conn,fname,&sbuf) && (info_level != SMB_INFO_IS_NAME_VALID)) {
2953 DEBUG(3,("call_trans2qfilepathinfo: SMB_VFS_STAT of %s failed (%s)\n",fname,strerror(errno)));
2954 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRbadpath);
2957 delete_pending = get_delete_on_close_flag(sbuf.st_dev, sbuf.st_ino);
2958 if (delete_pending) {
2959 return ERROR_NT(NT_STATUS_DELETE_PENDING);
2963 nlink = sbuf.st_nlink;
2965 if ((nlink > 0) && S_ISDIR(sbuf.st_mode)) {
2966 /* NTFS does not seem to count ".." */
2970 if ((nlink > 0) && delete_pending) {
2974 if (INFO_LEVEL_IS_UNIX(info_level) && !lp_unix_extensions()) {
2975 return ERROR_NT(NT_STATUS_INVALID_LEVEL);
2978 DEBUG(3,("call_trans2qfilepathinfo %s (fnum = %d) level=%d call=%d total_data=%d\n",
2979 fname,fsp ? fsp->fnum : -1, info_level,tran_call,total_data));
2981 p = strrchr_m(fname,'/');
2987 mode = dos_mode(conn,fname,&sbuf);
2989 mode = FILE_ATTRIBUTE_NORMAL;
2991 fullpathname = fname;
2993 file_size = get_file_size(sbuf);
2995 /* Pull out any data sent here before we realloc. */
2996 switch (info_level) {
2997 case SMB_INFO_QUERY_EAS_FROM_LIST:
2999 /* Pull any EA list from the data portion. */
3002 if (total_data < 4) {
3003 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
3005 ea_size = IVAL(pdata,0);
3007 if (total_data > 0 && ea_size != total_data) {
3008 DEBUG(4,("call_trans2qfilepathinfo: Rejecting EA request with incorrect \
3009 total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pdata,0) ));
3010 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
3013 if (!lp_ea_support(SNUM(conn))) {
3014 return ERROR_DOS(ERRDOS,ERReasnotsupported);
3017 if ((data_ctx = talloc_init("ea_list")) == NULL) {
3018 return ERROR_NT(NT_STATUS_NO_MEMORY);
3021 /* Pull out the list of names. */
3022 ea_list = read_ea_name_list(data_ctx, pdata + 4, ea_size - 4);
3024 talloc_destroy(data_ctx);
3025 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
3030 case SMB_QUERY_POSIX_LOCK:
3032 if (fsp == NULL || fsp->fh->fd == -1) {
3033 return ERROR_NT(NT_STATUS_INVALID_HANDLE);
3036 if (total_data != POSIX_LOCK_DATA_SIZE) {
3037 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
3040 if ((data_ctx = talloc_init("lock_request")) == NULL) {
3041 return ERROR_NT(NT_STATUS_NO_MEMORY);
3044 /* Copy the lock range data. */
3045 lock_data = (char *)talloc_memdup(
3046 data_ctx, pdata, total_data);
3048 talloc_destroy(data_ctx);
3049 return ERROR_NT(NT_STATUS_NO_MEMORY);
3056 *pparams = (char *)SMB_REALLOC(*pparams,2);
3057 if (*pparams == NULL) {
3058 talloc_destroy(data_ctx);
3059 return ERROR_NT(NT_STATUS_NO_MEMORY);
3063 data_size = max_data_bytes + DIR_ENTRY_SAFETY_MARGIN;
3064 *ppdata = (char *)SMB_REALLOC(*ppdata, data_size);
3065 if (*ppdata == NULL ) {
3066 talloc_destroy(data_ctx);
3067 return ERROR_NT(NT_STATUS_NO_MEMORY);
3071 create_time_ts = get_create_timespec(&sbuf,lp_fake_dir_create_times(SNUM(conn)));
3072 mtime_ts = get_mtimespec(&sbuf);
3073 atime_ts = get_atimespec(&sbuf);
3075 allocation_size = get_allocation_size(conn,fsp,&sbuf);
3078 if (fsp->pending_modtime) {
3079 /* the pending modtime overrides the current modtime */
3080 mtime_ts.tv_sec = fsp->pending_modtime;
3081 mtime_ts.tv_nsec = 0;
3084 /* Do we have this path open ? */
3085 files_struct *fsp1 = file_find_di_first(sbuf.st_dev, sbuf.st_ino);
3086 if (fsp1 && fsp1->pending_modtime) {
3087 /* the pending modtime overrides the current modtime */
3088 mtime_ts.tv_sec = fsp1->pending_modtime;
3089 mtime_ts.tv_nsec = 0;
3091 if (fsp1 && fsp1->initial_allocation_size) {
3092 allocation_size = get_allocation_size(conn, fsp1, &sbuf);
3096 if (lp_dos_filetime_resolution(SNUM(conn))) {
3097 dos_filetime_timespec(&create_time_ts);
3098 dos_filetime_timespec(&mtime_ts);
3099 dos_filetime_timespec(&atime_ts);
3102 create_time = convert_timespec_to_time_t(create_time_ts);
3103 mtime = convert_timespec_to_time_t(mtime_ts);
3104 atime = convert_timespec_to_time_t(atime_ts);
3106 /* NT expects the name to be in an exact form of the *full*
3107 filename. See the trans2 torture test */
3108 if (strequal(base_name,".")) {
3109 pstrcpy(dos_fname, "\\");
3111 pstr_sprintf(dos_fname, "\\%s", fname);
3112 string_replace(dos_fname, '/', '\\');
3115 switch (info_level) {
3116 case SMB_INFO_STANDARD:
3117 DEBUG(10,("call_trans2qfilepathinfo: SMB_INFO_STANDARD\n"));
3119 srv_put_dos_date2(pdata,l1_fdateCreation,create_time);
3120 srv_put_dos_date2(pdata,l1_fdateLastAccess,atime);
3121 srv_put_dos_date2(pdata,l1_fdateLastWrite,mtime); /* write time */
3122 SIVAL(pdata,l1_cbFile,(uint32)file_size);
3123 SIVAL(pdata,l1_cbFileAlloc,(uint32)allocation_size);
3124 SSVAL(pdata,l1_attrFile,mode);
3127 case SMB_INFO_QUERY_EA_SIZE:
3129 unsigned int ea_size = estimate_ea_size(conn, fsp, fname);
3130 DEBUG(10,("call_trans2qfilepathinfo: SMB_INFO_QUERY_EA_SIZE\n"));
3132 srv_put_dos_date2(pdata,0,create_time);
3133 srv_put_dos_date2(pdata,4,atime);
3134 srv_put_dos_date2(pdata,8,mtime); /* write time */
3135 SIVAL(pdata,12,(uint32)file_size);
3136 SIVAL(pdata,16,(uint32)allocation_size);
3137 SSVAL(pdata,20,mode);
3138 SIVAL(pdata,22,ea_size);
3142 case SMB_INFO_IS_NAME_VALID:
3143 DEBUG(10,("call_trans2qfilepathinfo: SMB_INFO_IS_NAME_VALID\n"));
3144 if (tran_call == TRANSACT2_QFILEINFO) {
3145 /* os/2 needs this ? really ?*/
3146 return ERROR_DOS(ERRDOS,ERRbadfunc);
3152 case SMB_INFO_QUERY_EAS_FROM_LIST:
3154 size_t total_ea_len = 0;
3155 struct ea_list *ea_file_list = NULL;
3157 DEBUG(10,("call_trans2qfilepathinfo: SMB_INFO_QUERY_EAS_FROM_LIST\n"));
3159 ea_file_list = get_ea_list_from_file(data_ctx, conn, fsp, fname, &total_ea_len);
3160 ea_list = ea_list_union(ea_list, ea_file_list, &total_ea_len);
3162 if (!ea_list || (total_ea_len > data_size)) {
3163 talloc_destroy(data_ctx);
3165 SIVAL(pdata,0,4); /* EA List Length must be set to 4 if no EA's. */
3169 data_size = fill_ea_buffer(data_ctx, pdata, data_size, conn, ea_list);
3170 talloc_destroy(data_ctx);
3174 case SMB_INFO_QUERY_ALL_EAS:
3176 /* We have data_size bytes to put EA's into. */
3177 size_t total_ea_len = 0;
3179 DEBUG(10,("call_trans2qfilepathinfo: SMB_INFO_QUERY_ALL_EAS\n"));
3181 data_ctx = talloc_init("ea_ctx");
3183 return ERROR_NT(NT_STATUS_NO_MEMORY);
3186 ea_list = get_ea_list_from_file(data_ctx, conn, fsp, fname, &total_ea_len);
3187 if (!ea_list || (total_ea_len > data_size)) {
3188 talloc_destroy(data_ctx);
3190 SIVAL(pdata,0,4); /* EA List Length must be set to 4 if no EA's. */
3194 data_size = fill_ea_buffer(data_ctx, pdata, data_size, conn, ea_list);
3195 talloc_destroy(data_ctx);
3199 case SMB_FILE_BASIC_INFORMATION:
3200 case SMB_QUERY_FILE_BASIC_INFO:
3202 if (info_level == SMB_QUERY_FILE_BASIC_INFO) {
3203 DEBUG(10,("call_trans2qfilepathinfo: SMB_QUERY_FILE_BASIC_INFO\n"));
3204 data_size = 36; /* w95 returns 40 bytes not 36 - why ?. */
3206 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_BASIC_INFORMATION\n"));
3210 put_long_date_timespec(pdata,create_time_ts);
3211 put_long_date_timespec(pdata+8,atime_ts);
3212 put_long_date_timespec(pdata+16,mtime_ts); /* write time */
3213 put_long_date_timespec(pdata+24,mtime_ts); /* change time */
3214 SIVAL(pdata,32,mode);
3216 DEBUG(5,("SMB_QFBI - "));
3217 DEBUG(5,("create: %s ", ctime(&create_time)));
3218 DEBUG(5,("access: %s ", ctime(&atime)));
3219 DEBUG(5,("write: %s ", ctime(&mtime)));
3220 DEBUG(5,("change: %s ", ctime(&mtime)));
3221 DEBUG(5,("mode: %x\n", mode));
3224 case SMB_FILE_STANDARD_INFORMATION:
3225 case SMB_QUERY_FILE_STANDARD_INFO:
3227 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_STANDARD_INFORMATION\n"));
3229 SOFF_T(pdata,0,allocation_size);
3230 SOFF_T(pdata,8,file_size);
3231 SIVAL(pdata,16,nlink);
3232 SCVAL(pdata,20,delete_pending?1:0);
3233 SCVAL(pdata,21,(mode&aDIR)?1:0);
3234 SSVAL(pdata,22,0); /* Padding. */
3237 case SMB_FILE_EA_INFORMATION:
3238 case SMB_QUERY_FILE_EA_INFO:
3240 unsigned int ea_size = estimate_ea_size(conn, fsp, fname);
3241 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_EA_INFORMATION\n"));
3243 SIVAL(pdata,0,ea_size);
3247 /* Get the 8.3 name - used if NT SMB was negotiated. */
3248 case SMB_QUERY_FILE_ALT_NAME_INFO:
3249 case SMB_FILE_ALTERNATE_NAME_INFORMATION:
3253 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_ALTERNATE_NAME_INFORMATION\n"));
3254 pstrcpy(short_name,base_name);
3255 /* Mangle if not already 8.3 */
3256 if(!mangle_is_8_3(short_name, True, conn->params)) {
3257 mangle_map(short_name,True,True,conn->params);
3259 len = srvstr_push(outbuf, pdata+4, short_name, -1, STR_UNICODE);
3260 data_size = 4 + len;
3265 case SMB_QUERY_FILE_NAME_INFO:
3267 this must be *exactly* right for ACLs on mapped drives to work
3269 len = srvstr_push(outbuf, pdata+4, dos_fname, -1, STR_UNICODE);
3270 DEBUG(10,("call_trans2qfilepathinfo: SMB_QUERY_FILE_NAME_INFO\n"));
3271 data_size = 4 + len;
3275 case SMB_FILE_ALLOCATION_INFORMATION:
3276 case SMB_QUERY_FILE_ALLOCATION_INFO:
3277 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_ALLOCATION_INFORMATION\n"));
3279 SOFF_T(pdata,0,allocation_size);
3282 case SMB_FILE_END_OF_FILE_INFORMATION:
3283 case SMB_QUERY_FILE_END_OF_FILEINFO:
3284 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_END_OF_FILE_INFORMATION\n"));
3286 SOFF_T(pdata,0,file_size);
3289 case SMB_QUERY_FILE_ALL_INFO:
3290 case SMB_FILE_ALL_INFORMATION:
3292 unsigned int ea_size = estimate_ea_size(conn, fsp, fname);
3293 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_ALL_INFORMATION\n"));
3294 put_long_date_timespec(pdata,create_time_ts);
3295 put_long_date_timespec(pdata+8,atime_ts);
3296 put_long_date_timespec(pdata+16,mtime_ts); /* write time */
3297 put_long_date_timespec(pdata+24,mtime_ts); /* change time */
3298 SIVAL(pdata,32,mode);
3299 SIVAL(pdata,36,0); /* padding. */
3301 SOFF_T(pdata,0,allocation_size);
3302 SOFF_T(pdata,8,file_size);
3303 SIVAL(pdata,16,nlink);
3304 SCVAL(pdata,20,delete_pending);
3305 SCVAL(pdata,21,(mode&aDIR)?1:0);
3308 SIVAL(pdata,0,ea_size);
3309 pdata += 4; /* EA info */
3310 len = srvstr_push(outbuf, pdata+4, dos_fname, -1, STR_UNICODE);
3313 data_size = PTR_DIFF(pdata,(*ppdata));
3316 case SMB_FILE_INTERNAL_INFORMATION:
3317 /* This should be an index number - looks like
3320 I think this causes us to fail the IFSKIT
3321 BasicFileInformationTest. -tpot */
3323 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_INTERNAL_INFORMATION\n"));
3324 SIVAL(pdata,0,sbuf.st_ino); /* FileIndexLow */
3325 SIVAL(pdata,4,sbuf.st_dev); /* FileIndexHigh */
3329 case SMB_FILE_ACCESS_INFORMATION:
3330 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_ACCESS_INFORMATION\n"));
3331 SIVAL(pdata,0,access_mask);
3335 case SMB_FILE_NAME_INFORMATION:
3336 /* Pathname with leading '\'. */
3339 byte_len = dos_PutUniCode(pdata+4,dos_fname,(size_t)max_data_bytes,False);
3340 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_NAME_INFORMATION\n"));
3341 SIVAL(pdata,0,byte_len);
3342 data_size = 4 + byte_len;
3346 case SMB_FILE_DISPOSITION_INFORMATION:
3347 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_DISPOSITION_INFORMATION\n"));
3349 SCVAL(pdata,0,delete_pending);
3352 case SMB_FILE_POSITION_INFORMATION:
3353 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_POSITION_INFORMATION\n"));
3355 SOFF_T(pdata,0,pos);
3358 case SMB_FILE_MODE_INFORMATION:
3359 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_MODE_INFORMATION\n"));
3360 SIVAL(pdata,0,mode);
3364 case SMB_FILE_ALIGNMENT_INFORMATION:
3365 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_ALIGNMENT_INFORMATION\n"));
3366 SIVAL(pdata,0,0); /* No alignment needed. */
3372 * NT4 server just returns "invalid query" to this - if we try to answer
3373 * it then NTws gets a BSOD! (tridge).
3374 * W2K seems to want this. JRA.
3376 case SMB_QUERY_FILE_STREAM_INFO:
3378 case SMB_FILE_STREAM_INFORMATION:
3379 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_STREAM_INFORMATION\n"));
3383 size_t byte_len = dos_PutUniCode(pdata+24,"::$DATA", (size_t)0xE, False);
3384 SIVAL(pdata,0,0); /* ??? */
3385 SIVAL(pdata,4,byte_len); /* Byte length of unicode string ::$DATA */
3386 SOFF_T(pdata,8,file_size);
3387 SIVAL(pdata,16,allocation_size);
3388 SIVAL(pdata,20,0); /* ??? */
3389 data_size = 24 + byte_len;
3393 case SMB_QUERY_COMPRESSION_INFO:
3394 case SMB_FILE_COMPRESSION_INFORMATION:
3395 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_COMPRESSION_INFORMATION\n"));
3396 SOFF_T(pdata,0,file_size);
3397 SIVAL(pdata,8,0); /* ??? */
3398 SIVAL(pdata,12,0); /* ??? */
3402 case SMB_FILE_NETWORK_OPEN_INFORMATION:
3403 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_NETWORK_OPEN_INFORMATION\n"));
3404 put_long_date_timespec(pdata,create_time_ts);
3405 put_long_date_timespec(pdata+8,atime_ts);
3406 put_long_date_timespec(pdata+16,mtime_ts); /* write time */
3407 put_long_date_timespec(pdata+24,mtime_ts); /* change time */
3408 SIVAL(pdata,32,allocation_size);
3409 SOFF_T(pdata,40,file_size);
3410 SIVAL(pdata,48,mode);
3411 SIVAL(pdata,52,0); /* ??? */
3415 case SMB_FILE_ATTRIBUTE_TAG_INFORMATION:
3416 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_ATTRIBUTE_TAG_INFORMATION\n"));
3417 SIVAL(pdata,0,mode);
3423 * CIFS UNIX Extensions.
3426 case SMB_QUERY_FILE_UNIX_BASIC:
3428 DEBUG(10,("call_trans2qfilepathinfo: SMB_QUERY_FILE_UNIX_BASIC\n"));
3429 DEBUG(4,("call_trans2qfilepathinfo: st_mode=%o\n",(int)sbuf.st_mode));
3431 SOFF_T(pdata,0,get_file_size(sbuf)); /* File size 64 Bit */
3434 SOFF_T(pdata,0,get_allocation_size(conn,fsp,&sbuf)); /* Number of bytes used on disk - 64 Bit */
3437 put_long_date_timespec(pdata,get_ctimespec(&sbuf)); /* Creation Time 64 Bit */
3438 put_long_date_timespec(pdata+8,get_atimespec(&sbuf)); /* Last access time 64 Bit */
3439 put_long_date_timespec(pdata+16,get_mtimespec(&sbuf)); /* Last modification time 64 Bit */
3442 SIVAL(pdata,0,sbuf.st_uid); /* user id for the owner */
3446 SIVAL(pdata,0,sbuf.st_gid); /* group id of owner */
3450 SIVAL(pdata,0,unix_filetype(sbuf.st_mode));
3453 SIVAL(pdata,0,unix_dev_major(sbuf.st_rdev)); /* Major device number if type is device */
3457 SIVAL(pdata,0,unix_dev_minor(sbuf.st_rdev)); /* Minor device number if type is device */
3461 SINO_T_VAL(pdata,0,(SMB_INO_T)sbuf.st_ino); /* inode number */
3464 SIVAL(pdata,0, unix_perms_to_wire(sbuf.st_mode)); /* Standard UNIX file permissions */
3468 SIVAL(pdata,0,sbuf.st_nlink); /* number of hard links */
3471 data_size = PTR_DIFF(pdata,(*ppdata));
3475 DEBUG(4,("call_trans2qfilepathinfo: SMB_QUERY_FILE_UNIX_BASIC "));
3477 for (i=0; i<100; i++)
3478 DEBUG(4,("%d=%x, ",i, (*ppdata)[i]));
3484 case SMB_QUERY_FILE_UNIX_LINK:
3488 DEBUG(10,("call_trans2qfilepathinfo: SMB_QUERY_FILE_UNIX_LINK\n"));
3490 if(!S_ISLNK(sbuf.st_mode))
3491 return(UNIXERROR(ERRSRV,ERRbadlink));
3493 return(UNIXERROR(ERRDOS,ERRbadlink));
3495 len = SMB_VFS_READLINK(conn,fullpathname, buffer, sizeof(pstring)-1); /* read link */
3497 return(UNIXERROR(ERRDOS,ERRnoaccess));
3499 len = srvstr_push(outbuf, pdata, buffer, -1, STR_TERMINATE);
3501 data_size = PTR_DIFF(pdata,(*ppdata));
3506 #if defined(HAVE_POSIX_ACLS)
3507 case SMB_QUERY_POSIX_ACL:
3509 SMB_ACL_T file_acl = NULL;
3510 SMB_ACL_T def_acl = NULL;
3511 uint16 num_file_acls = 0;
3512 uint16 num_def_acls = 0;
3514 if (fsp && !fsp->is_directory && (fsp->fh->fd != -1)) {
3515 file_acl = SMB_VFS_SYS_ACL_GET_FD(fsp, fsp->fh->fd);
3517 file_acl = SMB_VFS_SYS_ACL_GET_FILE(conn, fname, SMB_ACL_TYPE_ACCESS);
3520 if (file_acl == NULL && no_acl_syscall_error(errno)) {
3521 DEBUG(5,("call_trans2qfilepathinfo: ACLs not implemented on filesystem containing %s\n",
3523 return ERROR_NT(NT_STATUS_NOT_IMPLEMENTED);
3526 if (S_ISDIR(sbuf.st_mode)) {
3527 if (fsp && fsp->is_directory) {
3528 def_acl = SMB_VFS_SYS_ACL_GET_FILE(conn, fsp->fsp_name, SMB_ACL_TYPE_DEFAULT);
3530 def_acl = SMB_VFS_SYS_ACL_GET_FILE(conn, fname, SMB_ACL_TYPE_DEFAULT);
3532 def_acl = free_empty_sys_acl(conn, def_acl);
3535 num_file_acls = count_acl_entries(conn, file_acl);
3536 num_def_acls = count_acl_entries(conn, def_acl);
3538 if ( data_size < (num_file_acls + num_def_acls)*SMB_POSIX_ACL_ENTRY_SIZE + SMB_POSIX_ACL_HEADER_SIZE) {
3539 DEBUG(5,("call_trans2qfilepathinfo: data_size too small (%u) need %u\n",
3541 (unsigned int)((num_file_acls + num_def_acls)*SMB_POSIX_ACL_ENTRY_SIZE +
3542 SMB_POSIX_ACL_HEADER_SIZE) ));
3544 SMB_VFS_SYS_ACL_FREE_ACL(conn, file_acl);
3547 SMB_VFS_SYS_ACL_FREE_ACL(conn, def_acl);
3549 return ERROR_NT(NT_STATUS_BUFFER_TOO_SMALL);
3552 SSVAL(pdata,0,SMB_POSIX_ACL_VERSION);
3553 SSVAL(pdata,2,num_file_acls);
3554 SSVAL(pdata,4,num_def_acls);
3555 if (!marshall_posix_acl(conn, pdata + SMB_POSIX_ACL_HEADER_SIZE, &sbuf, file_acl)) {
3557 SMB_VFS_SYS_ACL_FREE_ACL(conn, file_acl);
3560 SMB_VFS_SYS_ACL_FREE_ACL(conn, def_acl);
3562 return ERROR_NT(NT_STATUS_INTERNAL_ERROR);
3564 if (!marshall_posix_acl(conn, pdata + SMB_POSIX_ACL_HEADER_SIZE + (num_file_acls*SMB_POSIX_ACL_ENTRY_SIZE), &sbuf, def_acl)) {
3566 SMB_VFS_SYS_ACL_FREE_ACL(conn, file_acl);
3569 SMB_VFS_SYS_ACL_FREE_ACL(conn, def_acl);
3571 return ERROR_NT(NT_STATUS_INTERNAL_ERROR);
3575 SMB_VFS_SYS_ACL_FREE_ACL(conn, file_acl);
3578 SMB_VFS_SYS_ACL_FREE_ACL(conn, def_acl);
3580 data_size = (num_file_acls + num_def_acls)*SMB_POSIX_ACL_ENTRY_SIZE + SMB_POSIX_ACL_HEADER_SIZE;
3586 case SMB_QUERY_POSIX_LOCK:
3588 NTSTATUS status = NT_STATUS_INVALID_LEVEL;
3590 SMB_BIG_UINT offset;
3592 enum brl_type lock_type;
3594 if (total_data != POSIX_LOCK_DATA_SIZE) {
3595 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
3598 switch (SVAL(pdata, POSIX_LOCK_TYPE_OFFSET)) {
3599 case POSIX_LOCK_TYPE_READ:
3600 lock_type = READ_LOCK;
3602 case POSIX_LOCK_TYPE_WRITE:
3603 lock_type = WRITE_LOCK;
3605 case POSIX_LOCK_TYPE_UNLOCK:
3607 /* There's no point in asking for an unlock... */
3608 talloc_destroy(data_ctx);
3609 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
3612 lock_pid = IVAL(pdata, POSIX_LOCK_PID_OFFSET);
3613 #if defined(HAVE_LONGLONG)
3614 offset = (((SMB_BIG_UINT) IVAL(pdata,(POSIX_LOCK_START_OFFSET+4))) << 32) |
3615 ((SMB_BIG_UINT) IVAL(pdata,POSIX_LOCK_START_OFFSET));
3616 count = (((SMB_BIG_UINT) IVAL(pdata,(POSIX_LOCK_LEN_OFFSET+4))) << 32) |
3617 ((SMB_BIG_UINT) IVAL(pdata,POSIX_LOCK_LEN_OFFSET));
3618 #else /* HAVE_LONGLONG */
3619 offset = (SMB_BIG_UINT)IVAL(pdata,POSIX_LOCK_START_OFFSET);
3620 count = (SMB_BIG_UINT)IVAL(pdata,POSIX_LOCK_LEN_OFFSET);
3621 #endif /* HAVE_LONGLONG */
3623 status = query_lock(fsp,
3630 if (ERROR_WAS_LOCK_DENIED(status)) {
3631 /* Here we need to report who has it locked... */
3632 data_size = POSIX_LOCK_DATA_SIZE;
3634 SSVAL(pdata, POSIX_LOCK_TYPE_OFFSET, lock_type);
3635 SSVAL(pdata, POSIX_LOCK_FLAGS_OFFSET, 0);
3636 SIVAL(pdata, POSIX_LOCK_PID_OFFSET, lock_pid);
3637 #if defined(HAVE_LONGLONG)
3638 SIVAL(pdata, POSIX_LOCK_START_OFFSET, (uint32)(offset & 0xFFFFFFFF));
3639 SIVAL(pdata, POSIX_LOCK_START_OFFSET + 4, (uint32)((offset >> 32) & 0xFFFFFFFF));
3640 SIVAL(pdata, POSIX_LOCK_LEN_OFFSET, (uint32)(count & 0xFFFFFFFF));
3641 SIVAL(pdata, POSIX_LOCK_LEN_OFFSET + 4, (uint32)((count >> 32) & 0xFFFFFFFF));
3642 #else /* HAVE_LONGLONG */
3643 SIVAL(pdata, POSIX_LOCK_START_OFFSET, offset);
3644 SIVAL(pdata, POSIX_LOCK_LEN_OFFSET, count);
3645 #endif /* HAVE_LONGLONG */
3647 } else if (NT_STATUS_IS_OK(status)) {
3648 /* For success we just return a copy of what we sent
3649 with the lock type set to POSIX_LOCK_TYPE_UNLOCK. */
3650 data_size = POSIX_LOCK_DATA_SIZE;
3651 memcpy(pdata, lock_data, POSIX_LOCK_DATA_SIZE);
3652 SSVAL(pdata, POSIX_LOCK_TYPE_OFFSET, POSIX_LOCK_TYPE_UNLOCK);
3654 return ERROR_NT(status);
3660 return ERROR_NT(NT_STATUS_INVALID_LEVEL);
3663 send_trans2_replies(outbuf, bufsize, params, param_size, *ppdata, data_size, max_data_bytes);
3668 /****************************************************************************
3669 Set a hard link (called by UNIX extensions and by NT rename with HARD link
3671 ****************************************************************************/
3673 NTSTATUS hardlink_internals(connection_struct *conn, char *oldname, char *newname)
3675 BOOL bad_path_oldname = False;
3676 BOOL bad_path_newname = False;
3677 SMB_STRUCT_STAT sbuf1, sbuf2;
3678 pstring last_component_oldname;
3679 pstring last_component_newname;
3680 NTSTATUS status = NT_STATUS_OK;
3686 if (ms_has_wild(newname) || ms_has_wild(oldname)) {
3687 return NT_STATUS_OBJECT_PATH_SYNTAX_BAD;
3690 unix_convert(oldname,conn,last_component_oldname,&bad_path_oldname,&sbuf1);
3691 if (bad_path_oldname) {
3692 return NT_STATUS_OBJECT_PATH_NOT_FOUND;
3695 /* Quick check for "." and ".." */
3696 if (last_component_oldname[0] == '.') {
3697 if (!last_component_oldname[1] || (last_component_oldname[1] == '.' && !last_component_oldname[2])) {
3698 return NT_STATUS_OBJECT_NAME_INVALID;
3702 /* source must already exist. */
3703 if (!VALID_STAT(sbuf1)) {
3704 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3707 if (!check_name(oldname,conn)) {
3708 return NT_STATUS_ACCESS_DENIED;
3711 unix_convert(newname,conn,last_component_newname,&bad_path_newname,&sbuf2);
3712 if (bad_path_newname) {
3713 return NT_STATUS_OBJECT_PATH_NOT_FOUND;
3716 /* Quick check for "." and ".." */
3717 if (last_component_newname[0] == '.') {
3718 if (!last_component_newname[1] || (last_component_newname[1] == '.' && !last_component_newname[2])) {
3719 return NT_STATUS_OBJECT_NAME_INVALID;
3723 /* Disallow if newname already exists. */
3724 if (VALID_STAT(sbuf2)) {
3725 return NT_STATUS_OBJECT_NAME_COLLISION;
3728 if (!check_name(newname,conn)) {
3729 return NT_STATUS_ACCESS_DENIED;
3732 /* No links from a directory. */
3733 if (S_ISDIR(sbuf1.st_mode)) {
3734 return NT_STATUS_FILE_IS_A_DIRECTORY;
3737 /* Ensure this is within the share. */
3738 if (!reduce_name(conn, oldname) != 0)
3739 return NT_STATUS_ACCESS_DENIED;
3741 DEBUG(10,("hardlink_internals: doing hard link %s -> %s\n", newname, oldname ));
3743 if (SMB_VFS_LINK(conn,oldname,newname) != 0) {
3744 status = map_nt_error_from_unix(errno);
3745 DEBUG(3,("hardlink_internals: Error %s hard link %s -> %s\n",
3746 nt_errstr(status), newname, oldname));
3752 /****************************************************************************
3753 Reply to a TRANS2_SETFILEINFO (set file info by fileid).
3754 ****************************************************************************/
3756 static int call_trans2setfilepathinfo(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize,
3757 unsigned int tran_call,
3758 char **pparams, int total_params, char **ppdata, int total_data,
3759 unsigned int max_data_bytes)
3761 char *params = *pparams;
3762 char *pdata = *ppdata;
3767 SMB_STRUCT_STAT sbuf;
3770 BOOL bad_path = False;
3771 files_struct *fsp = NULL;
3772 uid_t set_owner = (uid_t)SMB_UID_NO_CHANGE;
3773 gid_t set_grp = (uid_t)SMB_GID_NO_CHANGE;
3774 mode_t unixmode = 0;
3775 NTSTATUS status = NT_STATUS_OK;
3778 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
3783 if (tran_call == TRANSACT2_SETFILEINFO) {
3784 if (total_params < 4) {
3785 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
3788 fsp = file_fsp(params,0);
3789 info_level = SVAL(params,2);
3791 if(fsp && (fsp->is_directory || fsp->fh->fd == -1)) {
3793 * This is actually a SETFILEINFO on a directory
3794 * handle (returned from an NT SMB). NT5.0 seems
3795 * to do this call. JRA.
3797 pstrcpy(fname, fsp->fsp_name);
3798 if (SMB_VFS_STAT(conn,fname,&sbuf) != 0) {
3799 DEBUG(3,("call_trans2setfilepathinfo: fileinfo of %s failed (%s)\n",fname,strerror(errno)));
3800 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRbadpath);
3802 } else if (fsp && fsp->print_file) {
3804 * Doing a DELETE_ON_CLOSE should cancel a print job.
3806 if ((info_level == SMB_SET_FILE_DISPOSITION_INFO) && CVAL(pdata,0)) {
3807 fsp->fh->private_options |= FILE_DELETE_ON_CLOSE;
3809 DEBUG(3,("call_trans2setfilepathinfo: Cancelling print job (%s)\n", fsp->fsp_name ));
3812 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0, max_data_bytes);
3815 return (UNIXERROR(ERRDOS,ERRbadpath));
3818 * Original code - this is an open file.
3820 CHECK_FSP(fsp,conn);
3822 pstrcpy(fname, fsp->fsp_name);
3825 if (SMB_VFS_FSTAT(fsp,fd,&sbuf) != 0) {
3826 DEBUG(3,("call_trans2setfilepathinfo: fstat of fnum %d failed (%s)\n",fsp->fnum, strerror(errno)));
3827 return(UNIXERROR(ERRDOS,ERRbadfid));
3832 if (total_params < 6) {
3833 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
3836 info_level = SVAL(params,0);
3837 srvstr_get_path(inbuf, fname, ¶ms[6], sizeof(fname), -1, STR_TERMINATE, &status);
3838 if (!NT_STATUS_IS_OK(status)) {
3839 return ERROR_NT(status);
3841 unix_convert(fname,conn,0,&bad_path,&sbuf);
3843 return ERROR_NT(NT_STATUS_OBJECT_PATH_NOT_FOUND);
3847 * For CIFS UNIX extensions the target name may not exist.
3850 if(!VALID_STAT(sbuf) && !INFO_LEVEL_IS_UNIX(info_level)) {
3851 DEBUG(3,("call_trans2setfilepathinfo: stat of %s failed (%s)\n", fname, strerror(errno)));
3852 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRbadpath);
3855 if(!check_name(fname, conn)) {
3856 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRbadpath);
3861 if (!CAN_WRITE(conn))
3862 return ERROR_DOS(ERRSRV,ERRaccess);
3864 if (INFO_LEVEL_IS_UNIX(info_level) && !lp_unix_extensions()) {
3865 return ERROR_NT(NT_STATUS_INVALID_LEVEL);
3868 if (VALID_STAT(sbuf))
3869 unixmode = sbuf.st_mode;
3871 DEBUG(3,("call_trans2setfilepathinfo(%d) %s (fnum %d) info_level=%d totdata=%d\n",
3872 tran_call,fname, fsp ? fsp->fnum : -1, info_level,total_data));
3874 /* Realloc the parameter size */
3875 *pparams = (char *)SMB_REALLOC(*pparams,2);
3876 if (*pparams == NULL) {
3877 return ERROR_NT(NT_STATUS_NO_MEMORY);
3883 if (fsp && fsp->pending_modtime) {
3884 /* the pending modtime overrides the current modtime */
3885 sbuf.st_mtime = fsp->pending_modtime;
3888 size = get_file_size(sbuf);
3889 tvs.modtime = sbuf.st_mtime;
3890 tvs.actime = sbuf.st_atime;
3891 dosmode = dos_mode(conn,fname,&sbuf);
3892 unixmode = sbuf.st_mode;
3894 set_owner = VALID_STAT(sbuf) ? sbuf.st_uid : (uid_t)SMB_UID_NO_CHANGE;
3895 set_grp = VALID_STAT(sbuf) ? sbuf.st_gid : (gid_t)SMB_GID_NO_CHANGE;
3897 switch (info_level) {
3898 case SMB_INFO_STANDARD:
3900 if (total_data < 12) {
3901 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
3905 tvs.actime = srv_make_unix_date2(pdata+l1_fdateLastAccess);
3907 tvs.modtime = srv_make_unix_date2(pdata+l1_fdateLastWrite);
3911 case SMB_INFO_SET_EA:
3913 struct ea_list *ea_list = NULL;
3914 TALLOC_CTX *ctx = NULL;
3916 if (total_data < 10) {
3918 /* OS/2 workplace shell seems to send SET_EA requests of "null"
3919 length. They seem to have no effect. Bug #3212. JRA */
3921 if ((total_data == 4) && (IVAL(pdata,0) == 4)) {
3922 /* We're done. We only get EA info in this call. */
3924 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0, max_data_bytes);
3928 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
3931 if (IVAL(pdata,0) > total_data) {
3932 DEBUG(10,("call_trans2setfilepathinfo: bad total data size (%u) > %u\n",
3933 IVAL(pdata,0), (unsigned int)total_data));
3934 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
3937 ctx = talloc_init("SMB_INFO_SET_EA");
3939 return ERROR_NT(NT_STATUS_NO_MEMORY);
3941 ea_list = read_ea_list(ctx, pdata + 4, total_data - 4);
3943 talloc_destroy(ctx);
3944 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
3946 status = set_ea(conn, fsp, fname, ea_list);
3947 talloc_destroy(ctx);
3949 if (!NT_STATUS_IS_OK(status)) {
3950 return ERROR_NT(status);
3953 /* We're done. We only get EA info in this call. */
3955 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0, max_data_bytes);
3960 /* The following 2 info levels are only valid on query, not set. Remove them. JRA. */
3961 /* XXXX um, i don't think this is right.
3962 it's also not in the cifs6.txt spec.
3964 case SMB_INFO_QUERY_EAS_FROM_LIST:
3965 if (total_data < 28)
3966 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
3968 tvs.actime = make_unix_date2(pdata+8);
3969 tvs.modtime = make_unix_date2(pdata+12);
3970 size = IVAL(pdata,16);
3971 dosmode = IVAL(pdata,24);
3974 /* XXXX nor this. not in cifs6.txt, either. */
3975 case SMB_INFO_QUERY_ALL_EAS:
3976 if (total_data < 28)
3977 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
3979 tvs.actime = make_unix_date2(pdata+8);
3980 tvs.modtime = make_unix_date2(pdata+12);
3981 size = IVAL(pdata,16);
3982 dosmode = IVAL(pdata,24);
3986 case SMB_SET_FILE_BASIC_INFO:
3987 case SMB_FILE_BASIC_INFORMATION:
3989 /* Patch to do this correctly from Paul Eggert <eggert@twinsun.com>. */
3991 time_t changed_time;
3993 if (total_data < 36) {
3994 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
3997 /* Ignore create time at offset pdata. */
4000 tvs.actime = convert_timespec_to_time_t(interpret_long_date(pdata+8));
4002 write_time = convert_timespec_to_time_t(interpret_long_date(pdata+16));
4003 changed_time = convert_timespec_to_time_t(interpret_long_date(pdata+24));
4005 tvs.modtime = MIN(write_time, changed_time);
4007 if (write_time > tvs.modtime && write_time != (time_t)-1) {
4008 tvs.modtime = write_time;
4010 /* Prefer a defined time to an undefined one. */
4011 if (null_mtime(tvs.modtime)) {
4012 tvs.modtime = null_mtime(write_time) ? changed_time : write_time;
4016 dosmode = IVAL(pdata,32);
4020 case SMB_FILE_ALLOCATION_INFORMATION:
4021 case SMB_SET_FILE_ALLOCATION_INFO:
4024 SMB_BIG_UINT allocation_size;
4026 if (total_data < 8) {
4027 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
4030 allocation_size = (SMB_BIG_UINT)IVAL(pdata,0);
4031 #ifdef LARGE_SMB_OFF_T
4032 allocation_size |= (((SMB_BIG_UINT)IVAL(pdata,4)) << 32);
4033 #else /* LARGE_SMB_OFF_T */
4034 if (IVAL(pdata,4) != 0) {
4035 /* more than 32 bits? */
4036 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
4038 #endif /* LARGE_SMB_OFF_T */
4039 DEBUG(10,("call_trans2setfilepathinfo: Set file allocation info for file %s to %.0f\n",
4040 fname, (double)allocation_size ));
4042 if (allocation_size) {
4043 allocation_size = smb_roundup(conn, allocation_size);
4046 if(allocation_size != get_file_size(sbuf)) {
4047 SMB_STRUCT_STAT new_sbuf;
4049 DEBUG(10,("call_trans2setfilepathinfo: file %s : setting new allocation size to %.0f\n",
4050 fname, (double)allocation_size ));
4053 files_struct *new_fsp = NULL;
4055 status = open_file_ntcreate(conn, fname, &sbuf,
4057 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4060 FILE_ATTRIBUTE_NORMAL,
4061 FORCE_OPLOCK_BREAK_TO_NONE,
4064 if (!NT_STATUS_IS_OK(status)) {
4065 if (open_was_deferred(SVAL(inbuf,smb_mid))) {
4066 /* We have re-scheduled this call. */
4069 return(UNIXERROR(ERRDOS,ERRnoaccess));
4071 ret = vfs_allocate_file_space(new_fsp, allocation_size);
4072 if (SMB_VFS_FSTAT(new_fsp,new_fsp->fh->fd,&new_sbuf) != 0) {
4073 DEBUG(3,("call_trans2setfilepathinfo: fstat of fnum %d failed (%s)\n",
4074 new_fsp->fnum, strerror(errno)));
4077 close_file(new_fsp,NORMAL_CLOSE);
4079 ret = vfs_allocate_file_space(fsp, allocation_size);
4080 if (SMB_VFS_FSTAT(fsp,fd,&new_sbuf) != 0) {
4081 DEBUG(3,("call_trans2setfilepathinfo: fstat of fnum %d failed (%s)\n",
4082 fsp->fnum, strerror(errno)));
4087 return ERROR_NT(NT_STATUS_DISK_FULL);
4089 /* Allocate can truncate size... */
4090 size = get_file_size(new_sbuf);
4096 case SMB_FILE_END_OF_FILE_INFORMATION:
4097 case SMB_SET_FILE_END_OF_FILE_INFO:
4099 if (total_data < 8) {
4100 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
4103 size = IVAL(pdata,0);
4104 #ifdef LARGE_SMB_OFF_T
4105 size |= (((SMB_OFF_T)IVAL(pdata,4)) << 32);
4106 #else /* LARGE_SMB_OFF_T */
4107 if (IVAL(pdata,4) != 0) {
4108 /* more than 32 bits? */
4109 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
4111 #endif /* LARGE_SMB_OFF_T */
4112 DEBUG(10,("call_trans2setfilepathinfo: Set end of file info for file %s to %.0f\n", fname, (double)size ));
4116 case SMB_FILE_DISPOSITION_INFORMATION:
4117 case SMB_SET_FILE_DISPOSITION_INFO: /* Set delete on close for open file. */
4119 BOOL delete_on_close;
4121 if (total_data < 1) {
4122 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
4125 delete_on_close = (CVAL(pdata,0) ? True : False);
4127 /* Just ignore this set on a path. */
4128 if (tran_call != TRANSACT2_SETFILEINFO)
4132 return(UNIXERROR(ERRDOS,ERRbadfid));
4134 status = can_set_delete_on_close(fsp, delete_on_close,
4137 if (!NT_STATUS_IS_OK(status)) {
4138 return ERROR_NT(status);
4141 /* The set is across all open files on this dev/inode pair. */
4142 if (!set_delete_on_close(fsp, delete_on_close, ¤t_user.ut)) {
4143 return ERROR_NT(NT_STATUS_ACCESS_DENIED);
4147 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0, max_data_bytes);
4151 case SMB_FILE_POSITION_INFORMATION:
4153 SMB_BIG_UINT position_information;
4155 if (total_data < 8) {
4156 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
4159 position_information = (SMB_BIG_UINT)IVAL(pdata,0);
4160 #ifdef LARGE_SMB_OFF_T
4161 position_information |= (((SMB_BIG_UINT)IVAL(pdata,4)) << 32);
4162 #else /* LARGE_SMB_OFF_T */
4163 if (IVAL(pdata,4) != 0) {
4164 /* more than 32 bits? */
4165 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
4167 #endif /* LARGE_SMB_OFF_T */
4168 DEBUG(10,("call_trans2setfilepathinfo: Set file position information for file %s to %.0f\n",
4169 fname, (double)position_information ));
4171 fsp->fh->position_information = position_information;
4174 /* We're done. We only get position info in this call. */
4176 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0, max_data_bytes);
4180 /* From tridge Samba4 :
4181 * MODE_INFORMATION in setfileinfo (I have no
4182 * idea what "mode information" on a file is - it takes a value of 0,
4183 * 2, 4 or 6. What could it be?).
4186 case SMB_FILE_MODE_INFORMATION:
4190 if (total_data < 4) {
4191 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
4193 mode = IVAL(pdata,0);
4194 if (mode != 0 && mode != 2 && mode != 4 && mode != 6) {
4195 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
4198 /* We're done. We only get mode info in this call. */
4200 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0, max_data_bytes);
4205 * CIFS UNIX extensions.
4208 case SMB_SET_FILE_UNIX_BASIC:
4210 uint32 raw_unixmode;
4212 if (total_data < 100) {
4213 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
4216 if(IVAL(pdata, 0) != SMB_SIZE_NO_CHANGE_LO &&
4217 IVAL(pdata, 4) != SMB_SIZE_NO_CHANGE_HI) {
4218 size=IVAL(pdata,0); /* first 8 Bytes are size */
4219 #ifdef LARGE_SMB_OFF_T
4220 size |= (((SMB_OFF_T)IVAL(pdata,4)) << 32);
4221 #else /* LARGE_SMB_OFF_T */
4222 if (IVAL(pdata,4) != 0) {
4223 /* more than 32 bits? */
4224 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
4226 #endif /* LARGE_SMB_OFF_T */
4228 pdata+=24; /* ctime & st_blocks are not changed */
4229 tvs.actime = convert_timespec_to_time_t(interpret_long_date(pdata)); /* access_time */
4230 tvs.modtime = convert_timespec_to_time_t(interpret_long_date(pdata+8)); /* modification_time */
4232 set_owner = (uid_t)IVAL(pdata,0);
4234 set_grp = (gid_t)IVAL(pdata,0);
4236 raw_unixmode = IVAL(pdata,28);
4237 unixmode = unix_perms_from_wire(conn, &sbuf, raw_unixmode);
4238 dosmode = 0; /* Ensure dos mode change doesn't override this. */
4240 DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_BASIC: name = %s \
4241 size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n",
4242 fname, (double)size, (unsigned int)set_owner, (unsigned int)set_grp, (int)raw_unixmode));
4244 if (!VALID_STAT(sbuf)) {
4247 * The only valid use of this is to create character and block
4248 * devices, and named pipes. This is deprecated (IMHO) and
4249 * a new info level should be used for mknod. JRA.
4252 uint32 file_type = IVAL(pdata,0);
4253 #if defined(HAVE_MAKEDEV)
4254 uint32 dev_major = IVAL(pdata,4);
4255 uint32 dev_minor = IVAL(pdata,12);
4258 uid_t myuid = geteuid();
4259 gid_t mygid = getegid();
4260 SMB_DEV_T dev = (SMB_DEV_T)0;
4262 if (tran_call == TRANSACT2_SETFILEINFO)
4263 return(ERROR_DOS(ERRDOS,ERRnoaccess));
4265 if (raw_unixmode == SMB_MODE_NO_CHANGE) {
4266 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
4269 #if defined(HAVE_MAKEDEV)
4270 dev = makedev(dev_major, dev_minor);
4273 /* We can only create as the owner/group we are. */
4275 if ((set_owner != myuid) && (set_owner != (uid_t)SMB_UID_NO_CHANGE))
4276 return(ERROR_DOS(ERRDOS,ERRnoaccess));
4277 if ((set_grp != mygid) && (set_grp != (gid_t)SMB_GID_NO_CHANGE))
4278 return(ERROR_DOS(ERRDOS,ERRnoaccess));
4280 switch (file_type) {
4281 #if defined(S_IFIFO)
4282 case UNIX_TYPE_FIFO:
4283 unixmode |= S_IFIFO;
4286 #if defined(S_IFSOCK)
4287 case UNIX_TYPE_SOCKET:
4288 unixmode |= S_IFSOCK;
4291 #if defined(S_IFCHR)
4292 case UNIX_TYPE_CHARDEV:
4293 unixmode |= S_IFCHR;
4296 #if defined(S_IFBLK)
4297 case UNIX_TYPE_BLKDEV:
4298 unixmode |= S_IFBLK;
4302 return(ERROR_DOS(ERRDOS,ERRnoaccess));
4305 DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_BASIC doing mknod dev %.0f mode \
4306 0%o for file %s\n", (double)dev, unixmode, fname ));
4308 /* Ok - do the mknod. */
4309 if (SMB_VFS_MKNOD(conn,fname, unixmode, dev) != 0)
4310 return(UNIXERROR(ERRDOS,ERRnoaccess));
4312 inherit_access_acl(conn, fname, unixmode);
4315 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0, max_data_bytes);
4320 * Deal with the UNIX specific mode set.
4323 if (raw_unixmode != SMB_MODE_NO_CHANGE) {
4324 DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_BASIC setting mode 0%o for file %s\n",
4325 (unsigned int)unixmode, fname ));
4326 if (SMB_VFS_CHMOD(conn,fname,unixmode) != 0)
4327 return(UNIXERROR(ERRDOS,ERRnoaccess));
4331 * Deal with the UNIX specific uid set.
4334 if ((set_owner != (uid_t)SMB_UID_NO_CHANGE) && (sbuf.st_uid != set_owner)) {
4335 DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_BASIC changing owner %u for file %s\n",
4336 (unsigned int)set_owner, fname ));
4337 if (SMB_VFS_CHOWN(conn,fname,set_owner, (gid_t)-1) != 0)
4338 return(UNIXERROR(ERRDOS,ERRnoaccess));
4342 * Deal with the UNIX specific gid set.
4345 if ((set_grp != (uid_t)SMB_GID_NO_CHANGE) && (sbuf.st_gid != set_grp)) {
4346 DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_BASIC changing group %u for file %s\n",
4347 (unsigned int)set_owner, fname ));
4348 if (SMB_VFS_CHOWN(conn,fname,(uid_t)-1, set_grp) != 0)
4349 return(UNIXERROR(ERRDOS,ERRnoaccess));
4354 case SMB_SET_FILE_UNIX_LINK:
4356 pstring link_target;
4357 char *newname = fname;
4359 /* Set a symbolic link. */
4360 /* Don't allow this if follow links is false. */
4362 if (!lp_symlinks(SNUM(conn)))
4363 return(ERROR_DOS(ERRDOS,ERRnoaccess));
4365 srvstr_pull(inbuf, link_target, pdata, sizeof(link_target), -1, STR_TERMINATE);
4367 /* !widelinks forces the target path to be within the share. */
4368 /* This means we can interpret the target as a pathname. */
4369 if (!lp_widelinks(SNUM(conn))) {
4371 char *last_dirp = NULL;
4373 unix_format(link_target);
4374 if (*link_target == '/') {
4375 /* No absolute paths allowed. */
4376 return(UNIXERROR(ERRDOS,ERRnoaccess));
4378 pstrcpy(rel_name, newname);
4379 last_dirp = strrchr_m(rel_name, '/');
4381 last_dirp[1] = '\0';
4383 pstrcpy(rel_name, "./");
4385 pstrcat(rel_name, link_target);
4387 if (!check_name(rel_name, conn)) {
4388 return(UNIXERROR(ERRDOS,ERRnoaccess));
4392 DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_LINK doing symlink %s -> %s\n",
4393 fname, link_target ));
4395 if (SMB_VFS_SYMLINK(conn,link_target,newname) != 0)
4396 return(UNIXERROR(ERRDOS,ERRnoaccess));
4398 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0, max_data_bytes);
4402 case SMB_SET_FILE_UNIX_HLINK:
4405 char *newname = fname;
4407 /* Set a hard link. */
4408 srvstr_get_path(inbuf, oldname, pdata, sizeof(oldname), -1, STR_TERMINATE, &status);
4409 if (!NT_STATUS_IS_OK(status)) {
4410 return ERROR_NT(status);
4413 DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_LINK doing hard link %s -> %s\n",
4416 status = hardlink_internals(conn, oldname, newname);
4417 if (!NT_STATUS_IS_OK(status)) {
4418 return ERROR_NT(status);
4422 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0, max_data_bytes);
4426 case SMB_FILE_RENAME_INFORMATION:
4429 /* uint32 root_fid; */ /* Not used */
4435 if (total_data < 12) {
4436 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
4439 overwrite = (CVAL(pdata,0) ? True : False);
4440 /* root_fid = IVAL(pdata,4); */
4441 len = IVAL(pdata,8);
4442 srvstr_get_path(inbuf, newname, &pdata[12], sizeof(newname), len, 0, &status);
4443 if (!NT_STATUS_IS_OK(status)) {
4444 return ERROR_NT(status);
4447 /* Check the new name has no '/' characters. */
4448 if (strchr_m(newname, '/'))
4449 return ERROR_NT(NT_STATUS_NOT_SUPPORTED);
4451 RESOLVE_DFSPATH(newname, conn, inbuf, outbuf);
4453 /* Create the base directory. */
4454 pstrcpy(base_name, fname);
4455 p = strrchr_m(base_name, '/');
4458 /* Append the new name. */
4459 pstrcat(base_name, "/");
4460 pstrcat(base_name, newname);
4463 DEBUG(10,("call_trans2setfilepathinfo: SMB_FILE_RENAME_INFORMATION (fnum %d) %s -> %s\n",
4464 fsp->fnum, fsp->fsp_name, base_name ));
4465 status = rename_internals_fsp(conn, fsp, base_name, 0, overwrite);
4467 DEBUG(10,("call_trans2setfilepathinfo: SMB_FILE_RENAME_INFORMATION %s -> %s\n",
4469 status = rename_internals(conn, fname, base_name, 0, overwrite, False);
4471 if (!NT_STATUS_IS_OK(status)) {
4472 return ERROR_NT(status);
4474 process_pending_change_notify_queue((time_t)0);
4476 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0, max_data_bytes);
4480 #if defined(HAVE_POSIX_ACLS)
4481 case SMB_SET_POSIX_ACL:
4483 uint16 posix_acl_version;
4484 uint16 num_file_acls;
4485 uint16 num_def_acls;
4486 BOOL valid_file_acls = True;
4487 BOOL valid_def_acls = True;
4489 if (total_data < SMB_POSIX_ACL_HEADER_SIZE) {
4490 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
4492 posix_acl_version = SVAL(pdata,0);
4493 num_file_acls = SVAL(pdata,2);
4494 num_def_acls = SVAL(pdata,4);
4496 if (num_file_acls == SMB_POSIX_IGNORE_ACE_ENTRIES) {
4497 valid_file_acls = False;
4501 if (num_def_acls == SMB_POSIX_IGNORE_ACE_ENTRIES) {
4502 valid_def_acls = False;
4506 if (posix_acl_version != SMB_POSIX_ACL_VERSION) {
4507 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
4510 if (total_data < SMB_POSIX_ACL_HEADER_SIZE +
4511 (num_file_acls+num_def_acls)*SMB_POSIX_ACL_ENTRY_SIZE) {
4512 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
4515 if (valid_file_acls && !set_unix_posix_acl(conn, fsp, fname, num_file_acls,
4516 pdata + SMB_POSIX_ACL_HEADER_SIZE)) {
4517 return(UNIXERROR(ERRDOS,ERRnoaccess));
4520 if (valid_def_acls && !set_unix_posix_default_acl(conn, fname, &sbuf, num_def_acls,
4521 pdata + SMB_POSIX_ACL_HEADER_SIZE +
4522 (num_file_acls*SMB_POSIX_ACL_ENTRY_SIZE))) {
4523 return(UNIXERROR(ERRDOS,ERRnoaccess));
4527 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0, max_data_bytes);
4532 case SMB_SET_POSIX_LOCK:
4535 SMB_BIG_UINT offset;
4537 BOOL blocking_lock = False;
4538 enum brl_type lock_type;
4540 if (fsp == NULL || fsp->fh->fd == -1) {
4541 return ERROR_NT(NT_STATUS_INVALID_HANDLE);
4544 if (total_data != POSIX_LOCK_DATA_SIZE) {
4545 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
4548 switch (SVAL(pdata, POSIX_LOCK_TYPE_OFFSET)) {
4549 case POSIX_LOCK_TYPE_READ:
4550 lock_type = READ_LOCK;
4552 case POSIX_LOCK_TYPE_WRITE:
4553 /* Return the right POSIX-mappable error code for files opened read-only. */
4554 if (!fsp->can_write) {
4555 return ERROR_NT(NT_STATUS_INVALID_HANDLE);
4557 lock_type = WRITE_LOCK;
4559 case POSIX_LOCK_TYPE_UNLOCK:
4560 lock_type = UNLOCK_LOCK;
4563 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
4566 if (SVAL(pdata,POSIX_LOCK_FLAGS_OFFSET) == POSIX_LOCK_FLAG_NOWAIT) {
4567 blocking_lock = False;
4568 } else if (SVAL(pdata,POSIX_LOCK_FLAGS_OFFSET) == POSIX_LOCK_FLAG_WAIT) {
4569 blocking_lock = True;
4571 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
4574 if (!lp_blocking_locks(SNUM(conn))) {
4575 blocking_lock = False;
4578 lock_pid = IVAL(pdata, POSIX_LOCK_PID_OFFSET);
4579 #if defined(HAVE_LONGLONG)
4580 offset = (((SMB_BIG_UINT) IVAL(pdata,(POSIX_LOCK_START_OFFSET+4))) << 32) |
4581 ((SMB_BIG_UINT) IVAL(pdata,POSIX_LOCK_START_OFFSET));
4582 count = (((SMB_BIG_UINT) IVAL(pdata,(POSIX_LOCK_LEN_OFFSET+4))) << 32) |
4583 ((SMB_BIG_UINT) IVAL(pdata,POSIX_LOCK_LEN_OFFSET));
4584 #else /* HAVE_LONGLONG */
4585 offset = (SMB_BIG_UINT)IVAL(pdata,POSIX_LOCK_START_OFFSET);
4586 count = (SMB_BIG_UINT)IVAL(pdata,POSIX_LOCK_LEN_OFFSET);
4587 #endif /* HAVE_LONGLONG */
4589 if (lock_type == UNLOCK_LOCK) {
4590 status = do_unlock(fsp,
4596 struct byte_range_lock *br_lck = do_lock(fsp,
4605 if (br_lck && blocking_lock && ERROR_WAS_LOCK_DENIED(status)) {
4607 * A blocking lock was requested. Package up
4608 * this smb into a queued request and push it
4609 * onto the blocking lock queue.
4611 if(push_blocking_lock_request(br_lck,
4614 -1, /* infinite timeout. */
4621 TALLOC_FREE(br_lck);
4625 TALLOC_FREE(br_lck);
4628 if (!NT_STATUS_IS_OK(status)) {
4629 return ERROR_NT(status);
4633 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0, max_data_bytes);
4638 return ERROR_NT(NT_STATUS_INVALID_LEVEL);
4641 /* get some defaults (no modifications) if any info is zero or -1. */
4642 if (null_mtime(tvs.actime)) {
4643 tvs.actime = sbuf.st_atime;
4646 if (null_mtime(tvs.modtime)) {
4647 tvs.modtime = sbuf.st_mtime;
4650 DEBUG(6,("actime: %s " , ctime(&tvs.actime)));
4651 DEBUG(6,("modtime: %s ", ctime(&tvs.modtime)));
4652 DEBUG(6,("size: %.0f ", (double)size));
4655 if (S_ISDIR(sbuf.st_mode))
4661 DEBUG(6,("dosmode: %x\n" , dosmode));
4663 if(!((info_level == SMB_SET_FILE_END_OF_FILE_INFO) ||
4664 (info_level == SMB_SET_FILE_ALLOCATION_INFO) ||
4665 (info_level == SMB_FILE_ALLOCATION_INFORMATION) ||
4666 (info_level == SMB_FILE_END_OF_FILE_INFORMATION))) {
4669 * Only do this test if we are not explicitly
4670 * changing the size of a file.
4673 size = get_file_size(sbuf);
4677 * Try and set the times, size and mode of this file -
4678 * if they are different from the current values
4681 /* check the mode isn't different, before changing it */
4682 if ((dosmode != 0) && (dosmode != dos_mode(conn, fname, &sbuf))) {
4684 DEBUG(10,("call_trans2setfilepathinfo: file %s : setting dos mode %x\n", fname, dosmode ));
4686 if(file_set_dosmode(conn, fname, dosmode, &sbuf, False)) {
4687 DEBUG(2,("file_set_dosmode of %s failed (%s)\n", fname, strerror(errno)));
4688 return(UNIXERROR(ERRDOS,ERRnoaccess));
4693 if (size != get_file_size(sbuf)) {
4697 DEBUG(10,("call_trans2setfilepathinfo: file %s : setting new size to %.0f\n",
4698 fname, (double)size ));
4701 files_struct *new_fsp = NULL;
4703 status = open_file_ntcreate(conn, fname, &sbuf,
4705 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4708 FILE_ATTRIBUTE_NORMAL,
4709 FORCE_OPLOCK_BREAK_TO_NONE,
4712 if (!NT_STATUS_IS_OK(status)) {
4713 if (open_was_deferred(SVAL(inbuf,smb_mid))) {
4714 /* We have re-scheduled this call. */
4717 return(UNIXERROR(ERRDOS,ERRnoaccess));
4719 ret = vfs_set_filelen(new_fsp, size);
4720 close_file(new_fsp,NORMAL_CLOSE);
4722 ret = vfs_set_filelen(fsp, size);
4726 return (UNIXERROR(ERRHRD,ERRdiskfull));
4731 * Finally the times.
4733 if (sbuf.st_mtime != tvs.modtime || sbuf.st_atime != tvs.actime) {
4736 * This was a setfileinfo on an open file.
4737 * NT does this a lot. We also need to
4738 * set the time here, as it can be read by
4739 * FindFirst/FindNext and with the patch for bug #2045
4740 * in smbd/fileio.c it ensures that this timestamp is
4741 * kept sticky even after a write. We save the request
4742 * away and will set it on file close and after a write. JRA.
4745 if (tvs.modtime != (time_t)0 && tvs.modtime != (time_t)-1) {
4746 DEBUG(10,("call_trans2setfilepathinfo: setting pending modtime to %s\n", ctime(&tvs.modtime) ));
4747 fsp_set_pending_modtime(fsp, tvs.modtime);
4751 DEBUG(10,("call_trans2setfilepathinfo: setting utimes to modified values.\n"));
4753 if(file_utime(conn, fname, &tvs)!=0) {
4754 return(UNIXERROR(ERRDOS,ERRnoaccess));
4759 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0, max_data_bytes);
4764 /****************************************************************************
4765 Reply to a TRANS2_MKDIR (make directory with extended attributes).
4766 ****************************************************************************/
4768 static int call_trans2mkdir(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize,
4769 char **pparams, int total_params, char **ppdata, int total_data,
4770 unsigned int max_data_bytes)
4772 char *params = *pparams;
4773 char *pdata = *ppdata;
4776 SMB_STRUCT_STAT sbuf;
4777 BOOL bad_path = False;
4778 NTSTATUS status = NT_STATUS_OK;
4779 TALLOC_CTX *ctx = NULL;
4780 struct ea_list *ea_list = NULL;
4782 if (!CAN_WRITE(conn))
4783 return ERROR_DOS(ERRSRV,ERRaccess);
4785 if (total_params < 4) {
4786 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
4789 srvstr_get_path(inbuf, directory, ¶ms[4], sizeof(directory), -1, STR_TERMINATE, &status);
4790 if (!NT_STATUS_IS_OK(status)) {
4791 return ERROR_NT(status);
4794 DEBUG(3,("call_trans2mkdir : name = %s\n", directory));
4796 unix_convert(directory,conn,0,&bad_path,&sbuf);
4798 return ERROR_NT(NT_STATUS_OBJECT_PATH_NOT_FOUND);
4801 /* Any data in this call is an EA list. */
4802 if (total_data && (total_data != 4) && !lp_ea_support(SNUM(conn))) {
4803 return ERROR_NT(NT_STATUS_EAS_NOT_SUPPORTED);
4807 * OS/2 workplace shell seems to send SET_EA requests of "null"
4808 * length (4 bytes containing IVAL 4).
4809 * They seem to have no effect. Bug #3212. JRA.
4812 if (total_data != 4) {
4813 if (total_data < 10) {
4814 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
4817 if (IVAL(pdata,0) > total_data) {
4818 DEBUG(10,("call_trans2mkdir: bad total data size (%u) > %u\n",
4819 IVAL(pdata,0), (unsigned int)total_data));
4820 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
4823 ctx = talloc_init("TRANS2_MKDIR_SET_EA");
4825 return ERROR_NT(NT_STATUS_NO_MEMORY);
4827 ea_list = read_ea_list(ctx, pdata + 4, total_data - 4);
4829 talloc_destroy(ctx);
4830 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
4832 } else if (IVAL(pdata,0) != 4) {
4833 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
4836 if (check_name(directory,conn)) {
4837 ret = vfs_MkDir(conn,directory,unix_mode(conn,aDIR,directory,True));
4841 talloc_destroy(ctx);
4842 DEBUG(5,("call_trans2mkdir error (%s)\n", strerror(errno)));
4843 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRnoaccess);
4846 /* Try and set any given EA. */
4848 status = set_ea(conn, NULL, directory, ea_list);
4849 talloc_destroy(ctx);
4850 if (!NT_STATUS_IS_OK(status)) {
4851 return ERROR_NT(status);
4855 /* Realloc the parameter and data sizes */
4856 *pparams = (char *)SMB_REALLOC(*pparams,2);
4857 if(*pparams == NULL) {
4858 return ERROR_NT(NT_STATUS_NO_MEMORY);
4864 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0, max_data_bytes);
4869 /****************************************************************************
4870 Reply to a TRANS2_FINDNOTIFYFIRST (start monitoring a directory for changes).
4871 We don't actually do this - we just send a null response.
4872 ****************************************************************************/
4874 static int call_trans2findnotifyfirst(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize,
4875 char **pparams, int total_params, char **ppdata, int total_data,
4876 unsigned int max_data_bytes)
4878 static uint16 fnf_handle = 257;
4879 char *params = *pparams;
4882 if (total_params < 6) {
4883 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
4886 info_level = SVAL(params,4);
4887 DEBUG(3,("call_trans2findnotifyfirst - info_level %d\n", info_level));
4889 switch (info_level) {
4894 return ERROR_NT(NT_STATUS_INVALID_LEVEL);
4897 /* Realloc the parameter and data sizes */
4898 *pparams = (char *)SMB_REALLOC(*pparams,6);
4899 if (*pparams == NULL) {
4900 return ERROR_NT(NT_STATUS_NO_MEMORY);
4904 SSVAL(params,0,fnf_handle);
4905 SSVAL(params,2,0); /* No changes */
4906 SSVAL(params,4,0); /* No EA errors */
4913 send_trans2_replies(outbuf, bufsize, params, 6, *ppdata, 0, max_data_bytes);
4918 /****************************************************************************
4919 Reply to a TRANS2_FINDNOTIFYNEXT (continue monitoring a directory for
4920 changes). Currently this does nothing.
4921 ****************************************************************************/
4923 static int call_trans2findnotifynext(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize,
4924 char **pparams, int total_params, char **ppdata, int total_data,
4925 unsigned int max_data_bytes)
4927 char *params = *pparams;
4929 DEBUG(3,("call_trans2findnotifynext\n"));
4931 /* Realloc the parameter and data sizes */
4932 *pparams = (char *)SMB_REALLOC(*pparams,4);
4933 if (*pparams == NULL) {
4934 return ERROR_NT(NT_STATUS_NO_MEMORY);
4938 SSVAL(params,0,0); /* No changes */
4939 SSVAL(params,2,0); /* No EA errors */
4941 send_trans2_replies(outbuf, bufsize, params, 4, *ppdata, 0, max_data_bytes);
4946 /****************************************************************************
4947 Reply to a TRANS2_GET_DFS_REFERRAL - Shirish Kalele <kalele@veritas.com>.
4948 ****************************************************************************/
4950 static int call_trans2getdfsreferral(connection_struct *conn, char* inbuf, char* outbuf, int length, int bufsize,
4951 char **pparams, int total_params, char **ppdata, int total_data,
4952 unsigned int max_data_bytes)
4954 char *params = *pparams;
4957 int max_referral_level;
4959 DEBUG(10,("call_trans2getdfsreferral\n"));
4961 if (total_params < 2) {
4962 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
4965 max_referral_level = SVAL(params,0);
4967 if(!lp_host_msdfs())
4968 return ERROR_DOS(ERRDOS,ERRbadfunc);
4970 srvstr_pull(inbuf, pathname, ¶ms[2], sizeof(pathname), -1, STR_TERMINATE);
4971 if((reply_size = setup_dfs_referral(conn, pathname,max_referral_level,ppdata)) < 0)
4972 return UNIXERROR(ERRDOS,ERRbadfile);
4974 SSVAL(outbuf,smb_flg2,SVAL(outbuf,smb_flg2) | FLAGS2_DFS_PATHNAMES);
4975 send_trans2_replies(outbuf,bufsize,0,0,*ppdata,reply_size, max_data_bytes);
4980 #define LMCAT_SPL 0x53
4981 #define LMFUNC_GETJOBID 0x60
4983 /****************************************************************************
4984 Reply to a TRANS2_IOCTL - used for OS/2 printing.
4985 ****************************************************************************/
4987 static int call_trans2ioctl(connection_struct *conn, char* inbuf, char* outbuf, int length, int bufsize,
4988 char **pparams, int total_params, char **ppdata, int total_data,
4989 unsigned int max_data_bytes)
4991 char *pdata = *ppdata;
4992 files_struct *fsp = file_fsp(inbuf,smb_vwv15);
4994 /* check for an invalid fid before proceeding */
4997 return(ERROR_DOS(ERRDOS,ERRbadfid));
4999 if ((SVAL(inbuf,(smb_setup+4)) == LMCAT_SPL) &&
5000 (SVAL(inbuf,(smb_setup+6)) == LMFUNC_GETJOBID)) {
5001 *ppdata = (char *)SMB_REALLOC(*ppdata, 32);
5002 if (*ppdata == NULL) {
5003 return ERROR_NT(NT_STATUS_NO_MEMORY);
5007 /* NOTE - THIS IS ASCII ONLY AT THE MOMENT - NOT SURE IF OS/2
5008 CAN ACCEPT THIS IN UNICODE. JRA. */
5010 SSVAL(pdata,0,fsp->rap_print_jobid); /* Job number */
5011 srvstr_push( outbuf, pdata + 2, global_myname(), 15, STR_ASCII|STR_TERMINATE); /* Our NetBIOS name */
5012 srvstr_push( outbuf, pdata+18, lp_servicename(SNUM(conn)), 13, STR_ASCII|STR_TERMINATE); /* Service name */
5013 send_trans2_replies(outbuf,bufsize,*pparams,0,*ppdata,32, max_data_bytes);
5016 DEBUG(2,("Unknown TRANS2_IOCTL\n"));
5017 return ERROR_DOS(ERRSRV,ERRerror);
5021 /****************************************************************************
5022 Reply to a SMBfindclose (stop trans2 directory search).
5023 ****************************************************************************/
5025 int reply_findclose(connection_struct *conn,
5026 char *inbuf,char *outbuf,int length,int bufsize)
5029 int dptr_num=SVALS(inbuf,smb_vwv0);
5030 START_PROFILE(SMBfindclose);
5032 DEBUG(3,("reply_findclose, dptr_num = %d\n", dptr_num));
5034 dptr_close(&dptr_num);
5036 outsize = set_message(outbuf,0,0,False);
5038 DEBUG(3,("SMBfindclose dptr_num = %d\n", dptr_num));
5040 END_PROFILE(SMBfindclose);
5044 /****************************************************************************
5045 Reply to a SMBfindnclose (stop FINDNOTIFYFIRST directory search).
5046 ****************************************************************************/
5048 int reply_findnclose(connection_struct *conn,
5049 char *inbuf,char *outbuf,int length,int bufsize)
5053 START_PROFILE(SMBfindnclose);
5055 dptr_num = SVAL(inbuf,smb_vwv0);
5057 DEBUG(3,("reply_findnclose, dptr_num = %d\n", dptr_num));
5059 /* We never give out valid handles for a
5060 findnotifyfirst - so any dptr_num is ok here.
5063 outsize = set_message(outbuf,0,0,False);
5065 DEBUG(3,("SMB_findnclose dptr_num = %d\n", dptr_num));
5067 END_PROFILE(SMBfindnclose);
5071 int handle_trans2(connection_struct *conn,
5072 struct trans_state *state,
5073 char *inbuf, char *outbuf, int size, int bufsize)
5077 if (Protocol >= PROTOCOL_NT1) {
5078 SSVAL(outbuf,smb_flg2,SVAL(outbuf,smb_flg2) | 0x40); /* IS_LONG_NAME */
5081 /* Now we must call the relevant TRANS2 function */
5082 switch(state->call) {
5083 case TRANSACT2_OPEN:
5085 START_PROFILE_NESTED(Trans2_open);
5086 outsize = call_trans2open(
5087 conn, inbuf, outbuf, bufsize,
5088 &state->param, state->total_param,
5089 &state->data, state->total_data,
5090 state->max_data_return);
5091 END_PROFILE_NESTED(Trans2_open);
5095 case TRANSACT2_FINDFIRST:
5097 START_PROFILE_NESTED(Trans2_findfirst);
5098 outsize = call_trans2findfirst(
5099 conn, inbuf, outbuf, bufsize,
5100 &state->param, state->total_param,
5101 &state->data, state->total_data,
5102 state->max_data_return);
5103 END_PROFILE_NESTED(Trans2_findfirst);
5107 case TRANSACT2_FINDNEXT:
5109 START_PROFILE_NESTED(Trans2_findnext);
5110 outsize = call_trans2findnext(
5111 conn, inbuf, outbuf, size, bufsize,
5112 &state->param, state->total_param,
5113 &state->data, state->total_data,
5114 state->max_data_return);
5115 END_PROFILE_NESTED(Trans2_findnext);
5119 case TRANSACT2_QFSINFO:
5121 START_PROFILE_NESTED(Trans2_qfsinfo);
5122 outsize = call_trans2qfsinfo(
5123 conn, inbuf, outbuf, size, bufsize,
5124 &state->param, state->total_param,
5125 &state->data, state->total_data,
5126 state->max_data_return);
5127 END_PROFILE_NESTED(Trans2_qfsinfo);
5131 case TRANSACT2_SETFSINFO:
5133 START_PROFILE_NESTED(Trans2_setfsinfo);
5134 outsize = call_trans2setfsinfo(
5135 conn, inbuf, outbuf, size, bufsize,
5136 &state->param, state->total_param,
5137 &state->data, state->total_data,
5138 state->max_data_return);
5139 END_PROFILE_NESTED(Trans2_setfsinfo);
5143 case TRANSACT2_QPATHINFO:
5144 case TRANSACT2_QFILEINFO:
5146 START_PROFILE_NESTED(Trans2_qpathinfo);
5147 outsize = call_trans2qfilepathinfo(
5148 conn, inbuf, outbuf, size, bufsize, state->call,
5149 &state->param, state->total_param,
5150 &state->data, state->total_data,
5151 state->max_data_return);
5152 END_PROFILE_NESTED(Trans2_qpathinfo);
5156 case TRANSACT2_SETPATHINFO:
5157 case TRANSACT2_SETFILEINFO:
5159 START_PROFILE_NESTED(Trans2_setpathinfo);
5160 outsize = call_trans2setfilepathinfo(
5161 conn, inbuf, outbuf, size, bufsize, state->call,
5162 &state->param, state->total_param,
5163 &state->data, state->total_data,
5164 state->max_data_return);
5165 END_PROFILE_NESTED(Trans2_setpathinfo);
5169 case TRANSACT2_FINDNOTIFYFIRST:
5171 START_PROFILE_NESTED(Trans2_findnotifyfirst);
5172 outsize = call_trans2findnotifyfirst(
5173 conn, inbuf, outbuf, size, bufsize,
5174 &state->param, state->total_param,
5175 &state->data, state->total_data,
5176 state->max_data_return);
5177 END_PROFILE_NESTED(Trans2_findnotifyfirst);
5181 case TRANSACT2_FINDNOTIFYNEXT:
5183 START_PROFILE_NESTED(Trans2_findnotifynext);
5184 outsize = call_trans2findnotifynext(
5185 conn, inbuf, outbuf, size, bufsize,
5186 &state->param, state->total_param,
5187 &state->data, state->total_data,
5188 state->max_data_return);
5189 END_PROFILE_NESTED(Trans2_findnotifynext);
5193 case TRANSACT2_MKDIR:
5195 START_PROFILE_NESTED(Trans2_mkdir);
5196 outsize = call_trans2mkdir(
5197 conn, inbuf, outbuf, size, bufsize,
5198 &state->param, state->total_param,
5199 &state->data, state->total_data,
5200 state->max_data_return);
5201 END_PROFILE_NESTED(Trans2_mkdir);
5205 case TRANSACT2_GET_DFS_REFERRAL:
5207 START_PROFILE_NESTED(Trans2_get_dfs_referral);
5208 outsize = call_trans2getdfsreferral(
5209 conn, inbuf, outbuf, size, bufsize,
5210 &state->param, state->total_param,
5211 &state->data, state->total_data,
5212 state->max_data_return);
5213 END_PROFILE_NESTED(Trans2_get_dfs_referral);
5217 case TRANSACT2_IOCTL:
5219 START_PROFILE_NESTED(Trans2_ioctl);
5220 outsize = call_trans2ioctl(
5221 conn, inbuf, outbuf, size, bufsize,
5222 &state->param, state->total_param,
5223 &state->data, state->total_data,
5224 state->max_data_return);
5225 END_PROFILE_NESTED(Trans2_ioctl);
5230 /* Error in request */
5231 DEBUG(2,("Unknown request %d in trans2 call\n", state->call));
5232 outsize = ERROR_DOS(ERRSRV,ERRerror);
5238 /****************************************************************************
5239 Reply to a SMBtrans2.
5240 ****************************************************************************/
5242 int reply_trans2(connection_struct *conn, char *inbuf,char *outbuf,
5243 int size, int bufsize)
5246 unsigned int dsoff = SVAL(inbuf, smb_dsoff);
5247 unsigned int dscnt = SVAL(inbuf, smb_dscnt);
5248 unsigned int psoff = SVAL(inbuf, smb_psoff);
5249 unsigned int pscnt = SVAL(inbuf, smb_pscnt);
5250 unsigned int tran_call = SVAL(inbuf, smb_setup0);
5251 struct trans_state *state;
5254 START_PROFILE(SMBtrans2);
5256 result = allow_new_trans(conn->pending_trans, SVAL(inbuf, smb_mid));
5257 if (!NT_STATUS_IS_OK(result)) {
5258 DEBUG(2, ("Got invalid trans2 request: %s\n",
5259 nt_errstr(result)));
5260 END_PROFILE(SMBtrans2);
5261 return ERROR_NT(result);
5264 if (IS_IPC(conn) && (tran_call != TRANSACT2_OPEN)
5265 && (tran_call != TRANSACT2_GET_DFS_REFERRAL)) {
5266 END_PROFILE(SMBtrans2);
5267 return ERROR_DOS(ERRSRV,ERRaccess);
5270 if ((state = TALLOC_P(NULL, struct trans_state)) == NULL) {
5271 DEBUG(0, ("talloc failed\n"));
5272 END_PROFILE(SMBtrans2);
5273 return ERROR_NT(NT_STATUS_NO_MEMORY);
5276 state->cmd = SMBtrans2;
5278 state->mid = SVAL(inbuf, smb_mid);
5279 state->vuid = SVAL(inbuf, smb_uid);
5280 state->setup_count = SVAL(inbuf, smb_suwcnt);
5281 state->total_param = SVAL(inbuf, smb_tpscnt);
5282 state->param = NULL;
5283 state->total_data = SVAL(inbuf, smb_tdscnt);
5285 state->max_param_return = SVAL(inbuf, smb_mprcnt);
5286 state->max_data_return = SVAL(inbuf, smb_mdrcnt);
5287 state->max_setup_return = SVAL(inbuf, smb_msrcnt);
5288 state->close_on_completion = BITSETW(inbuf+smb_vwv5,0);
5289 state->one_way = BITSETW(inbuf+smb_vwv5,1);
5291 state->call = tran_call;
5293 /* All trans2 messages we handle have smb_sucnt == 1 - ensure this
5294 is so as a sanity check */
5295 if (state->setup_count != 1) {
5297 * Need to have rc=0 for ioctl to get job id for OS/2.
5298 * Network printing will fail if function is not successful.
5299 * Similar function in reply.c will be used if protocol
5300 * is LANMAN1.0 instead of LM1.2X002.
5301 * Until DosPrintSetJobInfo with PRJINFO3 is supported,
5302 * outbuf doesn't have to be set(only job id is used).
5304 if ( (state->setup_count == 4) && (tran_call == TRANSACT2_IOCTL) &&
5305 (SVAL(inbuf,(smb_setup+4)) == LMCAT_SPL) &&
5306 (SVAL(inbuf,(smb_setup+6)) == LMFUNC_GETJOBID)) {
5307 DEBUG(2,("Got Trans2 DevIOctl jobid\n"));
5309 DEBUG(2,("Invalid smb_sucnt in trans2 call(%u)\n",state->setup_count));
5310 DEBUG(2,("Transaction is %d\n",tran_call));
5312 END_PROFILE(SMBtrans2);
5313 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
5317 if ((dscnt > state->total_data) || (pscnt > state->total_param))
5320 if (state->total_data) {
5321 /* Can't use talloc here, the core routines do realloc on the
5322 * params and data. */
5323 state->data = (char *)SMB_MALLOC(state->total_data);
5324 if (state->data == NULL) {
5325 DEBUG(0,("reply_trans2: data malloc fail for %u "
5326 "bytes !\n", (unsigned int)state->total_data));
5328 END_PROFILE(SMBtrans2);
5329 return(ERROR_DOS(ERRDOS,ERRnomem));
5331 if ((dsoff+dscnt < dsoff) || (dsoff+dscnt < dscnt))
5333 if ((smb_base(inbuf)+dsoff+dscnt > inbuf + size) ||
5334 (smb_base(inbuf)+dsoff+dscnt < smb_base(inbuf)))
5337 memcpy(state->data,smb_base(inbuf)+dsoff,dscnt);
5340 if (state->total_param) {
5341 /* Can't use talloc here, the core routines do realloc on the
5342 * params and data. */
5343 state->param = (char *)SMB_MALLOC(state->total_param);
5344 if (state->param == NULL) {
5345 DEBUG(0,("reply_trans: param malloc fail for %u "
5346 "bytes !\n", (unsigned int)state->total_param));
5347 SAFE_FREE(state->data);
5349 END_PROFILE(SMBtrans2);
5350 return(ERROR_DOS(ERRDOS,ERRnomem));
5352 if ((psoff+pscnt < psoff) || (psoff+pscnt < pscnt))
5354 if ((smb_base(inbuf)+psoff+pscnt > inbuf + size) ||
5355 (smb_base(inbuf)+psoff+pscnt < smb_base(inbuf)))
5358 memcpy(state->param,smb_base(inbuf)+psoff,pscnt);
5361 state->received_data = dscnt;
5362 state->received_param = pscnt;
5364 if ((state->received_param == state->total_param) &&
5365 (state->received_data == state->total_data)) {
5367 outsize = handle_trans2(conn, state, inbuf, outbuf,
5369 SAFE_FREE(state->data);
5370 SAFE_FREE(state->param);
5372 END_PROFILE(SMBtrans2);
5376 DLIST_ADD(conn->pending_trans, state);
5378 /* We need to send an interim response then receive the rest
5379 of the parameter/data bytes */
5380 outsize = set_message(outbuf,0,0,False);
5382 END_PROFILE(SMBtrans2);
5387 DEBUG(0,("reply_trans2: invalid trans parameters\n"));
5388 SAFE_FREE(state->data);
5389 SAFE_FREE(state->param);
5391 END_PROFILE(SMBtrans2);
5392 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
5396 /****************************************************************************
5397 Reply to a SMBtranss2
5398 ****************************************************************************/
5400 int reply_transs2(connection_struct *conn,
5401 char *inbuf,char *outbuf,int size,int bufsize)
5404 unsigned int pcnt,poff,dcnt,doff,pdisp,ddisp;
5405 struct trans_state *state;
5407 START_PROFILE(SMBtranss2);
5411 for (state = conn->pending_trans; state != NULL;
5412 state = state->next) {
5413 if (state->mid == SVAL(inbuf,smb_mid)) {
5418 if ((state == NULL) || (state->cmd != SMBtrans2)) {
5419 END_PROFILE(SMBtranss2);
5420 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
5423 /* Revise state->total_param and state->total_data in case they have
5424 changed downwards */
5426 if (SVAL(inbuf, smb_tpscnt) < state->total_param)
5427 state->total_param = SVAL(inbuf, smb_tpscnt);
5428 if (SVAL(inbuf, smb_tdscnt) < state->total_data)
5429 state->total_data = SVAL(inbuf, smb_tdscnt);
5431 pcnt = SVAL(inbuf, smb_spscnt);
5432 poff = SVAL(inbuf, smb_spsoff);
5433 pdisp = SVAL(inbuf, smb_spsdisp);
5435 dcnt = SVAL(inbuf, smb_sdscnt);
5436 doff = SVAL(inbuf, smb_sdsoff);
5437 ddisp = SVAL(inbuf, smb_sdsdisp);
5439 state->received_param += pcnt;
5440 state->received_data += dcnt;
5442 if ((state->received_data > state->total_data) ||
5443 (state->received_param > state->total_param))
5447 if (pdisp+pcnt > state->total_param)
5449 if ((pdisp+pcnt < pdisp) || (pdisp+pcnt < pcnt))
5451 if (pdisp > state->total_param)
5453 if ((smb_base(inbuf) + poff + pcnt > inbuf + size) ||
5454 (smb_base(inbuf) + poff + pcnt < smb_base(inbuf)))
5456 if (state->param + pdisp < state->param)
5459 memcpy(state->param+pdisp,smb_base(inbuf)+poff,
5464 if (ddisp+dcnt > state->total_data)
5466 if ((ddisp+dcnt < ddisp) || (ddisp+dcnt < dcnt))
5468 if (ddisp > state->total_data)
5470 if ((smb_base(inbuf) + doff + dcnt > inbuf + size) ||
5471 (smb_base(inbuf) + doff + dcnt < smb_base(inbuf)))
5473 if (state->data + ddisp < state->data)
5476 memcpy(state->data+ddisp, smb_base(inbuf)+doff,
5480 if ((state->received_param < state->total_param) ||
5481 (state->received_data < state->total_data)) {
5482 END_PROFILE(SMBtranss2);
5486 /* construct_reply_common has done us the favor to pre-fill the
5487 * command field with SMBtranss2 which is wrong :-)
5489 SCVAL(outbuf,smb_com,SMBtrans2);
5491 outsize = handle_trans2(conn, state, inbuf, outbuf, size, bufsize);
5493 DLIST_REMOVE(conn->pending_trans, state);
5494 SAFE_FREE(state->data);
5495 SAFE_FREE(state->param);
5499 END_PROFILE(SMBtranss2);
5500 return(ERROR_DOS(ERRSRV,ERRnosupport));
5503 END_PROFILE(SMBtranss2);
5508 DEBUG(0,("reply_transs2: invalid trans parameters\n"));
5509 DLIST_REMOVE(conn->pending_trans, state);
5510 SAFE_FREE(state->data);
5511 SAFE_FREE(state->param);
5513 END_PROFILE(SMBtranss2);
5514 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);