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;
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, struct ea_list *);
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) {
399 struct ea_list *eal = TALLOC_ZERO_P(ctx, struct ea_list);
400 unsigned int namelen = CVAL(pdata,offset);
402 offset++; /* Go past the namelen byte. */
404 /* integer wrap paranioa. */
405 if ((offset + namelen < offset) || (offset + namelen < namelen) ||
406 (offset > data_size) || (namelen > data_size) ||
407 (offset + namelen >= data_size)) {
410 /* Ensure the name is null terminated. */
411 if (pdata[offset + namelen] != '\0') {
414 pull_ascii_talloc(ctx, &eal->ea.name, &pdata[offset]);
419 offset += (namelen + 1); /* Go past the name + terminating zero. */
420 DLIST_ADD_END(ea_list_head, eal, struct ea_list *);
421 DEBUG(10,("read_ea_name_list: read ea name %s\n", eal->ea.name));
427 /****************************************************************************
428 Read one EA list entry from the buffer.
429 ****************************************************************************/
431 struct ea_list *read_ea_list_entry(TALLOC_CTX *ctx, const char *pdata, size_t data_size, size_t *pbytes_used)
433 struct ea_list *eal = TALLOC_ZERO_P(ctx, struct ea_list);
435 unsigned int namelen;
445 eal->ea.flags = CVAL(pdata,0);
446 namelen = CVAL(pdata,1);
447 val_len = SVAL(pdata,2);
449 if (4 + namelen + 1 + val_len > data_size) {
453 /* Ensure the name is null terminated. */
454 if (pdata[namelen + 4] != '\0') {
457 pull_ascii_talloc(ctx, &eal->ea.name, pdata + 4);
462 eal->ea.value = data_blob(NULL, (size_t)val_len + 1);
463 if (!eal->ea.value.data) {
467 memcpy(eal->ea.value.data, pdata + 4 + namelen + 1, val_len);
469 /* Ensure we're null terminated just in case we print the value. */
470 eal->ea.value.data[val_len] = '\0';
471 /* But don't count the null. */
472 eal->ea.value.length--;
475 *pbytes_used = 4 + namelen + 1 + val_len;
478 DEBUG(10,("read_ea_list_entry: read ea name %s\n", eal->ea.name));
479 dump_data(10, (const char *)eal->ea.value.data, eal->ea.value.length);
484 /****************************************************************************
485 Read a list of EA names and data from an incoming data buffer. Create an ea_list with them.
486 ****************************************************************************/
488 static struct ea_list *read_ea_list(TALLOC_CTX *ctx, const char *pdata, size_t data_size)
490 struct ea_list *ea_list_head = NULL;
492 size_t bytes_used = 0;
494 while (offset < data_size) {
495 struct ea_list *eal = read_ea_list_entry(ctx, pdata + offset, data_size - offset, &bytes_used);
501 DLIST_ADD_END(ea_list_head, eal, struct ea_list *);
502 offset += bytes_used;
508 /****************************************************************************
509 Count the total EA size needed.
510 ****************************************************************************/
512 static size_t ea_list_size(struct ea_list *ealist)
515 struct ea_list *listp;
518 for (listp = ealist; listp; listp = listp->next) {
519 push_ascii_fstring(dos_ea_name, listp->ea.name);
520 ret += 4 + strlen(dos_ea_name) + 1 + listp->ea.value.length;
522 /* Add on 4 for total length. */
530 /****************************************************************************
531 Return a union of EA's from a file list and a list of names.
532 The TALLOC context for the two lists *MUST* be identical as we steal
533 memory from one list to add to another. JRA.
534 ****************************************************************************/
536 static struct ea_list *ea_list_union(struct ea_list *name_list, struct ea_list *file_list, size_t *total_ea_len)
538 struct ea_list *nlistp, *flistp;
540 for (nlistp = name_list; nlistp; nlistp = nlistp->next) {
541 for (flistp = file_list; flistp; flistp = flistp->next) {
542 if (strequal(nlistp->ea.name, flistp->ea.name)) {
548 /* Copy the data from this entry. */
549 nlistp->ea.flags = flistp->ea.flags;
550 nlistp->ea.value = flistp->ea.value;
553 nlistp->ea.flags = 0;
554 ZERO_STRUCT(nlistp->ea.value);
558 *total_ea_len = ea_list_size(name_list);
562 /****************************************************************************
563 Send the required number of replies back.
564 We assume all fields other than the data fields are
565 set correctly for the type of call.
566 HACK ! Always assumes smb_setup field is zero.
567 ****************************************************************************/
569 int send_trans2_replies(char *outbuf,
577 /* As we are using a protocol > LANMAN1 then the max_send
578 variable must have been set in the sessetupX call.
579 This takes precedence over the max_xmit field in the
580 global struct. These different max_xmit variables should
581 be merged as this is now too confusing */
583 int data_to_send = datasize;
584 int params_to_send = paramsize;
588 int params_sent_thistime, data_sent_thistime, total_sent_thistime;
589 int alignment_offset = 1; /* JRA. This used to be 3. Set to 1 to make netmon parse ok. */
590 int data_alignment_offset = 0;
592 /* Initially set the wcnt area to be 10 - this is true for all trans2 replies */
594 set_message(outbuf,10,0,True);
596 /* Modify the data_to_send and datasize and set the error if
597 we're trying to send more than max_data_bytes. We still send
598 the part of the packet(s) that fit. Strange, but needed
601 if (max_data_bytes > 0 && datasize > max_data_bytes) {
602 DEBUG(5,("send_trans2_replies: max_data_bytes %d exceeded by data %d\n",
603 max_data_bytes, datasize ));
604 datasize = data_to_send = max_data_bytes;
605 error_packet_set(outbuf,ERRDOS,ERRbufferoverflow,STATUS_BUFFER_OVERFLOW,__LINE__,__FILE__);
608 /* If there genuinely are no parameters or data to send just send the empty packet */
610 if(params_to_send == 0 && data_to_send == 0) {
612 if (!send_smb(smbd_server_fd(),outbuf))
613 exit_server("send_trans2_replies: send_smb failed.");
617 /* When sending params and data ensure that both are nicely aligned */
618 /* Only do this alignment when there is also data to send - else
619 can cause NT redirector problems. */
621 if (((params_to_send % 4) != 0) && (data_to_send != 0))
622 data_alignment_offset = 4 - (params_to_send % 4);
624 /* Space is bufsize minus Netbios over TCP header minus SMB header */
625 /* The alignment_offset is to align the param bytes on an even byte
626 boundary. NT 4.0 Beta needs this to work correctly. */
628 useable_space = bufsize - ((smb_buf(outbuf)+ alignment_offset+data_alignment_offset) - outbuf);
630 /* useable_space can never be more than max_send minus the alignment offset. */
632 useable_space = MIN(useable_space, max_send - (alignment_offset+data_alignment_offset));
634 while (params_to_send || data_to_send) {
635 /* Calculate whether we will totally or partially fill this packet */
637 total_sent_thistime = params_to_send + data_to_send + alignment_offset + data_alignment_offset;
639 /* We can never send more than useable_space */
641 * Note that 'useable_space' does not include the alignment offsets,
642 * but we must include the alignment offsets in the calculation of
643 * the length of the data we send over the wire, as the alignment offsets
644 * are sent here. Fix from Marc_Jacobsen@hp.com.
647 total_sent_thistime = MIN(total_sent_thistime, useable_space+ alignment_offset + data_alignment_offset);
649 set_message(outbuf, 10, total_sent_thistime, True);
651 /* Set total params and data to be sent */
652 SSVAL(outbuf,smb_tprcnt,paramsize);
653 SSVAL(outbuf,smb_tdrcnt,datasize);
655 /* Calculate how many parameters and data we can fit into
656 * this packet. Parameters get precedence
659 params_sent_thistime = MIN(params_to_send,useable_space);
660 data_sent_thistime = useable_space - params_sent_thistime;
661 data_sent_thistime = MIN(data_sent_thistime,data_to_send);
663 SSVAL(outbuf,smb_prcnt, params_sent_thistime);
665 /* smb_proff is the offset from the start of the SMB header to the
666 parameter bytes, however the first 4 bytes of outbuf are
667 the Netbios over TCP header. Thus use smb_base() to subtract
668 them from the calculation */
670 SSVAL(outbuf,smb_proff,((smb_buf(outbuf)+alignment_offset) - smb_base(outbuf)));
672 if(params_sent_thistime == 0)
673 SSVAL(outbuf,smb_prdisp,0);
675 /* Absolute displacement of param bytes sent in this packet */
676 SSVAL(outbuf,smb_prdisp,pp - params);
678 SSVAL(outbuf,smb_drcnt, data_sent_thistime);
679 if(data_sent_thistime == 0) {
680 SSVAL(outbuf,smb_droff,0);
681 SSVAL(outbuf,smb_drdisp, 0);
683 /* The offset of the data bytes is the offset of the
684 parameter bytes plus the number of parameters being sent this time */
685 SSVAL(outbuf,smb_droff,((smb_buf(outbuf)+alignment_offset) -
686 smb_base(outbuf)) + params_sent_thistime + data_alignment_offset);
687 SSVAL(outbuf,smb_drdisp, pd - pdata);
690 /* Copy the param bytes into the packet */
692 if(params_sent_thistime)
693 memcpy((smb_buf(outbuf)+alignment_offset),pp,params_sent_thistime);
695 /* Copy in the data bytes */
696 if(data_sent_thistime)
697 memcpy(smb_buf(outbuf)+alignment_offset+params_sent_thistime+
698 data_alignment_offset,pd,data_sent_thistime);
700 DEBUG(9,("t2_rep: params_sent_thistime = %d, data_sent_thistime = %d, useable_space = %d\n",
701 params_sent_thistime, data_sent_thistime, useable_space));
702 DEBUG(9,("t2_rep: params_to_send = %d, data_to_send = %d, paramsize = %d, datasize = %d\n",
703 params_to_send, data_to_send, paramsize, datasize));
705 /* Send the packet */
707 if (!send_smb(smbd_server_fd(),outbuf))
708 exit_server("send_trans2_replies: send_smb failed.");
710 pp += params_sent_thistime;
711 pd += data_sent_thistime;
713 params_to_send -= params_sent_thistime;
714 data_to_send -= data_sent_thistime;
717 if(params_to_send < 0 || data_to_send < 0) {
718 DEBUG(0,("send_trans2_replies failed sanity check pts = %d, dts = %d\n!!!",
719 params_to_send, data_to_send));
727 /****************************************************************************
728 Reply to a TRANSACT2_OPEN.
729 ****************************************************************************/
731 static int call_trans2open(connection_struct *conn, char *inbuf, char *outbuf, int bufsize,
732 char **pparams, int total_params, char **ppdata, int total_data,
733 unsigned int max_data_bytes)
735 char *params = *pparams;
736 char *pdata = *ppdata;
741 BOOL return_additional_info;
752 SMB_STRUCT_STAT sbuf;
754 BOOL bad_path = False;
756 TALLOC_CTX *ctx = NULL;
757 struct ea_list *ea_list = NULL;
762 uint32 create_disposition;
763 uint32 create_options = 0;
766 * Ensure we have enough parameters to perform the operation.
769 if (total_params < 29) {
770 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
773 flags = SVAL(params, 0);
774 deny_mode = SVAL(params, 2);
775 open_attr = SVAL(params,6);
776 oplock_request = (flags & REQUEST_OPLOCK) ? EXCLUSIVE_OPLOCK : 0;
777 if (oplock_request) {
778 oplock_request |= (flags & REQUEST_BATCH_OPLOCK) ? BATCH_OPLOCK : 0;
782 return_additional_info = BITSETW(params,0);
783 open_sattr = SVAL(params, 4);
784 open_time = make_unix_date3(params+8);
786 open_ofun = SVAL(params,12);
787 open_size = IVAL(params,14);
791 return(ERROR_DOS(ERRSRV,ERRaccess));
794 srvstr_get_path(inbuf, fname, pname, sizeof(fname), -1, STR_TERMINATE, &status);
795 if (!NT_STATUS_IS_OK(status)) {
796 return ERROR_NT(status);
799 DEBUG(3,("call_trans2open %s deny_mode=0x%x attr=%d ofun=0x%x size=%d\n",
800 fname, (unsigned int)deny_mode, (unsigned int)open_attr,
801 (unsigned int)open_ofun, open_size));
803 /* XXXX we need to handle passed times, sattr and flags */
805 unix_convert(fname,conn,0,&bad_path,&sbuf);
807 return ERROR_NT(NT_STATUS_OBJECT_PATH_NOT_FOUND);
810 if (!check_name(fname,conn)) {
811 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRnoaccess);
814 if (!map_open_params_to_ntcreate(fname, deny_mode, open_ofun,
819 return ERROR_DOS(ERRDOS, ERRbadaccess);
822 /* Any data in this call is an EA list. */
823 if (total_data && (total_data != 4) && !lp_ea_support(SNUM(conn))) {
824 return ERROR_NT(NT_STATUS_EAS_NOT_SUPPORTED);
827 if (total_data != 4) {
828 if (total_data < 10) {
829 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
832 if (IVAL(pdata,0) > total_data) {
833 DEBUG(10,("call_trans2open: bad total data size (%u) > %u\n",
834 IVAL(pdata,0), (unsigned int)total_data));
835 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
838 ctx = talloc_init("TRANS2_OPEN_SET_EA");
840 return ERROR_NT(NT_STATUS_NO_MEMORY);
842 ea_list = read_ea_list(ctx, pdata + 4, total_data - 4);
845 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
847 } else if (IVAL(pdata,0) != 4) {
848 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
851 status = open_file_ntcreate(conn,fname,&sbuf,
860 if (!NT_STATUS_IS_OK(status)) {
862 if (open_was_deferred(SVAL(inbuf,smb_mid))) {
863 /* We have re-scheduled this call. */
866 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRnoaccess);
869 size = get_file_size(sbuf);
870 fattr = dos_mode(conn,fname,&sbuf);
871 mtime = sbuf.st_mtime;
875 close_file(fsp,ERROR_CLOSE);
876 return(ERROR_DOS(ERRDOS,ERRnoaccess));
879 /* Save the requested allocation size. */
880 /* Allocate space for the file if a size hint is supplied */
881 if ((smb_action == FILE_WAS_CREATED) || (smb_action == FILE_WAS_OVERWRITTEN)) {
882 SMB_BIG_UINT allocation_size = (SMB_BIG_UINT)open_size;
883 if (allocation_size && (allocation_size > (SMB_BIG_UINT)size)) {
884 fsp->initial_allocation_size = smb_roundup(fsp->conn, allocation_size);
885 if (fsp->is_directory) {
886 close_file(fsp,ERROR_CLOSE);
887 /* Can't set allocation size on a directory. */
888 return ERROR_NT(NT_STATUS_ACCESS_DENIED);
890 if (vfs_allocate_file_space(fsp, fsp->initial_allocation_size) == -1) {
891 close_file(fsp,ERROR_CLOSE);
892 return ERROR_NT(NT_STATUS_DISK_FULL);
895 /* Adjust size here to return the right size in the reply.
896 Windows does it this way. */
897 size = fsp->initial_allocation_size;
899 fsp->initial_allocation_size = smb_roundup(fsp->conn,(SMB_BIG_UINT)size);
903 if (total_data && smb_action == FILE_WAS_CREATED) {
904 status = set_ea(conn, fsp, fname, ea_list);
906 if (!NT_STATUS_IS_OK(status)) {
907 close_file(fsp,ERROR_CLOSE);
908 return ERROR_NT(status);
912 /* Realloc the size of parameters and data we will return */
913 *pparams = (char *)SMB_REALLOC(*pparams, 30);
914 if(*pparams == NULL ) {
915 return ERROR_NT(NT_STATUS_NO_MEMORY);
919 SSVAL(params,0,fsp->fnum);
920 SSVAL(params,2,open_attr);
921 srv_put_dos_date2(params,4, mtime);
922 SIVAL(params,8, (uint32)size);
923 SSVAL(params,12,deny_mode);
924 SSVAL(params,14,0); /* open_type - file or directory. */
925 SSVAL(params,16,0); /* open_state - only valid for IPC device. */
927 if (oplock_request && lp_fake_oplocks(SNUM(conn))) {
928 smb_action |= EXTENDED_OPLOCK_GRANTED;
931 SSVAL(params,18,smb_action);
934 * WARNING - this may need to be changed if SMB_INO_T <> 4 bytes.
936 SIVAL(params,20,inode);
937 SSVAL(params,24,0); /* Padding. */
939 uint32 ea_size = estimate_ea_size(conn, fsp, fname);
940 SIVAL(params, 26, ea_size);
942 SIVAL(params, 26, 0);
945 /* Send the required number of replies */
946 send_trans2_replies(outbuf, bufsize, params, 30, *ppdata, 0, max_data_bytes);
951 /*********************************************************
952 Routine to check if a given string matches exactly.
953 as a special case a mask of "." does NOT match. That
954 is required for correct wildcard semantics
955 Case can be significant or not.
956 **********************************************************/
958 static BOOL exact_match(connection_struct *conn, char *str, char *mask)
960 if (mask[0] == '.' && mask[1] == 0)
962 if (conn->case_sensitive)
963 return strcmp(str,mask)==0;
964 if (StrCaseCmp(str,mask) != 0) {
967 if (dptr_has_wild(conn->dirptr)) {
973 /****************************************************************************
974 Return the filetype for UNIX extensions.
975 ****************************************************************************/
977 static uint32 unix_filetype(mode_t mode)
980 return UNIX_TYPE_FILE;
981 else if(S_ISDIR(mode))
982 return UNIX_TYPE_DIR;
984 else if(S_ISLNK(mode))
985 return UNIX_TYPE_SYMLINK;
988 else if(S_ISCHR(mode))
989 return UNIX_TYPE_CHARDEV;
992 else if(S_ISBLK(mode))
993 return UNIX_TYPE_BLKDEV;
996 else if(S_ISFIFO(mode))
997 return UNIX_TYPE_FIFO;
1000 else if(S_ISSOCK(mode))
1001 return UNIX_TYPE_SOCKET;
1004 DEBUG(0,("unix_filetype: unknown filetype %u", (unsigned)mode));
1005 return UNIX_TYPE_UNKNOWN;
1008 /****************************************************************************
1009 Map wire perms onto standard UNIX permissions. Obey share restrictions.
1010 ****************************************************************************/
1012 static mode_t unix_perms_from_wire( connection_struct *conn, SMB_STRUCT_STAT *pst, uint32 perms)
1016 if (perms == SMB_MODE_NO_CHANGE)
1017 return pst->st_mode;
1019 ret |= ((perms & UNIX_X_OTH ) ? S_IXOTH : 0);
1020 ret |= ((perms & UNIX_W_OTH ) ? S_IWOTH : 0);
1021 ret |= ((perms & UNIX_R_OTH ) ? S_IROTH : 0);
1022 ret |= ((perms & UNIX_X_GRP ) ? S_IXGRP : 0);
1023 ret |= ((perms & UNIX_W_GRP ) ? S_IWGRP : 0);
1024 ret |= ((perms & UNIX_R_GRP ) ? S_IRGRP : 0);
1025 ret |= ((perms & UNIX_X_USR ) ? S_IXUSR : 0);
1026 ret |= ((perms & UNIX_W_USR ) ? S_IWUSR : 0);
1027 ret |= ((perms & UNIX_R_USR ) ? S_IRUSR : 0);
1029 ret |= ((perms & UNIX_STICKY ) ? S_ISVTX : 0);
1032 ret |= ((perms & UNIX_SET_GID ) ? S_ISGID : 0);
1035 ret |= ((perms & UNIX_SET_UID ) ? S_ISUID : 0);
1038 if (VALID_STAT(*pst) && S_ISDIR(pst->st_mode)) {
1039 ret &= lp_dir_mask(SNUM(conn));
1040 /* Add in force bits */
1041 ret |= lp_force_dir_mode(SNUM(conn));
1043 /* Apply mode mask */
1044 ret &= lp_create_mask(SNUM(conn));
1045 /* Add in force bits */
1046 ret |= lp_force_create_mode(SNUM(conn));
1052 /****************************************************************************
1053 Get a level dependent lanman2 dir entry.
1054 ****************************************************************************/
1056 static BOOL get_lanman2_dir_entry(connection_struct *conn,
1057 void *inbuf, char *outbuf,
1058 char *path_mask,uint32 dirtype,int info_level,
1059 int requires_resume_key,
1060 BOOL dont_descend,char **ppdata,
1061 char *base_data, int space_remaining,
1062 BOOL *out_of_space, BOOL *got_exact_match,
1063 int *last_entry_off, struct ea_list *name_list, TALLOC_CTX *ea_ctx)
1067 SMB_STRUCT_STAT sbuf;
1071 char *p, *q, *pdata = *ppdata;
1075 SMB_OFF_T file_size = 0;
1076 SMB_BIG_UINT allocation_size = 0;
1078 struct timespec mdate_ts, adate_ts, create_date_ts;
1079 time_t mdate = (time_t)0, adate = (time_t)0, create_date = (time_t)0;
1081 char *last_entry_ptr;
1083 uint32 nt_extmode; /* Used for NT connections instead of mode */
1084 BOOL needslash = ( conn->dirpath[strlen(conn->dirpath) -1] != '/');
1085 BOOL check_mangled_names = lp_manglednames(conn->params);
1088 *out_of_space = False;
1089 *got_exact_match = False;
1091 ZERO_STRUCT(mdate_ts);
1092 ZERO_STRUCT(adate_ts);
1093 ZERO_STRUCT(create_date_ts);
1098 p = strrchr_m(path_mask,'/');
1101 pstrcpy(mask,"*.*");
1105 pstrcpy(mask, path_mask);
1110 BOOL ms_dfs_link = False;
1112 /* Needed if we run out of space */
1113 long curr_dirpos = prev_dirpos = dptr_TellDir(conn->dirptr);
1114 dname = dptr_ReadDirName(conn->dirptr,&curr_dirpos,&sbuf);
1117 * Due to bugs in NT client redirectors we are not using
1118 * resume keys any more - set them to zero.
1119 * Check out the related comments in findfirst/findnext.
1125 DEBUG(8,("get_lanman2_dir_entry:readdir on dirptr 0x%lx now at offset %ld\n",
1126 (long)conn->dirptr,curr_dirpos));
1131 pstrcpy(fname,dname);
1133 if(!(got_match = *got_exact_match = exact_match(conn, fname, mask)))
1134 got_match = mask_match(fname, mask, conn->case_sensitive);
1136 if(!got_match && check_mangled_names &&
1137 !mangle_is_8_3(fname, False, conn->params)) {
1140 * It turns out that NT matches wildcards against
1141 * both long *and* short names. This may explain some
1142 * of the wildcard wierdness from old DOS clients
1143 * that some people have been seeing.... JRA.
1147 pstrcpy( newname, fname);
1148 mangle_map( newname, True, False, conn->params);
1149 if(!(got_match = *got_exact_match = exact_match(conn, newname, mask)))
1150 got_match = mask_match(newname, mask, conn->case_sensitive);
1154 BOOL isdots = (strequal(fname,"..") || strequal(fname,"."));
1155 if (dont_descend && !isdots)
1158 pstrcpy(pathreal,conn->dirpath);
1160 pstrcat(pathreal,"/");
1161 pstrcat(pathreal,dname);
1163 if (INFO_LEVEL_IS_UNIX(info_level)) {
1164 if (SMB_VFS_LSTAT(conn,pathreal,&sbuf) != 0) {
1165 DEBUG(5,("get_lanman2_dir_entry:Couldn't lstat [%s] (%s)\n",
1166 pathreal,strerror(errno)));
1169 } else if (!VALID_STAT(sbuf) && SMB_VFS_STAT(conn,pathreal,&sbuf) != 0) {
1171 /* Needed to show the msdfs symlinks as
1174 if(lp_host_msdfs() &&
1175 lp_msdfs_root(SNUM(conn)) &&
1176 ((ms_dfs_link = is_msdfs_link(NULL,conn, pathreal, NULL, NULL, &sbuf)) == True)) {
1178 DEBUG(5,("get_lanman2_dir_entry: Masquerading msdfs link %s as a directory\n", pathreal));
1179 sbuf.st_mode = (sbuf.st_mode & 0xFFF) | S_IFDIR;
1183 DEBUG(5,("get_lanman2_dir_entry:Couldn't stat [%s] (%s)\n",
1184 pathreal,strerror(errno)));
1190 mode = dos_mode_msdfs(conn,pathreal,&sbuf);
1192 mode = dos_mode(conn,pathreal,&sbuf);
1195 if (!dir_check_ftype(conn,mode,dirtype)) {
1196 DEBUG(5,("[%s] attribs didn't match %x\n",fname,dirtype));
1201 file_size = get_file_size(sbuf);
1202 allocation_size = get_allocation_size(conn,NULL,&sbuf);
1204 mdate_ts = get_mtimespec(&sbuf);
1205 adate_ts = get_atimespec(&sbuf);
1206 create_date_ts = get_create_timespec(&sbuf,lp_fake_dir_create_times(SNUM(conn)));
1208 if (lp_dos_filetime_resolution(SNUM(conn))) {
1209 dos_filetime_timespec(&create_date_ts);
1210 dos_filetime_timespec(&mdate_ts);
1211 dos_filetime_timespec(&adate_ts);
1214 create_date = convert_timespec_to_time_t(create_date_ts);
1215 mdate = convert_timespec_to_time_t(mdate_ts);
1216 adate = convert_timespec_to_time_t(adate_ts);
1218 DEBUG(5,("get_lanman2_dir_entry found %s fname=%s\n",pathreal,fname));
1222 dptr_DirCacheAdd(conn->dirptr, dname, curr_dirpos);
1226 mangle_map(fname,False,True,conn->params);
1231 nt_extmode = mode ? mode : FILE_ATTRIBUTE_NORMAL;
1233 switch (info_level) {
1234 case SMB_FIND_INFO_STANDARD:
1235 DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_INFO_STANDARD\n"));
1236 if(requires_resume_key) {
1240 srv_put_dos_date2(p,0,create_date);
1241 srv_put_dos_date2(p,4,adate);
1242 srv_put_dos_date2(p,8,mdate);
1243 SIVAL(p,12,(uint32)file_size);
1244 SIVAL(p,16,(uint32)allocation_size);
1248 p += align_string(outbuf, p, 0);
1249 len = srvstr_push(outbuf, p, fname, -1, STR_TERMINATE);
1250 if (SVAL(outbuf, smb_flg2) & FLAGS2_UNICODE_STRINGS) {
1252 SCVAL(nameptr, -1, len - 2);
1254 SCVAL(nameptr, -1, 0);
1258 SCVAL(nameptr, -1, len - 1);
1260 SCVAL(nameptr, -1, 0);
1266 case SMB_FIND_EA_SIZE:
1267 DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_EA_SIZE\n"));
1268 if(requires_resume_key) {
1272 srv_put_dos_date2(p,0,create_date);
1273 srv_put_dos_date2(p,4,adate);
1274 srv_put_dos_date2(p,8,mdate);
1275 SIVAL(p,12,(uint32)file_size);
1276 SIVAL(p,16,(uint32)allocation_size);
1279 unsigned int ea_size = estimate_ea_size(conn, NULL, pathreal);
1280 SIVAL(p,22,ea_size); /* Extended attributes */
1284 len = srvstr_push(outbuf, p, fname, -1, STR_TERMINATE | STR_NOALIGN);
1285 if (SVAL(outbuf, smb_flg2) & FLAGS2_UNICODE_STRINGS) {
1298 SCVAL(nameptr,0,len);
1300 SCVAL(p,0,0); p += 1; /* Extra zero byte ? - why.. */
1303 case SMB_FIND_EA_LIST:
1305 struct ea_list *file_list = NULL;
1308 DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_EA_LIST\n"));
1312 if(requires_resume_key) {
1316 srv_put_dos_date2(p,0,create_date);
1317 srv_put_dos_date2(p,4,adate);
1318 srv_put_dos_date2(p,8,mdate);
1319 SIVAL(p,12,(uint32)file_size);
1320 SIVAL(p,16,(uint32)allocation_size);
1322 p += 22; /* p now points to the EA area. */
1324 file_list = get_ea_list_from_file(ea_ctx, conn, NULL, pathreal, &ea_len);
1325 name_list = ea_list_union(name_list, file_list, &ea_len);
1327 /* We need to determine if this entry will fit in the space available. */
1328 /* Max string size is 255 bytes. */
1329 if (PTR_DIFF(p + 255 + ea_len,pdata) > space_remaining) {
1330 /* Move the dirptr back to prev_dirpos */
1331 dptr_SeekDir(conn->dirptr, prev_dirpos);
1332 *out_of_space = True;
1333 DEBUG(9,("get_lanman2_dir_entry: out of space\n"));
1334 return False; /* Not finished - just out of space */
1337 /* Push the ea_data followed by the name. */
1338 p += fill_ea_buffer(ea_ctx, p, space_remaining, conn, name_list);
1340 len = srvstr_push(outbuf, p + 1, fname, -1, STR_TERMINATE | STR_NOALIGN);
1341 if (SVAL(outbuf, smb_flg2) & FLAGS2_UNICODE_STRINGS) {
1354 SCVAL(nameptr,0,len);
1356 SCVAL(p,0,0); p += 1; /* Extra zero byte ? - why.. */
1360 case SMB_FIND_FILE_BOTH_DIRECTORY_INFO:
1361 DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_FILE_BOTH_DIRECTORY_INFO\n"));
1362 was_8_3 = mangle_is_8_3(fname, True, conn->params);
1364 SIVAL(p,0,reskey); p += 4;
1365 put_long_date_timespec(p,create_date_ts); p += 8;
1366 put_long_date_timespec(p,adate_ts); p += 8;
1367 put_long_date_timespec(p,mdate_ts); p += 8;
1368 put_long_date_timespec(p,mdate_ts); p += 8;
1369 SOFF_T(p,0,file_size); p += 8;
1370 SOFF_T(p,0,allocation_size); p += 8;
1371 SIVAL(p,0,nt_extmode); p += 4;
1372 q = p; p += 4; /* q is placeholder for name length. */
1374 unsigned int ea_size = estimate_ea_size(conn, NULL, pathreal);
1375 SIVAL(p,0,ea_size); /* Extended attributes */
1378 /* Clear the short name buffer. This is
1379 * IMPORTANT as not doing so will trigger
1380 * a Win2k client bug. JRA.
1382 if (!was_8_3 && check_mangled_names) {
1383 pstring mangled_name;
1384 pstrcpy(mangled_name, fname);
1385 mangle_map(mangled_name,True,True,
1387 mangled_name[12] = 0;
1388 len = srvstr_push(outbuf, p+2, mangled_name, 24, STR_UPPER|STR_UNICODE);
1390 memset(p + 2 + len,'\0',24 - len);
1397 len = srvstr_push(outbuf, p, fname, -1, STR_TERMINATE_ASCII);
1400 SIVAL(p,0,0); /* Ensure any padding is null. */
1401 len = PTR_DIFF(p, pdata);
1402 len = (len + 3) & ~3;
1407 case SMB_FIND_FILE_DIRECTORY_INFO:
1408 DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_FILE_DIRECTORY_INFO\n"));
1410 SIVAL(p,0,reskey); p += 4;
1411 put_long_date_timespec(p,create_date_ts); p += 8;
1412 put_long_date_timespec(p,adate_ts); p += 8;
1413 put_long_date_timespec(p,mdate_ts); p += 8;
1414 put_long_date_timespec(p,mdate_ts); p += 8;
1415 SOFF_T(p,0,file_size); p += 8;
1416 SOFF_T(p,0,allocation_size); p += 8;
1417 SIVAL(p,0,nt_extmode); p += 4;
1418 len = srvstr_push(outbuf, p + 4, fname, -1, STR_TERMINATE_ASCII);
1421 SIVAL(p,0,0); /* Ensure any padding is null. */
1422 len = PTR_DIFF(p, pdata);
1423 len = (len + 3) & ~3;
1428 case SMB_FIND_FILE_FULL_DIRECTORY_INFO:
1429 DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_FILE_FULL_DIRECTORY_INFO\n"));
1431 SIVAL(p,0,reskey); p += 4;
1432 put_long_date_timespec(p,create_date_ts); p += 8;
1433 put_long_date_timespec(p,adate_ts); p += 8;
1434 put_long_date_timespec(p,mdate_ts); p += 8;
1435 put_long_date_timespec(p,mdate_ts); p += 8;
1436 SOFF_T(p,0,file_size); p += 8;
1437 SOFF_T(p,0,allocation_size); p += 8;
1438 SIVAL(p,0,nt_extmode); p += 4;
1439 q = p; p += 4; /* q is placeholder for name length. */
1441 unsigned int ea_size = estimate_ea_size(conn, NULL, pathreal);
1442 SIVAL(p,0,ea_size); /* Extended attributes */
1445 len = srvstr_push(outbuf, p, fname, -1, STR_TERMINATE_ASCII);
1449 SIVAL(p,0,0); /* Ensure any padding is null. */
1450 len = PTR_DIFF(p, pdata);
1451 len = (len + 3) & ~3;
1456 case SMB_FIND_FILE_NAMES_INFO:
1457 DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_FILE_NAMES_INFO\n"));
1459 SIVAL(p,0,reskey); p += 4;
1461 /* this must *not* be null terminated or w2k gets in a loop trying to set an
1462 acl on a dir (tridge) */
1463 len = srvstr_push(outbuf, p, fname, -1, STR_TERMINATE_ASCII);
1466 SIVAL(p,0,0); /* Ensure any padding is null. */
1467 len = PTR_DIFF(p, pdata);
1468 len = (len + 3) & ~3;
1473 case SMB_FIND_ID_FULL_DIRECTORY_INFO:
1474 DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_ID_FULL_DIRECTORY_INFO\n"));
1476 SIVAL(p,0,reskey); p += 4;
1477 put_long_date_timespec(p,create_date_ts); p += 8;
1478 put_long_date_timespec(p,adate_ts); p += 8;
1479 put_long_date_timespec(p,mdate_ts); p += 8;
1480 put_long_date_timespec(p,mdate_ts); p += 8;
1481 SOFF_T(p,0,file_size); p += 8;
1482 SOFF_T(p,0,allocation_size); p += 8;
1483 SIVAL(p,0,nt_extmode); p += 4;
1484 q = p; p += 4; /* q is placeholder for name length. */
1486 unsigned int ea_size = estimate_ea_size(conn, NULL, pathreal);
1487 SIVAL(p,0,ea_size); /* Extended attributes */
1490 SIVAL(p,0,0); p += 4; /* Unknown - reserved ? */
1491 SIVAL(p,0,sbuf.st_ino); p += 4; /* FileIndexLow */
1492 SIVAL(p,0,sbuf.st_dev); p += 4; /* FileIndexHigh */
1493 len = srvstr_push(outbuf, p, fname, -1, STR_TERMINATE_ASCII);
1496 SIVAL(p,0,0); /* Ensure any padding is null. */
1497 len = PTR_DIFF(p, pdata);
1498 len = (len + 3) & ~3;
1503 case SMB_FIND_ID_BOTH_DIRECTORY_INFO:
1504 DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_ID_BOTH_DIRECTORY_INFO\n"));
1505 was_8_3 = mangle_is_8_3(fname, True, conn->params);
1507 SIVAL(p,0,reskey); p += 4;
1508 put_long_date_timespec(p,create_date_ts); p += 8;
1509 put_long_date_timespec(p,adate_ts); p += 8;
1510 put_long_date_timespec(p,mdate_ts); p += 8;
1511 put_long_date_timespec(p,mdate_ts); p += 8;
1512 SOFF_T(p,0,file_size); p += 8;
1513 SOFF_T(p,0,allocation_size); p += 8;
1514 SIVAL(p,0,nt_extmode); p += 4;
1515 q = p; p += 4; /* q is placeholder for name length */
1517 unsigned int ea_size = estimate_ea_size(conn, NULL, pathreal);
1518 SIVAL(p,0,ea_size); /* Extended attributes */
1521 /* Clear the short name buffer. This is
1522 * IMPORTANT as not doing so will trigger
1523 * a Win2k client bug. JRA.
1525 if (!was_8_3 && check_mangled_names) {
1526 pstring mangled_name;
1527 pstrcpy(mangled_name, fname);
1528 mangle_map(mangled_name,True,True,
1530 mangled_name[12] = 0;
1531 len = srvstr_push(outbuf, p+2, mangled_name, 24, STR_UPPER|STR_UNICODE);
1534 memset(p + 2 + len,'\0',24 - len);
1541 SSVAL(p,0,0); p += 2; /* Reserved ? */
1542 SIVAL(p,0,sbuf.st_ino); p += 4; /* FileIndexLow */
1543 SIVAL(p,0,sbuf.st_dev); p += 4; /* FileIndexHigh */
1544 len = srvstr_push(outbuf, p, fname, -1, STR_TERMINATE_ASCII);
1547 SIVAL(p,0,0); /* Ensure any padding is null. */
1548 len = PTR_DIFF(p, pdata);
1549 len = (len + 3) & ~3;
1554 /* CIFS UNIX Extension. */
1556 case SMB_FIND_FILE_UNIX:
1557 DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_FILE_UNIX\n"));
1559 SIVAL(p,0,reskey); p+= 4; /* Used for continuing search. */
1561 /* Begin of SMB_QUERY_FILE_UNIX_BASIC */
1562 SOFF_T(p,0,get_file_size(sbuf)); /* File size 64 Bit */
1565 SOFF_T(p,0,get_allocation_size(conn,NULL,&sbuf)); /* Number of bytes used on disk - 64 Bit */
1568 put_long_date_timespec(p,get_ctimespec(&sbuf)); /* Inode change Time 64 Bit */
1569 put_long_date_timespec(p+8,get_atimespec(&sbuf)); /* Last access time 64 Bit */
1570 put_long_date_timespec(p+16,get_mtimespec(&sbuf)); /* Last modification time 64 Bit */
1573 SIVAL(p,0,sbuf.st_uid); /* user id for the owner */
1577 SIVAL(p,0,sbuf.st_gid); /* group id of owner */
1581 SIVAL(p,0,unix_filetype(sbuf.st_mode));
1584 SIVAL(p,0,unix_dev_major(sbuf.st_rdev)); /* Major device number if type is device */
1588 SIVAL(p,0,unix_dev_minor(sbuf.st_rdev)); /* Minor device number if type is device */
1592 SINO_T_VAL(p,0,(SMB_INO_T)sbuf.st_ino); /* inode number */
1595 SIVAL(p,0, unix_perms_to_wire(sbuf.st_mode)); /* Standard UNIX file permissions */
1599 SIVAL(p,0,sbuf.st_nlink); /* number of hard links */
1603 len = srvstr_push(outbuf, p, fname, -1, STR_TERMINATE);
1605 SIVAL(p,0,0); /* Ensure any padding is null. */
1607 len = PTR_DIFF(p, pdata);
1608 len = (len + 3) & ~3;
1609 SIVAL(pdata,0,len); /* Offset from this structure to the beginning of the next one */
1611 /* End of SMB_QUERY_FILE_UNIX_BASIC */
1620 if (PTR_DIFF(p,pdata) > space_remaining) {
1621 /* Move the dirptr back to prev_dirpos */
1622 dptr_SeekDir(conn->dirptr, prev_dirpos);
1623 *out_of_space = True;
1624 DEBUG(9,("get_lanman2_dir_entry: out of space\n"));
1625 return False; /* Not finished - just out of space */
1628 /* Setup the last entry pointer, as an offset from base_data */
1629 *last_entry_off = PTR_DIFF(last_entry_ptr,base_data);
1630 /* Advance the data pointer to the next slot */
1636 /****************************************************************************
1637 Reply to a TRANS2_FINDFIRST.
1638 ****************************************************************************/
1640 static int call_trans2findfirst(connection_struct *conn, char *inbuf, char *outbuf, int bufsize,
1641 char **pparams, int total_params, char **ppdata, int total_data,
1642 unsigned int max_data_bytes)
1644 /* We must be careful here that we don't return more than the
1645 allowed number of data bytes. If this means returning fewer than
1646 maxentries then so be it. We assume that the redirector has
1647 enough room for the fixed number of parameter bytes it has
1649 char *params = *pparams;
1650 char *pdata = *ppdata;
1651 uint32 dirtype = SVAL(params,0);
1652 int maxentries = SVAL(params,2);
1653 uint16 findfirst_flags = SVAL(params,4);
1654 BOOL close_after_first = (findfirst_flags & FLAG_TRANS2_FIND_CLOSE);
1655 BOOL close_if_end = (findfirst_flags & FLAG_TRANS2_FIND_CLOSE_IF_END);
1656 BOOL requires_resume_key = (findfirst_flags & FLAG_TRANS2_FIND_REQUIRE_RESUME);
1657 int info_level = SVAL(params,6);
1661 int last_entry_off=0;
1665 BOOL finished = False;
1666 BOOL dont_descend = False;
1667 BOOL out_of_space = False;
1668 int space_remaining;
1669 BOOL bad_path = False;
1670 BOOL mask_contains_wcard = False;
1671 SMB_STRUCT_STAT sbuf;
1672 TALLOC_CTX *ea_ctx = NULL;
1673 struct ea_list *ea_list = NULL;
1674 NTSTATUS ntstatus = NT_STATUS_OK;
1676 if (total_params < 12) {
1677 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
1680 *directory = *mask = 0;
1682 DEBUG(3,("call_trans2findfirst: dirtype = %x, maxentries = %d, close_after_first=%d, \
1683 close_if_end = %d requires_resume_key = %d level = 0x%x, max_data_bytes = %d\n",
1684 (unsigned int)dirtype, maxentries, close_after_first, close_if_end, requires_resume_key,
1685 info_level, max_data_bytes));
1688 /* W2K3 seems to treat zero as 1. */
1692 switch (info_level) {
1693 case SMB_FIND_INFO_STANDARD:
1694 case SMB_FIND_EA_SIZE:
1695 case SMB_FIND_EA_LIST:
1696 case SMB_FIND_FILE_DIRECTORY_INFO:
1697 case SMB_FIND_FILE_FULL_DIRECTORY_INFO:
1698 case SMB_FIND_FILE_NAMES_INFO:
1699 case SMB_FIND_FILE_BOTH_DIRECTORY_INFO:
1700 case SMB_FIND_ID_FULL_DIRECTORY_INFO:
1701 case SMB_FIND_ID_BOTH_DIRECTORY_INFO:
1703 case SMB_FIND_FILE_UNIX:
1704 if (!lp_unix_extensions()) {
1705 return ERROR_NT(NT_STATUS_INVALID_LEVEL);
1709 return ERROR_NT(NT_STATUS_INVALID_LEVEL);
1712 srvstr_get_path_wcard(inbuf, directory, params+12, sizeof(directory), -1, STR_TERMINATE, &ntstatus, &mask_contains_wcard);
1713 if (!NT_STATUS_IS_OK(ntstatus)) {
1714 return ERROR_NT(ntstatus);
1717 RESOLVE_DFSPATH_WCARD(directory, conn, inbuf, outbuf);
1719 unix_convert(directory,conn,0,&bad_path,&sbuf);
1721 return ERROR_NT(NT_STATUS_OBJECT_PATH_NOT_FOUND);
1723 if(!check_name(directory,conn)) {
1724 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRbadpath);
1727 p = strrchr_m(directory,'/');
1729 /* Windows and OS/2 systems treat search on the root '\' as if it were '\*' */
1730 if((directory[0] == '.') && (directory[1] == '\0')) {
1732 mask_contains_wcard = True;
1734 pstrcpy(mask,directory);
1736 pstrcpy(directory,"./");
1742 DEBUG(5,("dir=%s, mask = %s\n",directory, mask));
1744 if (info_level == SMB_FIND_EA_LIST) {
1747 if (total_data < 4) {
1748 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
1751 ea_size = IVAL(pdata,0);
1752 if (ea_size != total_data) {
1753 DEBUG(4,("call_trans2findfirst: Rejecting EA request with incorrect \
1754 total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pdata,0) ));
1755 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
1758 if (!lp_ea_support(SNUM(conn))) {
1759 return ERROR_DOS(ERRDOS,ERReasnotsupported);
1762 if ((ea_ctx = talloc_init("findnext_ea_list")) == NULL) {
1763 return ERROR_NT(NT_STATUS_NO_MEMORY);
1766 /* Pull out the list of names. */
1767 ea_list = read_ea_name_list(ea_ctx, pdata + 4, ea_size - 4);
1769 talloc_destroy(ea_ctx);
1770 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
1774 *ppdata = (char *)SMB_REALLOC(
1775 *ppdata, max_data_bytes + DIR_ENTRY_SAFETY_MARGIN);
1776 if(*ppdata == NULL ) {
1777 talloc_destroy(ea_ctx);
1778 return ERROR_NT(NT_STATUS_NO_MEMORY);
1782 /* Realloc the params space */
1783 *pparams = (char *)SMB_REALLOC(*pparams, 10);
1784 if (*pparams == NULL) {
1785 talloc_destroy(ea_ctx);
1786 return ERROR_NT(NT_STATUS_NO_MEMORY);
1790 /* Save the wildcard match and attribs we are using on this directory -
1791 needed as lanman2 assumes these are being saved between calls */
1793 dptr_num = dptr_create(conn,directory, False, True ,SVAL(inbuf,smb_pid), mask, mask_contains_wcard, dirtype);
1795 talloc_destroy(ea_ctx);
1796 return(UNIXERROR(ERRDOS,ERRbadfile));
1799 DEBUG(4,("dptr_num is %d, wcard = %s, attr = %d\n",dptr_num, mask, dirtype));
1801 /* We don't need to check for VOL here as this is returned by
1802 a different TRANS2 call. */
1804 DEBUG(8,("dirpath=<%s> dontdescend=<%s>\n", conn->dirpath,lp_dontdescend(SNUM(conn))));
1805 if (in_list(conn->dirpath,lp_dontdescend(SNUM(conn)),conn->case_sensitive))
1806 dont_descend = True;
1809 space_remaining = max_data_bytes;
1810 out_of_space = False;
1812 for (i=0;(i<maxentries) && !finished && !out_of_space;i++) {
1813 BOOL got_exact_match = False;
1815 /* this is a heuristic to avoid seeking the dirptr except when
1816 absolutely necessary. It allows for a filename of about 40 chars */
1817 if (space_remaining < DIRLEN_GUESS && numentries > 0) {
1818 out_of_space = True;
1821 finished = !get_lanman2_dir_entry(conn,
1823 mask,dirtype,info_level,
1824 requires_resume_key,dont_descend,
1825 &p,pdata,space_remaining, &out_of_space, &got_exact_match,
1826 &last_entry_off, ea_list, ea_ctx);
1829 if (finished && out_of_space)
1832 if (!finished && !out_of_space)
1836 * As an optimisation if we know we aren't looking
1837 * for a wildcard name (ie. the name matches the wildcard exactly)
1838 * then we can finish on any (first) match.
1839 * This speeds up large directory searches. JRA.
1845 space_remaining = max_data_bytes - PTR_DIFF(p,pdata);
1848 talloc_destroy(ea_ctx);
1850 /* Check if we can close the dirptr */
1851 if(close_after_first || (finished && close_if_end)) {
1852 DEBUG(5,("call_trans2findfirst - (2) closing dptr_num %d\n", dptr_num));
1853 dptr_close(&dptr_num);
1857 * If there are no matching entries we must return ERRDOS/ERRbadfile -
1858 * from observation of NT. NB. This changes to ERRDOS,ERRnofiles if
1859 * the protocol level is less than NT1. Tested with smbclient. JRA.
1860 * This should fix the OS/2 client bug #2335.
1863 if(numentries == 0) {
1864 dptr_close(&dptr_num);
1865 if (Protocol < PROTOCOL_NT1) {
1866 return ERROR_DOS(ERRDOS,ERRnofiles);
1868 return ERROR_BOTH(NT_STATUS_NO_SUCH_FILE,ERRDOS,ERRbadfile);
1872 /* At this point pdata points to numentries directory entries. */
1874 /* Set up the return parameter block */
1875 SSVAL(params,0,dptr_num);
1876 SSVAL(params,2,numentries);
1877 SSVAL(params,4,finished);
1878 SSVAL(params,6,0); /* Never an EA error */
1879 SSVAL(params,8,last_entry_off);
1881 send_trans2_replies( outbuf, bufsize, params, 10, pdata, PTR_DIFF(p,pdata), max_data_bytes);
1883 if ((! *directory) && dptr_path(dptr_num))
1884 slprintf(directory,sizeof(directory)-1, "(%s)",dptr_path(dptr_num));
1886 DEBUG( 4, ( "%s mask=%s directory=%s dirtype=%d numentries=%d\n",
1887 smb_fn_name(CVAL(inbuf,smb_com)),
1888 mask, directory, dirtype, numentries ) );
1891 * Force a name mangle here to ensure that the
1892 * mask as an 8.3 name is top of the mangled cache.
1893 * The reasons for this are subtle. Don't remove
1894 * this code unless you know what you are doing
1895 * (see PR#13758). JRA.
1898 if(!mangle_is_8_3_wildcards( mask, False, conn->params))
1899 mangle_map(mask, True, True, conn->params);
1904 /****************************************************************************
1905 Reply to a TRANS2_FINDNEXT.
1906 ****************************************************************************/
1908 static int call_trans2findnext(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize,
1909 char **pparams, int total_params, char **ppdata, int total_data,
1910 unsigned int max_data_bytes)
1912 /* We must be careful here that we don't return more than the
1913 allowed number of data bytes. If this means returning fewer than
1914 maxentries then so be it. We assume that the redirector has
1915 enough room for the fixed number of parameter bytes it has
1917 char *params = *pparams;
1918 char *pdata = *ppdata;
1919 int dptr_num = SVAL(params,0);
1920 int maxentries = SVAL(params,2);
1921 uint16 info_level = SVAL(params,4);
1922 uint32 resume_key = IVAL(params,6);
1923 uint16 findnext_flags = SVAL(params,10);
1924 BOOL close_after_request = (findnext_flags & FLAG_TRANS2_FIND_CLOSE);
1925 BOOL close_if_end = (findnext_flags & FLAG_TRANS2_FIND_CLOSE_IF_END);
1926 BOOL requires_resume_key = (findnext_flags & FLAG_TRANS2_FIND_REQUIRE_RESUME);
1927 BOOL continue_bit = (findnext_flags & FLAG_TRANS2_FIND_CONTINUE);
1928 BOOL mask_contains_wcard = False;
1929 pstring resume_name;
1935 int i, last_entry_off=0;
1936 BOOL finished = False;
1937 BOOL dont_descend = False;
1938 BOOL out_of_space = False;
1939 int space_remaining;
1940 TALLOC_CTX *ea_ctx = NULL;
1941 struct ea_list *ea_list = NULL;
1942 NTSTATUS ntstatus = NT_STATUS_OK;
1944 if (total_params < 12) {
1945 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
1948 *mask = *directory = *resume_name = 0;
1950 srvstr_get_path_wcard(inbuf, resume_name, params+12, sizeof(resume_name), -1, STR_TERMINATE, &ntstatus, &mask_contains_wcard);
1951 if (!NT_STATUS_IS_OK(ntstatus)) {
1952 /* Win9x or OS/2 can send a resume name of ".." or ".". This will cause the parser to
1953 complain (it thinks we're asking for the directory above the shared
1954 path or an invalid name). Catch this as the resume name is only compared, never used in
1955 a file access. JRA. */
1956 if (NT_STATUS_EQUAL(ntstatus,NT_STATUS_OBJECT_PATH_SYNTAX_BAD)) {
1957 pstrcpy(resume_name, "..");
1958 } else if (NT_STATUS_EQUAL(ntstatus,NT_STATUS_OBJECT_NAME_INVALID)) {
1959 pstrcpy(resume_name, ".");
1961 return ERROR_NT(ntstatus);
1965 DEBUG(3,("call_trans2findnext: dirhandle = %d, max_data_bytes = %d, maxentries = %d, \
1966 close_after_request=%d, close_if_end = %d requires_resume_key = %d \
1967 resume_key = %d resume name = %s continue=%d level = %d\n",
1968 dptr_num, max_data_bytes, maxentries, close_after_request, close_if_end,
1969 requires_resume_key, resume_key, resume_name, continue_bit, info_level));
1972 /* W2K3 seems to treat zero as 1. */
1976 switch (info_level) {
1977 case SMB_FIND_INFO_STANDARD:
1978 case SMB_FIND_EA_SIZE:
1979 case SMB_FIND_EA_LIST:
1980 case SMB_FIND_FILE_DIRECTORY_INFO:
1981 case SMB_FIND_FILE_FULL_DIRECTORY_INFO:
1982 case SMB_FIND_FILE_NAMES_INFO:
1983 case SMB_FIND_FILE_BOTH_DIRECTORY_INFO:
1984 case SMB_FIND_ID_FULL_DIRECTORY_INFO:
1985 case SMB_FIND_ID_BOTH_DIRECTORY_INFO:
1987 case SMB_FIND_FILE_UNIX:
1988 if (!lp_unix_extensions()) {
1989 return ERROR_NT(NT_STATUS_INVALID_LEVEL);
1993 return ERROR_NT(NT_STATUS_INVALID_LEVEL);
1996 if (info_level == SMB_FIND_EA_LIST) {
1999 if (total_data < 4) {
2000 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
2003 ea_size = IVAL(pdata,0);
2004 if (ea_size != total_data) {
2005 DEBUG(4,("call_trans2findnext: Rejecting EA request with incorrect \
2006 total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pdata,0) ));
2007 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
2010 if (!lp_ea_support(SNUM(conn))) {
2011 return ERROR_DOS(ERRDOS,ERReasnotsupported);
2014 if ((ea_ctx = talloc_init("findnext_ea_list")) == NULL) {
2015 return ERROR_NT(NT_STATUS_NO_MEMORY);
2018 /* Pull out the list of names. */
2019 ea_list = read_ea_name_list(ea_ctx, pdata + 4, ea_size - 4);
2021 talloc_destroy(ea_ctx);
2022 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
2026 *ppdata = (char *)SMB_REALLOC(
2027 *ppdata, max_data_bytes + DIR_ENTRY_SAFETY_MARGIN);
2028 if(*ppdata == NULL) {
2029 talloc_destroy(ea_ctx);
2030 return ERROR_NT(NT_STATUS_NO_MEMORY);
2035 /* Realloc the params space */
2036 *pparams = (char *)SMB_REALLOC(*pparams, 6*SIZEOFWORD);
2037 if(*pparams == NULL ) {
2038 talloc_destroy(ea_ctx);
2039 return ERROR_NT(NT_STATUS_NO_MEMORY);
2044 /* Check that the dptr is valid */
2045 if(!(conn->dirptr = dptr_fetch_lanman2(dptr_num))) {
2046 talloc_destroy(ea_ctx);
2047 return ERROR_DOS(ERRDOS,ERRnofiles);
2050 string_set(&conn->dirpath,dptr_path(dptr_num));
2052 /* Get the wildcard mask from the dptr */
2053 if((p = dptr_wcard(dptr_num))== NULL) {
2054 DEBUG(2,("dptr_num %d has no wildcard\n", dptr_num));
2055 talloc_destroy(ea_ctx);
2056 return ERROR_DOS(ERRDOS,ERRnofiles);
2060 pstrcpy(directory,conn->dirpath);
2062 /* Get the attr mask from the dptr */
2063 dirtype = dptr_attr(dptr_num);
2065 DEBUG(3,("dptr_num is %d, mask = %s, attr = %x, dirptr=(0x%lX,%ld)\n",
2066 dptr_num, mask, dirtype,
2068 dptr_TellDir(conn->dirptr)));
2070 /* We don't need to check for VOL here as this is returned by
2071 a different TRANS2 call. */
2073 DEBUG(8,("dirpath=<%s> dontdescend=<%s>\n",conn->dirpath,lp_dontdescend(SNUM(conn))));
2074 if (in_list(conn->dirpath,lp_dontdescend(SNUM(conn)),conn->case_sensitive))
2075 dont_descend = True;
2078 space_remaining = max_data_bytes;
2079 out_of_space = False;
2082 * Seek to the correct position. We no longer use the resume key but
2083 * depend on the last file name instead.
2086 if(*resume_name && !continue_bit) {
2089 long current_pos = 0;
2091 * Remember, mangle_map is called by
2092 * get_lanman2_dir_entry(), so the resume name
2093 * could be mangled. Ensure we check the unmangled name.
2096 if (mangle_is_mangled(resume_name, conn->params)) {
2097 mangle_check_cache(resume_name, sizeof(resume_name)-1,
2102 * Fix for NT redirector problem triggered by resume key indexes
2103 * changing between directory scans. We now return a resume key of 0
2104 * and instead look for the filename to continue from (also given
2105 * to us by NT/95/smbfs/smbclient). If no other scans have been done between the
2106 * findfirst/findnext (as is usual) then the directory pointer
2107 * should already be at the correct place.
2110 finished = !dptr_SearchDir(conn->dirptr, resume_name, ¤t_pos, &st);
2111 } /* end if resume_name && !continue_bit */
2113 for (i=0;(i<(int)maxentries) && !finished && !out_of_space ;i++) {
2114 BOOL got_exact_match = False;
2116 /* this is a heuristic to avoid seeking the dirptr except when
2117 absolutely necessary. It allows for a filename of about 40 chars */
2118 if (space_remaining < DIRLEN_GUESS && numentries > 0) {
2119 out_of_space = True;
2122 finished = !get_lanman2_dir_entry(conn,
2124 mask,dirtype,info_level,
2125 requires_resume_key,dont_descend,
2126 &p,pdata,space_remaining, &out_of_space, &got_exact_match,
2127 &last_entry_off, ea_list, ea_ctx);
2130 if (finished && out_of_space)
2133 if (!finished && !out_of_space)
2137 * As an optimisation if we know we aren't looking
2138 * for a wildcard name (ie. the name matches the wildcard exactly)
2139 * then we can finish on any (first) match.
2140 * This speeds up large directory searches. JRA.
2146 space_remaining = max_data_bytes - PTR_DIFF(p,pdata);
2149 talloc_destroy(ea_ctx);
2151 /* Check if we can close the dirptr */
2152 if(close_after_request || (finished && close_if_end)) {
2153 DEBUG(5,("call_trans2findnext: closing dptr_num = %d\n", dptr_num));
2154 dptr_close(&dptr_num); /* This frees up the saved mask */
2157 /* Set up the return parameter block */
2158 SSVAL(params,0,numentries);
2159 SSVAL(params,2,finished);
2160 SSVAL(params,4,0); /* Never an EA error */
2161 SSVAL(params,6,last_entry_off);
2163 send_trans2_replies( outbuf, bufsize, params, 8, pdata, PTR_DIFF(p,pdata), max_data_bytes);
2165 if ((! *directory) && dptr_path(dptr_num))
2166 slprintf(directory,sizeof(directory)-1, "(%s)",dptr_path(dptr_num));
2168 DEBUG( 3, ( "%s mask=%s directory=%s dirtype=%d numentries=%d\n",
2169 smb_fn_name(CVAL(inbuf,smb_com)),
2170 mask, directory, dirtype, numentries ) );
2175 /****************************************************************************
2176 Reply to a TRANS2_QFSINFO (query filesystem info).
2177 ****************************************************************************/
2179 static int call_trans2qfsinfo(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize,
2180 char **pparams, int total_params, char **ppdata, int total_data,
2181 unsigned int max_data_bytes)
2183 char *pdata = *ppdata;
2184 char *params = *pparams;
2185 uint16 info_level = SVAL(params,0);
2188 char *vname = volume_label(SNUM(conn));
2189 int snum = SNUM(conn);
2190 char *fstype = lp_fstype(SNUM(conn));
2193 DEBUG(3,("call_trans2qfsinfo: level = %d\n", info_level));
2195 if(SMB_VFS_STAT(conn,".",&st)!=0) {
2196 DEBUG(2,("call_trans2qfsinfo: stat of . failed (%s)\n", strerror(errno)));
2197 return ERROR_DOS(ERRSRV,ERRinvdevice);
2200 *ppdata = (char *)SMB_REALLOC(
2201 *ppdata, max_data_bytes + DIR_ENTRY_SAFETY_MARGIN);
2202 if (*ppdata == NULL ) {
2203 return ERROR_NT(NT_STATUS_NO_MEMORY);
2207 memset((char *)pdata,'\0',max_data_bytes + DIR_ENTRY_SAFETY_MARGIN);
2209 switch (info_level) {
2210 case SMB_INFO_ALLOCATION:
2212 SMB_BIG_UINT dfree,dsize,bsize,block_size,sectors_per_unit,bytes_per_sector;
2214 if (get_dfree_info(conn,".",False,&bsize,&dfree,&dsize) == (SMB_BIG_UINT)-1) {
2215 return(UNIXERROR(ERRHRD,ERRgeneral));
2218 block_size = lp_block_size(snum);
2219 if (bsize < block_size) {
2220 SMB_BIG_UINT factor = block_size/bsize;
2225 if (bsize > block_size) {
2226 SMB_BIG_UINT factor = bsize/block_size;
2231 bytes_per_sector = 512;
2232 sectors_per_unit = bsize/bytes_per_sector;
2234 DEBUG(5,("call_trans2qfsinfo : SMB_INFO_ALLOCATION id=%x, bsize=%u, cSectorUnit=%u, \
2235 cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)st.st_dev, (unsigned int)bsize, (unsigned int)sectors_per_unit,
2236 (unsigned int)bytes_per_sector, (unsigned int)dsize, (unsigned int)dfree));
2238 SIVAL(pdata,l1_idFileSystem,st.st_dev);
2239 SIVAL(pdata,l1_cSectorUnit,sectors_per_unit);
2240 SIVAL(pdata,l1_cUnit,dsize);
2241 SIVAL(pdata,l1_cUnitAvail,dfree);
2242 SSVAL(pdata,l1_cbSector,bytes_per_sector);
2246 case SMB_INFO_VOLUME:
2247 /* Return volume name */
2249 * Add volume serial number - hash of a combination of
2250 * the called hostname and the service name.
2252 SIVAL(pdata,0,str_checksum(lp_servicename(snum)) ^ (str_checksum(get_local_machine_name())<<16) );
2254 * Win2k3 and previous mess this up by sending a name length
2255 * one byte short. I believe only older clients (OS/2 Win9x) use
2256 * this call so try fixing this by adding a terminating null to
2257 * the pushed string. The change here was adding the STR_TERMINATE. JRA.
2259 len = srvstr_push(outbuf, pdata+l2_vol_szVolLabel, vname, -1, STR_NOALIGN|STR_TERMINATE);
2260 SCVAL(pdata,l2_vol_cch,len);
2261 data_len = l2_vol_szVolLabel + len;
2262 DEBUG(5,("call_trans2qfsinfo : time = %x, namelen = %d, name = %s\n",
2263 (unsigned)st.st_ctime, len, vname));
2266 case SMB_QUERY_FS_ATTRIBUTE_INFO:
2267 case SMB_FS_ATTRIBUTE_INFORMATION:
2270 #if defined(HAVE_SYS_QUOTAS)
2271 quota_flag = FILE_VOLUME_QUOTAS;
2274 SIVAL(pdata,0,FILE_CASE_PRESERVED_NAMES|FILE_CASE_SENSITIVE_SEARCH|
2275 (lp_nt_acl_support(SNUM(conn)) ? FILE_PERSISTENT_ACLS : 0)|
2276 quota_flag); /* FS ATTRIBUTES */
2278 SIVAL(pdata,4,255); /* Max filename component length */
2279 /* NOTE! the fstype must *not* be null terminated or win98 won't recognise it
2280 and will think we can't do long filenames */
2281 len = srvstr_push(outbuf, pdata+12, fstype, -1, STR_UNICODE);
2283 data_len = 12 + len;
2286 case SMB_QUERY_FS_LABEL_INFO:
2287 case SMB_FS_LABEL_INFORMATION:
2288 len = srvstr_push(outbuf, pdata+4, vname, -1, 0);
2293 case SMB_QUERY_FS_VOLUME_INFO:
2294 case SMB_FS_VOLUME_INFORMATION:
2297 * Add volume serial number - hash of a combination of
2298 * the called hostname and the service name.
2300 SIVAL(pdata,8,str_checksum(lp_servicename(snum)) ^
2301 (str_checksum(get_local_machine_name())<<16));
2303 len = srvstr_push(outbuf, pdata+18, vname, -1, STR_UNICODE);
2304 SIVAL(pdata,12,len);
2306 DEBUG(5,("call_trans2qfsinfo : SMB_QUERY_FS_VOLUME_INFO namelen = %d, vol=%s serv=%s\n",
2307 (int)strlen(vname),vname, lp_servicename(snum)));
2310 case SMB_QUERY_FS_SIZE_INFO:
2311 case SMB_FS_SIZE_INFORMATION:
2313 SMB_BIG_UINT dfree,dsize,bsize,block_size,sectors_per_unit,bytes_per_sector;
2315 if (get_dfree_info(conn,".",False,&bsize,&dfree,&dsize) == (SMB_BIG_UINT)-1) {
2316 return(UNIXERROR(ERRHRD,ERRgeneral));
2318 block_size = lp_block_size(snum);
2319 if (bsize < block_size) {
2320 SMB_BIG_UINT factor = block_size/bsize;
2325 if (bsize > block_size) {
2326 SMB_BIG_UINT factor = bsize/block_size;
2331 bytes_per_sector = 512;
2332 sectors_per_unit = bsize/bytes_per_sector;
2333 DEBUG(5,("call_trans2qfsinfo : SMB_QUERY_FS_SIZE_INFO bsize=%u, cSectorUnit=%u, \
2334 cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize, (unsigned int)sectors_per_unit,
2335 (unsigned int)bytes_per_sector, (unsigned int)dsize, (unsigned int)dfree));
2336 SBIG_UINT(pdata,0,dsize);
2337 SBIG_UINT(pdata,8,dfree);
2338 SIVAL(pdata,16,sectors_per_unit);
2339 SIVAL(pdata,20,bytes_per_sector);
2343 case SMB_FS_FULL_SIZE_INFORMATION:
2345 SMB_BIG_UINT dfree,dsize,bsize,block_size,sectors_per_unit,bytes_per_sector;
2347 if (get_dfree_info(conn,".",False,&bsize,&dfree,&dsize) == (SMB_BIG_UINT)-1) {
2348 return(UNIXERROR(ERRHRD,ERRgeneral));
2350 block_size = lp_block_size(snum);
2351 if (bsize < block_size) {
2352 SMB_BIG_UINT factor = block_size/bsize;
2357 if (bsize > block_size) {
2358 SMB_BIG_UINT factor = bsize/block_size;
2363 bytes_per_sector = 512;
2364 sectors_per_unit = bsize/bytes_per_sector;
2365 DEBUG(5,("call_trans2qfsinfo : SMB_QUERY_FS_FULL_SIZE_INFO bsize=%u, cSectorUnit=%u, \
2366 cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize, (unsigned int)sectors_per_unit,
2367 (unsigned int)bytes_per_sector, (unsigned int)dsize, (unsigned int)dfree));
2368 SBIG_UINT(pdata,0,dsize); /* Total Allocation units. */
2369 SBIG_UINT(pdata,8,dfree); /* Caller available allocation units. */
2370 SBIG_UINT(pdata,16,dfree); /* Actual available allocation units. */
2371 SIVAL(pdata,24,sectors_per_unit); /* Sectors per allocation unit. */
2372 SIVAL(pdata,28,bytes_per_sector); /* Bytes per sector. */
2376 case SMB_QUERY_FS_DEVICE_INFO:
2377 case SMB_FS_DEVICE_INFORMATION:
2379 SIVAL(pdata,0,0); /* dev type */
2380 SIVAL(pdata,4,0); /* characteristics */
2383 #ifdef HAVE_SYS_QUOTAS
2384 case SMB_FS_QUOTA_INFORMATION:
2386 * what we have to send --metze:
2388 * Unknown1: 24 NULL bytes
2389 * Soft Quota Treshold: 8 bytes seems like SMB_BIG_UINT or so
2390 * Hard Quota Limit: 8 bytes seems like SMB_BIG_UINT or so
2391 * Quota Flags: 2 byte :
2392 * Unknown3: 6 NULL bytes
2396 * details for Quota Flags:
2398 * 0x0020 Log Limit: log if the user exceeds his Hard Quota
2399 * 0x0010 Log Warn: log if the user exceeds his Soft Quota
2400 * 0x0002 Deny Disk: deny disk access when the user exceeds his Hard Quota
2401 * 0x0001 Enable Quotas: enable quota for this fs
2405 /* we need to fake up a fsp here,
2406 * because its not send in this call
2409 SMB_NTQUOTA_STRUCT quotas;
2412 ZERO_STRUCT(quotas);
2418 if (current_user.ut.uid != 0) {
2419 DEBUG(0,("set_user_quota: access_denied service [%s] user [%s]\n",
2420 lp_servicename(SNUM(conn)),conn->user));
2421 return ERROR_DOS(ERRDOS,ERRnoaccess);
2424 if (vfs_get_ntquota(&fsp, SMB_USER_FS_QUOTA_TYPE, NULL, "as)!=0) {
2425 DEBUG(0,("vfs_get_ntquota() failed for service [%s]\n",lp_servicename(SNUM(conn))));
2426 return ERROR_DOS(ERRSRV,ERRerror);
2431 DEBUG(10,("SMB_FS_QUOTA_INFORMATION: for service [%s]\n",lp_servicename(SNUM(conn))));
2433 /* Unknown1 24 NULL bytes*/
2434 SBIG_UINT(pdata,0,(SMB_BIG_UINT)0);
2435 SBIG_UINT(pdata,8,(SMB_BIG_UINT)0);
2436 SBIG_UINT(pdata,16,(SMB_BIG_UINT)0);
2438 /* Default Soft Quota 8 bytes */
2439 SBIG_UINT(pdata,24,quotas.softlim);
2441 /* Default Hard Quota 8 bytes */
2442 SBIG_UINT(pdata,32,quotas.hardlim);
2444 /* Quota flag 2 bytes */
2445 SSVAL(pdata,40,quotas.qflags);
2447 /* Unknown3 6 NULL bytes */
2453 #endif /* HAVE_SYS_QUOTAS */
2454 case SMB_FS_OBJECTID_INFORMATION:
2459 * Query the version and capabilities of the CIFS UNIX extensions
2463 case SMB_QUERY_CIFS_UNIX_INFO:
2464 if (!lp_unix_extensions()) {
2465 return ERROR_NT(NT_STATUS_INVALID_LEVEL);
2468 SSVAL(pdata,0,CIFS_UNIX_MAJOR_VERSION);
2469 SSVAL(pdata,2,CIFS_UNIX_MINOR_VERSION);
2470 /* We have POSIX ACLs, pathname and locking capability. */
2471 SBIG_UINT(pdata,4,((SMB_BIG_UINT)(
2472 CIFS_UNIX_POSIX_ACLS_CAP|
2473 CIFS_UNIX_POSIX_PATHNAMES_CAP|
2474 CIFS_UNIX_FCNTL_LOCKS_CAP)));
2477 case SMB_QUERY_POSIX_FS_INFO:
2480 vfs_statvfs_struct svfs;
2482 if (!lp_unix_extensions()) {
2483 return ERROR_NT(NT_STATUS_INVALID_LEVEL);
2486 rc = SMB_VFS_STATVFS(conn, ".", &svfs);
2490 SIVAL(pdata,0,svfs.OptimalTransferSize);
2491 SIVAL(pdata,4,svfs.BlockSize);
2492 SBIG_UINT(pdata,8,svfs.TotalBlocks);
2493 SBIG_UINT(pdata,16,svfs.BlocksAvail);
2494 SBIG_UINT(pdata,24,svfs.UserBlocksAvail);
2495 SBIG_UINT(pdata,32,svfs.TotalFileNodes);
2496 SBIG_UINT(pdata,40,svfs.FreeFileNodes);
2497 SBIG_UINT(pdata,48,svfs.FsIdentifier);
2498 DEBUG(5,("call_trans2qfsinfo : SMB_QUERY_POSIX_FS_INFO succsessful\n"));
2500 } else if (rc == EOPNOTSUPP) {
2501 return ERROR_NT(NT_STATUS_INVALID_LEVEL);
2502 #endif /* EOPNOTSUPP */
2504 DEBUG(0,("vfs_statvfs() failed for service [%s]\n",lp_servicename(SNUM(conn))));
2505 return ERROR_DOS(ERRSRV,ERRerror);
2510 case SMB_MAC_QUERY_FS_INFO:
2512 * Thursby MAC extension... ONLY on NTFS filesystems
2513 * once we do streams then we don't need this
2515 if (strequal(lp_fstype(SNUM(conn)),"NTFS")) {
2517 SIVAL(pdata,84,0x100); /* Don't support mac... */
2522 return ERROR_NT(NT_STATUS_INVALID_LEVEL);
2526 send_trans2_replies( outbuf, bufsize, params, 0, pdata, data_len, max_data_bytes);
2528 DEBUG( 4, ( "%s info_level = %d\n", smb_fn_name(CVAL(inbuf,smb_com)), info_level) );
2533 /****************************************************************************
2534 Reply to a TRANS2_SETFSINFO (set filesystem info).
2535 ****************************************************************************/
2537 static int call_trans2setfsinfo(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize,
2538 char **pparams, int total_params, char **ppdata, int total_data,
2539 unsigned int max_data_bytes)
2541 char *pdata = *ppdata;
2542 char *params = *pparams;
2546 DEBUG(10,("call_trans2setfsinfo: for service [%s]\n",lp_servicename(SNUM(conn))));
2549 if (total_params < 4) {
2550 DEBUG(0,("call_trans2setfsinfo: requires total_params(%d) >= 4 bytes!\n",
2552 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
2555 info_level = SVAL(params,2);
2557 switch(info_level) {
2558 case SMB_SET_CIFS_UNIX_INFO:
2560 uint16 client_unix_major;
2561 uint16 client_unix_minor;
2562 uint32 client_unix_cap_low;
2563 uint32 client_unix_cap_high;
2565 if (!lp_unix_extensions()) {
2566 return ERROR_NT(NT_STATUS_INVALID_LEVEL);
2569 /* There should be 12 bytes of capabilities set. */
2570 if (total_data < 8) {
2571 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
2573 client_unix_major = SVAL(pdata,0);
2574 client_unix_minor = SVAL(pdata,2);
2575 client_unix_cap_low = IVAL(pdata,4);
2576 client_unix_cap_high = IVAL(pdata,8);
2577 /* Just print these values for now. */
2578 DEBUG(10,("call_trans2setfsinfo: set unix info. major = %u, minor = %u \
2579 cap_low = 0x%x, cap_high = 0x%x\n",
2580 (unsigned int)client_unix_major,
2581 (unsigned int)client_unix_minor,
2582 (unsigned int)client_unix_cap_low,
2583 (unsigned int)client_unix_cap_high ));
2585 /* Here is where we must switch to posix pathname processing... */
2586 if (client_unix_cap_low & CIFS_UNIX_POSIX_PATHNAMES_CAP) {
2587 lp_set_posix_pathnames();
2588 mangle_change_to_posix();
2591 if (client_unix_cap_low & CIFS_UNIX_FCNTL_LOCKS_CAP) {
2592 lp_set_posix_cifsx_locktype(POSIX_LOCK);
2596 case SMB_FS_QUOTA_INFORMATION:
2598 files_struct *fsp = NULL;
2599 SMB_NTQUOTA_STRUCT quotas;
2601 ZERO_STRUCT(quotas);
2604 if ((current_user.ut.uid != 0)||!CAN_WRITE(conn)) {
2605 DEBUG(0,("set_user_quota: access_denied service [%s] user [%s]\n",
2606 lp_servicename(SNUM(conn)),conn->user));
2607 return ERROR_DOS(ERRSRV,ERRaccess);
2610 /* note: normaly there're 48 bytes,
2611 * but we didn't use the last 6 bytes for now
2614 fsp = file_fsp(params,0);
2615 if (!CHECK_NTQUOTA_HANDLE_OK(fsp,conn)) {
2616 DEBUG(3,("TRANSACT_GET_USER_QUOTA: no valid QUOTA HANDLE\n"));
2617 return ERROR_NT(NT_STATUS_INVALID_HANDLE);
2620 if (total_data < 42) {
2621 DEBUG(0,("call_trans2setfsinfo: SET_FS_QUOTA: requires total_data(%d) >= 42 bytes!\n",
2623 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
2626 /* unknown_1 24 NULL bytes in pdata*/
2628 /* the soft quotas 8 bytes (SMB_BIG_UINT)*/
2629 quotas.softlim = (SMB_BIG_UINT)IVAL(pdata,24);
2630 #ifdef LARGE_SMB_OFF_T
2631 quotas.softlim |= (((SMB_BIG_UINT)IVAL(pdata,28)) << 32);
2632 #else /* LARGE_SMB_OFF_T */
2633 if ((IVAL(pdata,28) != 0)&&
2634 ((quotas.softlim != 0xFFFFFFFF)||
2635 (IVAL(pdata,28)!=0xFFFFFFFF))) {
2636 /* more than 32 bits? */
2637 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
2639 #endif /* LARGE_SMB_OFF_T */
2641 /* the hard quotas 8 bytes (SMB_BIG_UINT)*/
2642 quotas.hardlim = (SMB_BIG_UINT)IVAL(pdata,32);
2643 #ifdef LARGE_SMB_OFF_T
2644 quotas.hardlim |= (((SMB_BIG_UINT)IVAL(pdata,36)) << 32);
2645 #else /* LARGE_SMB_OFF_T */
2646 if ((IVAL(pdata,36) != 0)&&
2647 ((quotas.hardlim != 0xFFFFFFFF)||
2648 (IVAL(pdata,36)!=0xFFFFFFFF))) {
2649 /* more than 32 bits? */
2650 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
2652 #endif /* LARGE_SMB_OFF_T */
2654 /* quota_flags 2 bytes **/
2655 quotas.qflags = SVAL(pdata,40);
2657 /* unknown_2 6 NULL bytes follow*/
2659 /* now set the quotas */
2660 if (vfs_set_ntquota(fsp, SMB_USER_FS_QUOTA_TYPE, NULL, "as)!=0) {
2661 DEBUG(0,("vfs_set_ntquota() failed for service [%s]\n",lp_servicename(SNUM(conn))));
2662 return ERROR_DOS(ERRSRV,ERRerror);
2668 DEBUG(3,("call_trans2setfsinfo: unknown level (0x%X) not implemented yet.\n",
2670 return ERROR_NT(NT_STATUS_INVALID_LEVEL);
2675 * sending this reply works fine,
2676 * but I'm not sure it's the same
2677 * like windows do...
2680 outsize = set_message(outbuf,10,0,True);
2685 /****************************************************************************
2686 Utility function to set bad path error.
2687 ****************************************************************************/
2689 int set_bad_path_error(int err, BOOL bad_path, char *outbuf, int def_class, uint32 def_code)
2691 DEBUG(10,("set_bad_path_error: err = %d bad_path = %d\n",
2692 err, (int)bad_path ));
2696 return ERROR_NT(NT_STATUS_OBJECT_PATH_NOT_FOUND);
2698 return ERROR_NT(NT_STATUS_OBJECT_NAME_NOT_FOUND);
2701 return UNIXERROR(def_class,def_code);
2704 #if defined(HAVE_POSIX_ACLS)
2705 /****************************************************************************
2706 Utility function to count the number of entries in a POSIX acl.
2707 ****************************************************************************/
2709 static unsigned int count_acl_entries(connection_struct *conn, SMB_ACL_T posix_acl)
2711 unsigned int ace_count = 0;
2712 int entry_id = SMB_ACL_FIRST_ENTRY;
2713 SMB_ACL_ENTRY_T entry;
2715 while ( posix_acl && (SMB_VFS_SYS_ACL_GET_ENTRY(conn, posix_acl, entry_id, &entry) == 1)) {
2717 if (entry_id == SMB_ACL_FIRST_ENTRY) {
2718 entry_id = SMB_ACL_NEXT_ENTRY;
2725 /****************************************************************************
2726 Utility function to marshall a POSIX acl into wire format.
2727 ****************************************************************************/
2729 static BOOL marshall_posix_acl(connection_struct *conn, char *pdata, SMB_STRUCT_STAT *pst, SMB_ACL_T posix_acl)
2731 int entry_id = SMB_ACL_FIRST_ENTRY;
2732 SMB_ACL_ENTRY_T entry;
2734 while ( posix_acl && (SMB_VFS_SYS_ACL_GET_ENTRY(conn, posix_acl, entry_id, &entry) == 1)) {
2735 SMB_ACL_TAG_T tagtype;
2736 SMB_ACL_PERMSET_T permset;
2737 unsigned char perms = 0;
2738 unsigned int own_grp;
2741 if (entry_id == SMB_ACL_FIRST_ENTRY) {
2742 entry_id = SMB_ACL_NEXT_ENTRY;
2745 if (SMB_VFS_SYS_ACL_GET_TAG_TYPE(conn, entry, &tagtype) == -1) {
2746 DEBUG(0,("marshall_posix_acl: SMB_VFS_SYS_ACL_GET_TAG_TYPE failed.\n"));
2750 if (SMB_VFS_SYS_ACL_GET_PERMSET(conn, entry, &permset) == -1) {
2751 DEBUG(0,("marshall_posix_acl: SMB_VFS_SYS_ACL_GET_PERMSET failed.\n"));
2755 perms |= (SMB_VFS_SYS_ACL_GET_PERM(conn, permset, SMB_ACL_READ) ? SMB_POSIX_ACL_READ : 0);
2756 perms |= (SMB_VFS_SYS_ACL_GET_PERM(conn, permset, SMB_ACL_WRITE) ? SMB_POSIX_ACL_WRITE : 0);
2757 perms |= (SMB_VFS_SYS_ACL_GET_PERM(conn, permset, SMB_ACL_EXECUTE) ? SMB_POSIX_ACL_EXECUTE : 0);
2759 SCVAL(pdata,1,perms);
2762 case SMB_ACL_USER_OBJ:
2763 SCVAL(pdata,0,SMB_POSIX_ACL_USER_OBJ);
2764 own_grp = (unsigned int)pst->st_uid;
2765 SIVAL(pdata,2,own_grp);
2770 uid_t *puid = (uid_t *)SMB_VFS_SYS_ACL_GET_QUALIFIER(conn, entry);
2772 DEBUG(0,("marshall_posix_acl: SMB_VFS_SYS_ACL_GET_QUALIFIER failed.\n"));
2774 own_grp = (unsigned int)*puid;
2775 SMB_VFS_SYS_ACL_FREE_QUALIFIER(conn, (void *)puid,tagtype);
2776 SCVAL(pdata,0,SMB_POSIX_ACL_USER);
2777 SIVAL(pdata,2,own_grp);
2781 case SMB_ACL_GROUP_OBJ:
2782 SCVAL(pdata,0,SMB_POSIX_ACL_GROUP_OBJ);
2783 own_grp = (unsigned int)pst->st_gid;
2784 SIVAL(pdata,2,own_grp);
2789 gid_t *pgid= (gid_t *)SMB_VFS_SYS_ACL_GET_QUALIFIER(conn, entry);
2791 DEBUG(0,("marshall_posix_acl: SMB_VFS_SYS_ACL_GET_QUALIFIER failed.\n"));
2793 own_grp = (unsigned int)*pgid;
2794 SMB_VFS_SYS_ACL_FREE_QUALIFIER(conn, (void *)pgid,tagtype);
2795 SCVAL(pdata,0,SMB_POSIX_ACL_GROUP);
2796 SIVAL(pdata,2,own_grp);
2801 SCVAL(pdata,0,SMB_POSIX_ACL_MASK);
2802 SIVAL(pdata,2,0xFFFFFFFF);
2803 SIVAL(pdata,6,0xFFFFFFFF);
2806 SCVAL(pdata,0,SMB_POSIX_ACL_OTHER);
2807 SIVAL(pdata,2,0xFFFFFFFF);
2808 SIVAL(pdata,6,0xFFFFFFFF);
2811 DEBUG(0,("marshall_posix_acl: unknown tagtype.\n"));
2814 pdata += SMB_POSIX_ACL_ENTRY_SIZE;
2821 /****************************************************************************
2822 Reply to a TRANS2_QFILEPATHINFO or TRANSACT2_QFILEINFO (query file info by
2823 file name or file id).
2824 ****************************************************************************/
2826 static int call_trans2qfilepathinfo(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize,
2827 unsigned int tran_call,
2828 char **pparams, int total_params, char **ppdata, int total_data,
2829 unsigned int max_data_bytes)
2831 char *params = *pparams;
2832 char *pdata = *ppdata;
2836 SMB_OFF_T file_size=0;
2837 SMB_BIG_UINT allocation_size=0;
2838 unsigned int data_size = 0;
2839 unsigned int param_size = 2;
2840 SMB_STRUCT_STAT sbuf;
2841 pstring fname, dos_fname;
2846 BOOL bad_path = False;
2847 BOOL delete_pending = False;
2849 time_t create_time, mtime, atime;
2850 struct timespec create_time_ts, mtime_ts, atime_ts;
2851 files_struct *fsp = NULL;
2852 TALLOC_CTX *data_ctx = NULL;
2853 struct ea_list *ea_list = NULL;
2854 uint32 access_mask = 0x12019F; /* Default - GENERIC_EXECUTE mapping from Windows */
2855 char *lock_data = NULL;
2858 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
2862 if (tran_call == TRANSACT2_QFILEINFO) {
2863 if (total_params < 4) {
2864 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
2867 fsp = file_fsp(params,0);
2868 info_level = SVAL(params,2);
2870 DEBUG(3,("call_trans2qfilepathinfo: TRANSACT2_QFILEINFO: level = %d\n", info_level));
2872 if(fsp && (fsp->fake_file_handle)) {
2874 * This is actually for the QUOTA_FAKE_FILE --metze
2877 pstrcpy(fname, fsp->fsp_name);
2878 /* We know this name is ok, it's already passed the checks. */
2880 } else if(fsp && (fsp->is_directory || fsp->fh->fd == -1)) {
2882 * This is actually a QFILEINFO on a directory
2883 * handle (returned from an NT SMB). NT5.0 seems
2884 * to do this call. JRA.
2886 /* We know this name is ok, it's already passed the checks. */
2887 pstrcpy(fname, fsp->fsp_name);
2889 if (INFO_LEVEL_IS_UNIX(info_level)) {
2890 /* Always do lstat for UNIX calls. */
2891 if (SMB_VFS_LSTAT(conn,fname,&sbuf)) {
2892 DEBUG(3,("call_trans2qfilepathinfo: SMB_VFS_LSTAT of %s failed (%s)\n",fname,strerror(errno)));
2893 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRbadpath);
2895 } else if (SMB_VFS_STAT(conn,fname,&sbuf)) {
2896 DEBUG(3,("call_trans2qfilepathinfo: SMB_VFS_STAT of %s failed (%s)\n",fname,strerror(errno)));
2897 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRbadpath);
2900 delete_pending = get_delete_on_close_flag(sbuf.st_dev, sbuf.st_ino);
2903 * Original code - this is an open file.
2905 CHECK_FSP(fsp,conn);
2907 pstrcpy(fname, fsp->fsp_name);
2908 if (SMB_VFS_FSTAT(fsp,fsp->fh->fd,&sbuf) != 0) {
2909 DEBUG(3,("fstat of fnum %d failed (%s)\n", fsp->fnum, strerror(errno)));
2910 return(UNIXERROR(ERRDOS,ERRbadfid));
2912 pos = fsp->fh->position_information;
2913 delete_pending = get_delete_on_close_flag(sbuf.st_dev, sbuf.st_ino);
2914 access_mask = fsp->access_mask;
2917 NTSTATUS status = NT_STATUS_OK;
2920 if (total_params < 6) {
2921 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
2924 info_level = SVAL(params,0);
2926 DEBUG(3,("call_trans2qfilepathinfo: TRANSACT2_QPATHINFO: level = %d\n", info_level));
2928 srvstr_get_path(inbuf, fname, ¶ms[6], sizeof(fname), -1, STR_TERMINATE, &status);
2929 if (!NT_STATUS_IS_OK(status)) {
2930 return ERROR_NT(status);
2933 RESOLVE_DFSPATH(fname, conn, inbuf, outbuf);
2935 unix_convert(fname,conn,0,&bad_path,&sbuf);
2937 return ERROR_NT(NT_STATUS_OBJECT_PATH_NOT_FOUND);
2939 if (!check_name(fname,conn)) {
2940 DEBUG(3,("call_trans2qfilepathinfo: fileinfo of %s failed (%s)\n",fname,strerror(errno)));
2941 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRbadpath);
2944 if (INFO_LEVEL_IS_UNIX(info_level)) {
2945 /* Always do lstat for UNIX calls. */
2946 if (SMB_VFS_LSTAT(conn,fname,&sbuf)) {
2947 DEBUG(3,("call_trans2qfilepathinfo: SMB_VFS_LSTAT of %s failed (%s)\n",fname,strerror(errno)));
2948 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRbadpath);
2950 } else if (!VALID_STAT(sbuf) && SMB_VFS_STAT(conn,fname,&sbuf) && (info_level != SMB_INFO_IS_NAME_VALID)) {
2951 DEBUG(3,("call_trans2qfilepathinfo: SMB_VFS_STAT of %s failed (%s)\n",fname,strerror(errno)));
2952 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRbadpath);
2955 delete_pending = get_delete_on_close_flag(sbuf.st_dev, sbuf.st_ino);
2956 if (delete_pending) {
2957 return ERROR_NT(NT_STATUS_DELETE_PENDING);
2961 nlink = sbuf.st_nlink;
2963 if ((nlink > 0) && S_ISDIR(sbuf.st_mode)) {
2964 /* NTFS does not seem to count ".." */
2968 if ((nlink > 0) && delete_pending) {
2972 if (INFO_LEVEL_IS_UNIX(info_level) && !lp_unix_extensions()) {
2973 return ERROR_NT(NT_STATUS_INVALID_LEVEL);
2976 DEBUG(3,("call_trans2qfilepathinfo %s (fnum = %d) level=%d call=%d total_data=%d\n",
2977 fname,fsp ? fsp->fnum : -1, info_level,tran_call,total_data));
2979 p = strrchr_m(fname,'/');
2985 mode = dos_mode(conn,fname,&sbuf);
2987 mode = FILE_ATTRIBUTE_NORMAL;
2989 fullpathname = fname;
2991 file_size = get_file_size(sbuf);
2993 /* Pull out any data sent here before we realloc. */
2994 switch (info_level) {
2995 case SMB_INFO_QUERY_EAS_FROM_LIST:
2997 /* Pull any EA list from the data portion. */
3000 if (total_data < 4) {
3001 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
3003 ea_size = IVAL(pdata,0);
3005 if (total_data > 0 && ea_size != total_data) {
3006 DEBUG(4,("call_trans2qfilepathinfo: Rejecting EA request with incorrect \
3007 total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pdata,0) ));
3008 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
3011 if (!lp_ea_support(SNUM(conn))) {
3012 return ERROR_DOS(ERRDOS,ERReasnotsupported);
3015 if ((data_ctx = talloc_init("ea_list")) == NULL) {
3016 return ERROR_NT(NT_STATUS_NO_MEMORY);
3019 /* Pull out the list of names. */
3020 ea_list = read_ea_name_list(data_ctx, pdata + 4, ea_size - 4);
3022 talloc_destroy(data_ctx);
3023 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
3028 case SMB_QUERY_POSIX_LOCK:
3030 if (fsp == NULL || fsp->fh->fd == -1) {
3031 return ERROR_NT(NT_STATUS_INVALID_HANDLE);
3034 if (total_data != POSIX_LOCK_DATA_SIZE) {
3035 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
3038 if ((data_ctx = talloc_init("lock_request")) == NULL) {
3039 return ERROR_NT(NT_STATUS_NO_MEMORY);
3042 /* Copy the lock range data. */
3043 lock_data = (char *)talloc_memdup(
3044 data_ctx, pdata, total_data);
3046 talloc_destroy(data_ctx);
3047 return ERROR_NT(NT_STATUS_NO_MEMORY);
3054 *pparams = (char *)SMB_REALLOC(*pparams,2);
3055 if (*pparams == NULL) {
3056 talloc_destroy(data_ctx);
3057 return ERROR_NT(NT_STATUS_NO_MEMORY);
3061 data_size = max_data_bytes + DIR_ENTRY_SAFETY_MARGIN;
3062 *ppdata = (char *)SMB_REALLOC(*ppdata, data_size);
3063 if (*ppdata == NULL ) {
3064 talloc_destroy(data_ctx);
3065 return ERROR_NT(NT_STATUS_NO_MEMORY);
3069 create_time_ts = get_create_timespec(&sbuf,lp_fake_dir_create_times(SNUM(conn)));
3070 mtime_ts = get_mtimespec(&sbuf);
3071 atime_ts = get_atimespec(&sbuf);
3073 allocation_size = get_allocation_size(conn,fsp,&sbuf);
3076 if (fsp->pending_modtime) {
3077 /* the pending modtime overrides the current modtime */
3078 mtime_ts.tv_sec = fsp->pending_modtime;
3079 mtime_ts.tv_nsec = 0;
3082 /* Do we have this path open ? */
3083 files_struct *fsp1 = file_find_di_first(sbuf.st_dev, sbuf.st_ino);
3084 if (fsp1 && fsp1->pending_modtime) {
3085 /* the pending modtime overrides the current modtime */
3086 mtime_ts.tv_sec = fsp1->pending_modtime;
3087 mtime_ts.tv_nsec = 0;
3089 if (fsp1 && fsp1->initial_allocation_size) {
3090 allocation_size = get_allocation_size(conn, fsp1, &sbuf);
3094 if (lp_dos_filetime_resolution(SNUM(conn))) {
3095 dos_filetime_timespec(&create_time_ts);
3096 dos_filetime_timespec(&mtime_ts);
3097 dos_filetime_timespec(&atime_ts);
3100 create_time = convert_timespec_to_time_t(create_time_ts);
3101 mtime = convert_timespec_to_time_t(mtime_ts);
3102 atime = convert_timespec_to_time_t(atime_ts);
3104 /* NT expects the name to be in an exact form of the *full*
3105 filename. See the trans2 torture test */
3106 if (strequal(base_name,".")) {
3107 pstrcpy(dos_fname, "\\");
3109 pstr_sprintf(dos_fname, "\\%s", fname);
3110 string_replace(dos_fname, '/', '\\');
3113 switch (info_level) {
3114 case SMB_INFO_STANDARD:
3115 DEBUG(10,("call_trans2qfilepathinfo: SMB_INFO_STANDARD\n"));
3117 srv_put_dos_date2(pdata,l1_fdateCreation,create_time);
3118 srv_put_dos_date2(pdata,l1_fdateLastAccess,atime);
3119 srv_put_dos_date2(pdata,l1_fdateLastWrite,mtime); /* write time */
3120 SIVAL(pdata,l1_cbFile,(uint32)file_size);
3121 SIVAL(pdata,l1_cbFileAlloc,(uint32)allocation_size);
3122 SSVAL(pdata,l1_attrFile,mode);
3125 case SMB_INFO_QUERY_EA_SIZE:
3127 unsigned int ea_size = estimate_ea_size(conn, fsp, fname);
3128 DEBUG(10,("call_trans2qfilepathinfo: SMB_INFO_QUERY_EA_SIZE\n"));
3130 srv_put_dos_date2(pdata,0,create_time);
3131 srv_put_dos_date2(pdata,4,atime);
3132 srv_put_dos_date2(pdata,8,mtime); /* write time */
3133 SIVAL(pdata,12,(uint32)file_size);
3134 SIVAL(pdata,16,(uint32)allocation_size);
3135 SSVAL(pdata,20,mode);
3136 SIVAL(pdata,22,ea_size);
3140 case SMB_INFO_IS_NAME_VALID:
3141 DEBUG(10,("call_trans2qfilepathinfo: SMB_INFO_IS_NAME_VALID\n"));
3142 if (tran_call == TRANSACT2_QFILEINFO) {
3143 /* os/2 needs this ? really ?*/
3144 return ERROR_DOS(ERRDOS,ERRbadfunc);
3150 case SMB_INFO_QUERY_EAS_FROM_LIST:
3152 size_t total_ea_len = 0;
3153 struct ea_list *ea_file_list = NULL;
3155 DEBUG(10,("call_trans2qfilepathinfo: SMB_INFO_QUERY_EAS_FROM_LIST\n"));
3157 ea_file_list = get_ea_list_from_file(data_ctx, conn, fsp, fname, &total_ea_len);
3158 ea_list = ea_list_union(ea_list, ea_file_list, &total_ea_len);
3160 if (!ea_list || (total_ea_len > data_size)) {
3161 talloc_destroy(data_ctx);
3163 SIVAL(pdata,0,4); /* EA List Length must be set to 4 if no EA's. */
3167 data_size = fill_ea_buffer(data_ctx, pdata, data_size, conn, ea_list);
3168 talloc_destroy(data_ctx);
3172 case SMB_INFO_QUERY_ALL_EAS:
3174 /* We have data_size bytes to put EA's into. */
3175 size_t total_ea_len = 0;
3177 DEBUG(10,("call_trans2qfilepathinfo: SMB_INFO_QUERY_ALL_EAS\n"));
3179 data_ctx = talloc_init("ea_ctx");
3181 return ERROR_NT(NT_STATUS_NO_MEMORY);
3184 ea_list = get_ea_list_from_file(data_ctx, conn, fsp, fname, &total_ea_len);
3185 if (!ea_list || (total_ea_len > data_size)) {
3186 talloc_destroy(data_ctx);
3188 SIVAL(pdata,0,4); /* EA List Length must be set to 4 if no EA's. */
3192 data_size = fill_ea_buffer(data_ctx, pdata, data_size, conn, ea_list);
3193 talloc_destroy(data_ctx);
3197 case SMB_FILE_BASIC_INFORMATION:
3198 case SMB_QUERY_FILE_BASIC_INFO:
3200 if (info_level == SMB_QUERY_FILE_BASIC_INFO) {
3201 DEBUG(10,("call_trans2qfilepathinfo: SMB_QUERY_FILE_BASIC_INFO\n"));
3202 data_size = 36; /* w95 returns 40 bytes not 36 - why ?. */
3204 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_BASIC_INFORMATION\n"));
3208 put_long_date_timespec(pdata,create_time_ts);
3209 put_long_date_timespec(pdata+8,atime_ts);
3210 put_long_date_timespec(pdata+16,mtime_ts); /* write time */
3211 put_long_date_timespec(pdata+24,mtime_ts); /* change time */
3212 SIVAL(pdata,32,mode);
3214 DEBUG(5,("SMB_QFBI - "));
3215 DEBUG(5,("create: %s ", ctime(&create_time)));
3216 DEBUG(5,("access: %s ", ctime(&atime)));
3217 DEBUG(5,("write: %s ", ctime(&mtime)));
3218 DEBUG(5,("change: %s ", ctime(&mtime)));
3219 DEBUG(5,("mode: %x\n", mode));
3222 case SMB_FILE_STANDARD_INFORMATION:
3223 case SMB_QUERY_FILE_STANDARD_INFO:
3225 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_STANDARD_INFORMATION\n"));
3227 SOFF_T(pdata,0,allocation_size);
3228 SOFF_T(pdata,8,file_size);
3229 SIVAL(pdata,16,nlink);
3230 SCVAL(pdata,20,delete_pending?1:0);
3231 SCVAL(pdata,21,(mode&aDIR)?1:0);
3232 SSVAL(pdata,22,0); /* Padding. */
3235 case SMB_FILE_EA_INFORMATION:
3236 case SMB_QUERY_FILE_EA_INFO:
3238 unsigned int ea_size = estimate_ea_size(conn, fsp, fname);
3239 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_EA_INFORMATION\n"));
3241 SIVAL(pdata,0,ea_size);
3245 /* Get the 8.3 name - used if NT SMB was negotiated. */
3246 case SMB_QUERY_FILE_ALT_NAME_INFO:
3247 case SMB_FILE_ALTERNATE_NAME_INFORMATION:
3251 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_ALTERNATE_NAME_INFORMATION\n"));
3252 pstrcpy(short_name,base_name);
3253 /* Mangle if not already 8.3 */
3254 if(!mangle_is_8_3(short_name, True, conn->params)) {
3255 mangle_map(short_name,True,True,conn->params);
3257 len = srvstr_push(outbuf, pdata+4, short_name, -1, STR_UNICODE);
3258 data_size = 4 + len;
3263 case SMB_QUERY_FILE_NAME_INFO:
3265 this must be *exactly* right for ACLs on mapped drives to work
3267 len = srvstr_push(outbuf, pdata+4, dos_fname, -1, STR_UNICODE);
3268 DEBUG(10,("call_trans2qfilepathinfo: SMB_QUERY_FILE_NAME_INFO\n"));
3269 data_size = 4 + len;
3273 case SMB_FILE_ALLOCATION_INFORMATION:
3274 case SMB_QUERY_FILE_ALLOCATION_INFO:
3275 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_ALLOCATION_INFORMATION\n"));
3277 SOFF_T(pdata,0,allocation_size);
3280 case SMB_FILE_END_OF_FILE_INFORMATION:
3281 case SMB_QUERY_FILE_END_OF_FILEINFO:
3282 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_END_OF_FILE_INFORMATION\n"));
3284 SOFF_T(pdata,0,file_size);
3287 case SMB_QUERY_FILE_ALL_INFO:
3288 case SMB_FILE_ALL_INFORMATION:
3290 unsigned int ea_size = estimate_ea_size(conn, fsp, fname);
3291 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_ALL_INFORMATION\n"));
3292 put_long_date_timespec(pdata,create_time_ts);
3293 put_long_date_timespec(pdata+8,atime_ts);
3294 put_long_date_timespec(pdata+16,mtime_ts); /* write time */
3295 put_long_date_timespec(pdata+24,mtime_ts); /* change time */
3296 SIVAL(pdata,32,mode);
3297 SIVAL(pdata,36,0); /* padding. */
3299 SOFF_T(pdata,0,allocation_size);
3300 SOFF_T(pdata,8,file_size);
3301 SIVAL(pdata,16,nlink);
3302 SCVAL(pdata,20,delete_pending);
3303 SCVAL(pdata,21,(mode&aDIR)?1:0);
3306 SIVAL(pdata,0,ea_size);
3307 pdata += 4; /* EA info */
3308 len = srvstr_push(outbuf, pdata+4, dos_fname, -1, STR_UNICODE);
3311 data_size = PTR_DIFF(pdata,(*ppdata));
3314 case SMB_FILE_INTERNAL_INFORMATION:
3315 /* This should be an index number - looks like
3318 I think this causes us to fail the IFSKIT
3319 BasicFileInformationTest. -tpot */
3321 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_INTERNAL_INFORMATION\n"));
3322 SIVAL(pdata,0,sbuf.st_ino); /* FileIndexLow */
3323 SIVAL(pdata,4,sbuf.st_dev); /* FileIndexHigh */
3327 case SMB_FILE_ACCESS_INFORMATION:
3328 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_ACCESS_INFORMATION\n"));
3329 SIVAL(pdata,0,access_mask);
3333 case SMB_FILE_NAME_INFORMATION:
3334 /* Pathname with leading '\'. */
3337 byte_len = dos_PutUniCode(pdata+4,dos_fname,(size_t)max_data_bytes,False);
3338 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_NAME_INFORMATION\n"));
3339 SIVAL(pdata,0,byte_len);
3340 data_size = 4 + byte_len;
3344 case SMB_FILE_DISPOSITION_INFORMATION:
3345 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_DISPOSITION_INFORMATION\n"));
3347 SCVAL(pdata,0,delete_pending);
3350 case SMB_FILE_POSITION_INFORMATION:
3351 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_POSITION_INFORMATION\n"));
3353 SOFF_T(pdata,0,pos);
3356 case SMB_FILE_MODE_INFORMATION:
3357 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_MODE_INFORMATION\n"));
3358 SIVAL(pdata,0,mode);
3362 case SMB_FILE_ALIGNMENT_INFORMATION:
3363 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_ALIGNMENT_INFORMATION\n"));
3364 SIVAL(pdata,0,0); /* No alignment needed. */
3370 * NT4 server just returns "invalid query" to this - if we try to answer
3371 * it then NTws gets a BSOD! (tridge).
3372 * W2K seems to want this. JRA.
3374 case SMB_QUERY_FILE_STREAM_INFO:
3376 case SMB_FILE_STREAM_INFORMATION:
3377 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_STREAM_INFORMATION\n"));
3381 size_t byte_len = dos_PutUniCode(pdata+24,"::$DATA", (size_t)0xE, False);
3382 SIVAL(pdata,0,0); /* ??? */
3383 SIVAL(pdata,4,byte_len); /* Byte length of unicode string ::$DATA */
3384 SOFF_T(pdata,8,file_size);
3385 SIVAL(pdata,16,allocation_size);
3386 SIVAL(pdata,20,0); /* ??? */
3387 data_size = 24 + byte_len;
3391 case SMB_QUERY_COMPRESSION_INFO:
3392 case SMB_FILE_COMPRESSION_INFORMATION:
3393 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_COMPRESSION_INFORMATION\n"));
3394 SOFF_T(pdata,0,file_size);
3395 SIVAL(pdata,8,0); /* ??? */
3396 SIVAL(pdata,12,0); /* ??? */
3400 case SMB_FILE_NETWORK_OPEN_INFORMATION:
3401 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_NETWORK_OPEN_INFORMATION\n"));
3402 put_long_date_timespec(pdata,create_time_ts);
3403 put_long_date_timespec(pdata+8,atime_ts);
3404 put_long_date_timespec(pdata+16,mtime_ts); /* write time */
3405 put_long_date_timespec(pdata+24,mtime_ts); /* change time */
3406 SIVAL(pdata,32,allocation_size);
3407 SOFF_T(pdata,40,file_size);
3408 SIVAL(pdata,48,mode);
3409 SIVAL(pdata,52,0); /* ??? */
3413 case SMB_FILE_ATTRIBUTE_TAG_INFORMATION:
3414 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_ATTRIBUTE_TAG_INFORMATION\n"));
3415 SIVAL(pdata,0,mode);
3421 * CIFS UNIX Extensions.
3424 case SMB_QUERY_FILE_UNIX_BASIC:
3426 DEBUG(10,("call_trans2qfilepathinfo: SMB_QUERY_FILE_UNIX_BASIC\n"));
3427 DEBUG(4,("call_trans2qfilepathinfo: st_mode=%o\n",(int)sbuf.st_mode));
3429 SOFF_T(pdata,0,get_file_size(sbuf)); /* File size 64 Bit */
3432 SOFF_T(pdata,0,get_allocation_size(conn,fsp,&sbuf)); /* Number of bytes used on disk - 64 Bit */
3435 put_long_date_timespec(pdata,get_ctimespec(&sbuf)); /* Creation Time 64 Bit */
3436 put_long_date_timespec(pdata+8,get_atimespec(&sbuf)); /* Last access time 64 Bit */
3437 put_long_date_timespec(pdata+16,get_mtimespec(&sbuf)); /* Last modification time 64 Bit */
3440 SIVAL(pdata,0,sbuf.st_uid); /* user id for the owner */
3444 SIVAL(pdata,0,sbuf.st_gid); /* group id of owner */
3448 SIVAL(pdata,0,unix_filetype(sbuf.st_mode));
3451 SIVAL(pdata,0,unix_dev_major(sbuf.st_rdev)); /* Major device number if type is device */
3455 SIVAL(pdata,0,unix_dev_minor(sbuf.st_rdev)); /* Minor device number if type is device */
3459 SINO_T_VAL(pdata,0,(SMB_INO_T)sbuf.st_ino); /* inode number */
3462 SIVAL(pdata,0, unix_perms_to_wire(sbuf.st_mode)); /* Standard UNIX file permissions */
3466 SIVAL(pdata,0,sbuf.st_nlink); /* number of hard links */
3469 data_size = PTR_DIFF(pdata,(*ppdata));
3473 DEBUG(4,("call_trans2qfilepathinfo: SMB_QUERY_FILE_UNIX_BASIC "));
3475 for (i=0; i<100; i++)
3476 DEBUG(4,("%d=%x, ",i, (*ppdata)[i]));
3482 case SMB_QUERY_FILE_UNIX_LINK:
3486 DEBUG(10,("call_trans2qfilepathinfo: SMB_QUERY_FILE_UNIX_LINK\n"));
3488 if(!S_ISLNK(sbuf.st_mode))
3489 return(UNIXERROR(ERRSRV,ERRbadlink));
3491 return(UNIXERROR(ERRDOS,ERRbadlink));
3493 len = SMB_VFS_READLINK(conn,fullpathname, buffer, sizeof(pstring)-1); /* read link */
3495 return(UNIXERROR(ERRDOS,ERRnoaccess));
3497 len = srvstr_push(outbuf, pdata, buffer, -1, STR_TERMINATE);
3499 data_size = PTR_DIFF(pdata,(*ppdata));
3504 #if defined(HAVE_POSIX_ACLS)
3505 case SMB_QUERY_POSIX_ACL:
3507 SMB_ACL_T file_acl = NULL;
3508 SMB_ACL_T def_acl = NULL;
3509 uint16 num_file_acls = 0;
3510 uint16 num_def_acls = 0;
3512 if (fsp && !fsp->is_directory && (fsp->fh->fd != -1)) {
3513 file_acl = SMB_VFS_SYS_ACL_GET_FD(fsp, fsp->fh->fd);
3515 file_acl = SMB_VFS_SYS_ACL_GET_FILE(conn, fname, SMB_ACL_TYPE_ACCESS);
3518 if (file_acl == NULL && no_acl_syscall_error(errno)) {
3519 DEBUG(5,("call_trans2qfilepathinfo: ACLs not implemented on filesystem containing %s\n",
3521 return ERROR_NT(NT_STATUS_NOT_IMPLEMENTED);
3524 if (S_ISDIR(sbuf.st_mode)) {
3525 if (fsp && fsp->is_directory) {
3526 def_acl = SMB_VFS_SYS_ACL_GET_FILE(conn, fsp->fsp_name, SMB_ACL_TYPE_DEFAULT);
3528 def_acl = SMB_VFS_SYS_ACL_GET_FILE(conn, fname, SMB_ACL_TYPE_DEFAULT);
3530 def_acl = free_empty_sys_acl(conn, def_acl);
3533 num_file_acls = count_acl_entries(conn, file_acl);
3534 num_def_acls = count_acl_entries(conn, def_acl);
3536 if ( data_size < (num_file_acls + num_def_acls)*SMB_POSIX_ACL_ENTRY_SIZE + SMB_POSIX_ACL_HEADER_SIZE) {
3537 DEBUG(5,("call_trans2qfilepathinfo: data_size too small (%u) need %u\n",
3539 (unsigned int)((num_file_acls + num_def_acls)*SMB_POSIX_ACL_ENTRY_SIZE +
3540 SMB_POSIX_ACL_HEADER_SIZE) ));
3542 SMB_VFS_SYS_ACL_FREE_ACL(conn, file_acl);
3545 SMB_VFS_SYS_ACL_FREE_ACL(conn, def_acl);
3547 return ERROR_NT(NT_STATUS_BUFFER_TOO_SMALL);
3550 SSVAL(pdata,0,SMB_POSIX_ACL_VERSION);
3551 SSVAL(pdata,2,num_file_acls);
3552 SSVAL(pdata,4,num_def_acls);
3553 if (!marshall_posix_acl(conn, pdata + SMB_POSIX_ACL_HEADER_SIZE, &sbuf, file_acl)) {
3555 SMB_VFS_SYS_ACL_FREE_ACL(conn, file_acl);
3558 SMB_VFS_SYS_ACL_FREE_ACL(conn, def_acl);
3560 return ERROR_NT(NT_STATUS_INTERNAL_ERROR);
3562 if (!marshall_posix_acl(conn, pdata + SMB_POSIX_ACL_HEADER_SIZE + (num_file_acls*SMB_POSIX_ACL_ENTRY_SIZE), &sbuf, def_acl)) {
3564 SMB_VFS_SYS_ACL_FREE_ACL(conn, file_acl);
3567 SMB_VFS_SYS_ACL_FREE_ACL(conn, def_acl);
3569 return ERROR_NT(NT_STATUS_INTERNAL_ERROR);
3573 SMB_VFS_SYS_ACL_FREE_ACL(conn, file_acl);
3576 SMB_VFS_SYS_ACL_FREE_ACL(conn, def_acl);
3578 data_size = (num_file_acls + num_def_acls)*SMB_POSIX_ACL_ENTRY_SIZE + SMB_POSIX_ACL_HEADER_SIZE;
3584 case SMB_QUERY_POSIX_LOCK:
3586 NTSTATUS status = NT_STATUS_INVALID_LEVEL;
3588 SMB_BIG_UINT offset;
3590 enum brl_type lock_type;
3592 if (total_data != POSIX_LOCK_DATA_SIZE) {
3593 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
3596 switch (SVAL(pdata, POSIX_LOCK_TYPE_OFFSET)) {
3597 case POSIX_LOCK_TYPE_READ:
3598 lock_type = READ_LOCK;
3600 case POSIX_LOCK_TYPE_WRITE:
3601 lock_type = WRITE_LOCK;
3603 case POSIX_LOCK_TYPE_UNLOCK:
3605 /* There's no point in asking for an unlock... */
3606 talloc_destroy(data_ctx);
3607 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
3610 lock_pid = IVAL(pdata, POSIX_LOCK_PID_OFFSET);
3611 #if defined(HAVE_LONGLONG)
3612 offset = (((SMB_BIG_UINT) IVAL(pdata,(POSIX_LOCK_START_OFFSET+4))) << 32) |
3613 ((SMB_BIG_UINT) IVAL(pdata,POSIX_LOCK_START_OFFSET));
3614 count = (((SMB_BIG_UINT) IVAL(pdata,(POSIX_LOCK_LEN_OFFSET+4))) << 32) |
3615 ((SMB_BIG_UINT) IVAL(pdata,POSIX_LOCK_LEN_OFFSET));
3616 #else /* HAVE_LONGLONG */
3617 offset = (SMB_BIG_UINT)IVAL(pdata,POSIX_LOCK_START_OFFSET);
3618 count = (SMB_BIG_UINT)IVAL(pdata,POSIX_LOCK_LEN_OFFSET);
3619 #endif /* HAVE_LONGLONG */
3621 status = query_lock(fsp,
3628 if (ERROR_WAS_LOCK_DENIED(status)) {
3629 /* Here we need to report who has it locked... */
3630 data_size = POSIX_LOCK_DATA_SIZE;
3632 SSVAL(pdata, POSIX_LOCK_TYPE_OFFSET, lock_type);
3633 SSVAL(pdata, POSIX_LOCK_FLAGS_OFFSET, 0);
3634 SIVAL(pdata, POSIX_LOCK_PID_OFFSET, lock_pid);
3635 #if defined(HAVE_LONGLONG)
3636 SIVAL(pdata, POSIX_LOCK_START_OFFSET, (uint32)(offset & 0xFFFFFFFF));
3637 SIVAL(pdata, POSIX_LOCK_START_OFFSET + 4, (uint32)((offset >> 32) & 0xFFFFFFFF));
3638 SIVAL(pdata, POSIX_LOCK_LEN_OFFSET, (uint32)(count & 0xFFFFFFFF));
3639 SIVAL(pdata, POSIX_LOCK_LEN_OFFSET + 4, (uint32)((count >> 32) & 0xFFFFFFFF));
3640 #else /* HAVE_LONGLONG */
3641 SIVAL(pdata, POSIX_LOCK_START_OFFSET, offset);
3642 SIVAL(pdata, POSIX_LOCK_LEN_OFFSET, count);
3643 #endif /* HAVE_LONGLONG */
3645 } else if (NT_STATUS_IS_OK(status)) {
3646 /* For success we just return a copy of what we sent
3647 with the lock type set to POSIX_LOCK_TYPE_UNLOCK. */
3648 data_size = POSIX_LOCK_DATA_SIZE;
3649 memcpy(pdata, lock_data, POSIX_LOCK_DATA_SIZE);
3650 SSVAL(pdata, POSIX_LOCK_TYPE_OFFSET, POSIX_LOCK_TYPE_UNLOCK);
3652 return ERROR_NT(status);
3658 return ERROR_NT(NT_STATUS_INVALID_LEVEL);
3661 send_trans2_replies(outbuf, bufsize, params, param_size, *ppdata, data_size, max_data_bytes);
3666 /****************************************************************************
3667 Set a hard link (called by UNIX extensions and by NT rename with HARD link
3669 ****************************************************************************/
3671 NTSTATUS hardlink_internals(connection_struct *conn, char *oldname, char *newname)
3673 BOOL bad_path_oldname = False;
3674 BOOL bad_path_newname = False;
3675 SMB_STRUCT_STAT sbuf1, sbuf2;
3676 pstring last_component_oldname;
3677 pstring last_component_newname;
3678 NTSTATUS status = NT_STATUS_OK;
3684 if (ms_has_wild(newname) || ms_has_wild(oldname)) {
3685 return NT_STATUS_OBJECT_PATH_SYNTAX_BAD;
3688 unix_convert(oldname,conn,last_component_oldname,&bad_path_oldname,&sbuf1);
3689 if (bad_path_oldname) {
3690 return NT_STATUS_OBJECT_PATH_NOT_FOUND;
3693 /* Quick check for "." and ".." */
3694 if (last_component_oldname[0] == '.') {
3695 if (!last_component_oldname[1] || (last_component_oldname[1] == '.' && !last_component_oldname[2])) {
3696 return NT_STATUS_OBJECT_NAME_INVALID;
3700 /* source must already exist. */
3701 if (!VALID_STAT(sbuf1)) {
3702 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3705 if (!check_name(oldname,conn)) {
3706 return NT_STATUS_ACCESS_DENIED;
3709 unix_convert(newname,conn,last_component_newname,&bad_path_newname,&sbuf2);
3710 if (bad_path_newname) {
3711 return NT_STATUS_OBJECT_PATH_NOT_FOUND;
3714 /* Quick check for "." and ".." */
3715 if (last_component_newname[0] == '.') {
3716 if (!last_component_newname[1] || (last_component_newname[1] == '.' && !last_component_newname[2])) {
3717 return NT_STATUS_OBJECT_NAME_INVALID;
3721 /* Disallow if newname already exists. */
3722 if (VALID_STAT(sbuf2)) {
3723 return NT_STATUS_OBJECT_NAME_COLLISION;
3726 if (!check_name(newname,conn)) {
3727 return NT_STATUS_ACCESS_DENIED;
3730 /* No links from a directory. */
3731 if (S_ISDIR(sbuf1.st_mode)) {
3732 return NT_STATUS_FILE_IS_A_DIRECTORY;
3735 /* Ensure this is within the share. */
3736 if (!reduce_name(conn, oldname) != 0)
3737 return NT_STATUS_ACCESS_DENIED;
3739 DEBUG(10,("hardlink_internals: doing hard link %s -> %s\n", newname, oldname ));
3741 if (SMB_VFS_LINK(conn,oldname,newname) != 0) {
3742 status = map_nt_error_from_unix(errno);
3743 DEBUG(3,("hardlink_internals: Error %s hard link %s -> %s\n",
3744 nt_errstr(status), newname, oldname));
3750 /****************************************************************************
3751 Reply to a TRANS2_SETFILEINFO (set file info by fileid).
3752 ****************************************************************************/
3754 static int call_trans2setfilepathinfo(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize,
3755 unsigned int tran_call,
3756 char **pparams, int total_params, char **ppdata, int total_data,
3757 unsigned int max_data_bytes)
3759 char *params = *pparams;
3760 char *pdata = *ppdata;
3765 SMB_STRUCT_STAT sbuf;
3768 BOOL bad_path = False;
3769 files_struct *fsp = NULL;
3770 uid_t set_owner = (uid_t)SMB_UID_NO_CHANGE;
3771 gid_t set_grp = (uid_t)SMB_GID_NO_CHANGE;
3772 mode_t unixmode = 0;
3773 NTSTATUS status = NT_STATUS_OK;
3776 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
3781 if (tran_call == TRANSACT2_SETFILEINFO) {
3782 if (total_params < 4) {
3783 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
3786 fsp = file_fsp(params,0);
3787 info_level = SVAL(params,2);
3789 if(fsp && (fsp->is_directory || fsp->fh->fd == -1)) {
3791 * This is actually a SETFILEINFO on a directory
3792 * handle (returned from an NT SMB). NT5.0 seems
3793 * to do this call. JRA.
3795 pstrcpy(fname, fsp->fsp_name);
3796 if (SMB_VFS_STAT(conn,fname,&sbuf) != 0) {
3797 DEBUG(3,("call_trans2setfilepathinfo: fileinfo of %s failed (%s)\n",fname,strerror(errno)));
3798 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRbadpath);
3800 } else if (fsp && fsp->print_file) {
3802 * Doing a DELETE_ON_CLOSE should cancel a print job.
3804 if ((info_level == SMB_SET_FILE_DISPOSITION_INFO) && CVAL(pdata,0)) {
3805 fsp->fh->private_options |= FILE_DELETE_ON_CLOSE;
3807 DEBUG(3,("call_trans2setfilepathinfo: Cancelling print job (%s)\n", fsp->fsp_name ));
3810 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0, max_data_bytes);
3813 return (UNIXERROR(ERRDOS,ERRbadpath));
3816 * Original code - this is an open file.
3818 CHECK_FSP(fsp,conn);
3820 pstrcpy(fname, fsp->fsp_name);
3823 if (SMB_VFS_FSTAT(fsp,fd,&sbuf) != 0) {
3824 DEBUG(3,("call_trans2setfilepathinfo: fstat of fnum %d failed (%s)\n",fsp->fnum, strerror(errno)));
3825 return(UNIXERROR(ERRDOS,ERRbadfid));
3830 if (total_params < 6) {
3831 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
3834 info_level = SVAL(params,0);
3835 srvstr_get_path(inbuf, fname, ¶ms[6], sizeof(fname), -1, STR_TERMINATE, &status);
3836 if (!NT_STATUS_IS_OK(status)) {
3837 return ERROR_NT(status);
3839 unix_convert(fname,conn,0,&bad_path,&sbuf);
3841 return ERROR_NT(NT_STATUS_OBJECT_PATH_NOT_FOUND);
3845 * For CIFS UNIX extensions the target name may not exist.
3848 if(!VALID_STAT(sbuf) && !INFO_LEVEL_IS_UNIX(info_level)) {
3849 DEBUG(3,("call_trans2setfilepathinfo: stat of %s failed (%s)\n", fname, strerror(errno)));
3850 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRbadpath);
3853 if(!check_name(fname, conn)) {
3854 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRbadpath);
3859 if (!CAN_WRITE(conn))
3860 return ERROR_DOS(ERRSRV,ERRaccess);
3862 if (INFO_LEVEL_IS_UNIX(info_level) && !lp_unix_extensions()) {
3863 return ERROR_NT(NT_STATUS_INVALID_LEVEL);
3866 if (VALID_STAT(sbuf))
3867 unixmode = sbuf.st_mode;
3869 DEBUG(3,("call_trans2setfilepathinfo(%d) %s (fnum %d) info_level=%d totdata=%d\n",
3870 tran_call,fname, fsp ? fsp->fnum : -1, info_level,total_data));
3872 /* Realloc the parameter size */
3873 *pparams = (char *)SMB_REALLOC(*pparams,2);
3874 if (*pparams == NULL) {
3875 return ERROR_NT(NT_STATUS_NO_MEMORY);
3881 if (fsp && fsp->pending_modtime) {
3882 /* the pending modtime overrides the current modtime */
3883 sbuf.st_mtime = fsp->pending_modtime;
3886 size = get_file_size(sbuf);
3887 tvs.modtime = sbuf.st_mtime;
3888 tvs.actime = sbuf.st_atime;
3889 dosmode = dos_mode(conn,fname,&sbuf);
3890 unixmode = sbuf.st_mode;
3892 set_owner = VALID_STAT(sbuf) ? sbuf.st_uid : (uid_t)SMB_UID_NO_CHANGE;
3893 set_grp = VALID_STAT(sbuf) ? sbuf.st_gid : (gid_t)SMB_GID_NO_CHANGE;
3895 switch (info_level) {
3896 case SMB_INFO_STANDARD:
3898 if (total_data < 12) {
3899 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
3903 tvs.actime = srv_make_unix_date2(pdata+l1_fdateLastAccess);
3905 tvs.modtime = srv_make_unix_date2(pdata+l1_fdateLastWrite);
3909 case SMB_INFO_SET_EA:
3911 struct ea_list *ea_list = NULL;
3912 TALLOC_CTX *ctx = NULL;
3914 if (total_data < 10) {
3916 /* OS/2 workplace shell seems to send SET_EA requests of "null"
3917 length. They seem to have no effect. Bug #3212. JRA */
3919 if ((total_data == 4) && (IVAL(pdata,0) == 4)) {
3920 /* We're done. We only get EA info in this call. */
3922 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0, max_data_bytes);
3926 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
3929 if (IVAL(pdata,0) > total_data) {
3930 DEBUG(10,("call_trans2setfilepathinfo: bad total data size (%u) > %u\n",
3931 IVAL(pdata,0), (unsigned int)total_data));
3932 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
3935 ctx = talloc_init("SMB_INFO_SET_EA");
3937 return ERROR_NT(NT_STATUS_NO_MEMORY);
3939 ea_list = read_ea_list(ctx, pdata + 4, total_data - 4);
3941 talloc_destroy(ctx);
3942 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
3944 status = set_ea(conn, fsp, fname, ea_list);
3945 talloc_destroy(ctx);
3947 if (!NT_STATUS_IS_OK(status)) {
3948 return ERROR_NT(status);
3951 /* We're done. We only get EA info in this call. */
3953 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0, max_data_bytes);
3958 /* The following 2 info levels are only valid on query, not set. Remove them. JRA. */
3959 /* XXXX um, i don't think this is right.
3960 it's also not in the cifs6.txt spec.
3962 case SMB_INFO_QUERY_EAS_FROM_LIST:
3963 if (total_data < 28)
3964 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
3966 tvs.actime = make_unix_date2(pdata+8);
3967 tvs.modtime = make_unix_date2(pdata+12);
3968 size = IVAL(pdata,16);
3969 dosmode = IVAL(pdata,24);
3972 /* XXXX nor this. not in cifs6.txt, either. */
3973 case SMB_INFO_QUERY_ALL_EAS:
3974 if (total_data < 28)
3975 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
3977 tvs.actime = make_unix_date2(pdata+8);
3978 tvs.modtime = make_unix_date2(pdata+12);
3979 size = IVAL(pdata,16);
3980 dosmode = IVAL(pdata,24);
3984 case SMB_SET_FILE_BASIC_INFO:
3985 case SMB_FILE_BASIC_INFORMATION:
3987 /* Patch to do this correctly from Paul Eggert <eggert@twinsun.com>. */
3989 time_t changed_time;
3991 if (total_data < 36) {
3992 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
3995 /* Ignore create time at offset pdata. */
3998 tvs.actime = convert_timespec_to_time_t(interpret_long_date(pdata+8));
4000 write_time = convert_timespec_to_time_t(interpret_long_date(pdata+16));
4001 changed_time = convert_timespec_to_time_t(interpret_long_date(pdata+24));
4003 tvs.modtime = MIN(write_time, changed_time);
4005 if (write_time > tvs.modtime && write_time != (time_t)-1) {
4006 tvs.modtime = write_time;
4008 /* Prefer a defined time to an undefined one. */
4009 if (null_mtime(tvs.modtime)) {
4010 tvs.modtime = null_mtime(write_time) ? changed_time : write_time;
4014 dosmode = IVAL(pdata,32);
4018 case SMB_FILE_ALLOCATION_INFORMATION:
4019 case SMB_SET_FILE_ALLOCATION_INFO:
4022 SMB_BIG_UINT allocation_size;
4024 if (total_data < 8) {
4025 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
4028 allocation_size = (SMB_BIG_UINT)IVAL(pdata,0);
4029 #ifdef LARGE_SMB_OFF_T
4030 allocation_size |= (((SMB_BIG_UINT)IVAL(pdata,4)) << 32);
4031 #else /* LARGE_SMB_OFF_T */
4032 if (IVAL(pdata,4) != 0) {
4033 /* more than 32 bits? */
4034 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
4036 #endif /* LARGE_SMB_OFF_T */
4037 DEBUG(10,("call_trans2setfilepathinfo: Set file allocation info for file %s to %.0f\n",
4038 fname, (double)allocation_size ));
4040 if (allocation_size) {
4041 allocation_size = smb_roundup(conn, allocation_size);
4044 if(allocation_size != get_file_size(sbuf)) {
4045 SMB_STRUCT_STAT new_sbuf;
4047 DEBUG(10,("call_trans2setfilepathinfo: file %s : setting new allocation size to %.0f\n",
4048 fname, (double)allocation_size ));
4051 files_struct *new_fsp = NULL;
4053 status = open_file_ntcreate(conn, fname, &sbuf,
4055 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4058 FILE_ATTRIBUTE_NORMAL,
4059 FORCE_OPLOCK_BREAK_TO_NONE,
4062 if (!NT_STATUS_IS_OK(status)) {
4063 if (open_was_deferred(SVAL(inbuf,smb_mid))) {
4064 /* We have re-scheduled this call. */
4067 return(UNIXERROR(ERRDOS,ERRnoaccess));
4069 ret = vfs_allocate_file_space(new_fsp, allocation_size);
4070 if (SMB_VFS_FSTAT(new_fsp,new_fsp->fh->fd,&new_sbuf) != 0) {
4071 DEBUG(3,("call_trans2setfilepathinfo: fstat of fnum %d failed (%s)\n",
4072 new_fsp->fnum, strerror(errno)));
4075 close_file(new_fsp,NORMAL_CLOSE);
4077 ret = vfs_allocate_file_space(fsp, allocation_size);
4078 if (SMB_VFS_FSTAT(fsp,fd,&new_sbuf) != 0) {
4079 DEBUG(3,("call_trans2setfilepathinfo: fstat of fnum %d failed (%s)\n",
4080 fsp->fnum, strerror(errno)));
4085 return ERROR_NT(NT_STATUS_DISK_FULL);
4087 /* Allocate can truncate size... */
4088 size = get_file_size(new_sbuf);
4094 case SMB_FILE_END_OF_FILE_INFORMATION:
4095 case SMB_SET_FILE_END_OF_FILE_INFO:
4097 if (total_data < 8) {
4098 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
4101 size = IVAL(pdata,0);
4102 #ifdef LARGE_SMB_OFF_T
4103 size |= (((SMB_OFF_T)IVAL(pdata,4)) << 32);
4104 #else /* LARGE_SMB_OFF_T */
4105 if (IVAL(pdata,4) != 0) {
4106 /* more than 32 bits? */
4107 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
4109 #endif /* LARGE_SMB_OFF_T */
4110 DEBUG(10,("call_trans2setfilepathinfo: Set end of file info for file %s to %.0f\n", fname, (double)size ));
4114 case SMB_FILE_DISPOSITION_INFORMATION:
4115 case SMB_SET_FILE_DISPOSITION_INFO: /* Set delete on close for open file. */
4117 BOOL delete_on_close;
4119 if (total_data < 1) {
4120 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
4123 delete_on_close = (CVAL(pdata,0) ? True : False);
4125 /* Just ignore this set on a path. */
4126 if (tran_call != TRANSACT2_SETFILEINFO)
4130 return(UNIXERROR(ERRDOS,ERRbadfid));
4132 status = can_set_delete_on_close(fsp, delete_on_close,
4135 if (!NT_STATUS_IS_OK(status)) {
4136 return ERROR_NT(status);
4139 /* The set is across all open files on this dev/inode pair. */
4140 if (!set_delete_on_close(fsp, delete_on_close, ¤t_user.ut)) {
4141 return ERROR_NT(NT_STATUS_ACCESS_DENIED);
4145 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0, max_data_bytes);
4149 case SMB_FILE_POSITION_INFORMATION:
4151 SMB_BIG_UINT position_information;
4153 if (total_data < 8) {
4154 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
4157 position_information = (SMB_BIG_UINT)IVAL(pdata,0);
4158 #ifdef LARGE_SMB_OFF_T
4159 position_information |= (((SMB_BIG_UINT)IVAL(pdata,4)) << 32);
4160 #else /* LARGE_SMB_OFF_T */
4161 if (IVAL(pdata,4) != 0) {
4162 /* more than 32 bits? */
4163 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
4165 #endif /* LARGE_SMB_OFF_T */
4166 DEBUG(10,("call_trans2setfilepathinfo: Set file position information for file %s to %.0f\n",
4167 fname, (double)position_information ));
4169 fsp->fh->position_information = position_information;
4172 /* We're done. We only get position info in this call. */
4174 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0, max_data_bytes);
4178 /* From tridge Samba4 :
4179 * MODE_INFORMATION in setfileinfo (I have no
4180 * idea what "mode information" on a file is - it takes a value of 0,
4181 * 2, 4 or 6. What could it be?).
4184 case SMB_FILE_MODE_INFORMATION:
4188 if (total_data < 4) {
4189 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
4191 mode = IVAL(pdata,0);
4192 if (mode != 0 && mode != 2 && mode != 4 && mode != 6) {
4193 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
4196 /* We're done. We only get mode info in this call. */
4198 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0, max_data_bytes);
4203 * CIFS UNIX extensions.
4206 case SMB_SET_FILE_UNIX_BASIC:
4208 uint32 raw_unixmode;
4210 if (total_data < 100) {
4211 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
4214 if(IVAL(pdata, 0) != SMB_SIZE_NO_CHANGE_LO &&
4215 IVAL(pdata, 4) != SMB_SIZE_NO_CHANGE_HI) {
4216 size=IVAL(pdata,0); /* first 8 Bytes are size */
4217 #ifdef LARGE_SMB_OFF_T
4218 size |= (((SMB_OFF_T)IVAL(pdata,4)) << 32);
4219 #else /* LARGE_SMB_OFF_T */
4220 if (IVAL(pdata,4) != 0) {
4221 /* more than 32 bits? */
4222 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
4224 #endif /* LARGE_SMB_OFF_T */
4226 pdata+=24; /* ctime & st_blocks are not changed */
4227 tvs.actime = convert_timespec_to_time_t(interpret_long_date(pdata)); /* access_time */
4228 tvs.modtime = convert_timespec_to_time_t(interpret_long_date(pdata+8)); /* modification_time */
4230 set_owner = (uid_t)IVAL(pdata,0);
4232 set_grp = (gid_t)IVAL(pdata,0);
4234 raw_unixmode = IVAL(pdata,28);
4235 unixmode = unix_perms_from_wire(conn, &sbuf, raw_unixmode);
4236 dosmode = 0; /* Ensure dos mode change doesn't override this. */
4238 DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_BASIC: name = %s \
4239 size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n",
4240 fname, (double)size, (unsigned int)set_owner, (unsigned int)set_grp, (int)raw_unixmode));
4242 if (!VALID_STAT(sbuf)) {
4245 * The only valid use of this is to create character and block
4246 * devices, and named pipes. This is deprecated (IMHO) and
4247 * a new info level should be used for mknod. JRA.
4250 uint32 file_type = IVAL(pdata,0);
4251 #if defined(HAVE_MAKEDEV)
4252 uint32 dev_major = IVAL(pdata,4);
4253 uint32 dev_minor = IVAL(pdata,12);
4256 uid_t myuid = geteuid();
4257 gid_t mygid = getegid();
4258 SMB_DEV_T dev = (SMB_DEV_T)0;
4260 if (tran_call == TRANSACT2_SETFILEINFO)
4261 return(ERROR_DOS(ERRDOS,ERRnoaccess));
4263 if (raw_unixmode == SMB_MODE_NO_CHANGE) {
4264 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
4267 #if defined(HAVE_MAKEDEV)
4268 dev = makedev(dev_major, dev_minor);
4271 /* We can only create as the owner/group we are. */
4273 if ((set_owner != myuid) && (set_owner != (uid_t)SMB_UID_NO_CHANGE))
4274 return(ERROR_DOS(ERRDOS,ERRnoaccess));
4275 if ((set_grp != mygid) && (set_grp != (gid_t)SMB_GID_NO_CHANGE))
4276 return(ERROR_DOS(ERRDOS,ERRnoaccess));
4278 switch (file_type) {
4279 #if defined(S_IFIFO)
4280 case UNIX_TYPE_FIFO:
4281 unixmode |= S_IFIFO;
4284 #if defined(S_IFSOCK)
4285 case UNIX_TYPE_SOCKET:
4286 unixmode |= S_IFSOCK;
4289 #if defined(S_IFCHR)
4290 case UNIX_TYPE_CHARDEV:
4291 unixmode |= S_IFCHR;
4294 #if defined(S_IFBLK)
4295 case UNIX_TYPE_BLKDEV:
4296 unixmode |= S_IFBLK;
4300 return(ERROR_DOS(ERRDOS,ERRnoaccess));
4303 DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_BASIC doing mknod dev %.0f mode \
4304 0%o for file %s\n", (double)dev, unixmode, fname ));
4306 /* Ok - do the mknod. */
4307 if (SMB_VFS_MKNOD(conn,fname, unixmode, dev) != 0)
4308 return(UNIXERROR(ERRDOS,ERRnoaccess));
4310 if (lp_inherit_perms(SNUM(conn))) {
4311 inherit_access_acl(conn, fname,
4316 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0, max_data_bytes);
4321 * Deal with the UNIX specific mode set.
4324 if (raw_unixmode != SMB_MODE_NO_CHANGE) {
4325 DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_BASIC setting mode 0%o for file %s\n",
4326 (unsigned int)unixmode, fname ));
4327 if (SMB_VFS_CHMOD(conn,fname,unixmode) != 0)
4328 return(UNIXERROR(ERRDOS,ERRnoaccess));
4332 * Deal with the UNIX specific uid set.
4335 if ((set_owner != (uid_t)SMB_UID_NO_CHANGE) && (sbuf.st_uid != set_owner)) {
4336 DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_BASIC changing owner %u for file %s\n",
4337 (unsigned int)set_owner, fname ));
4338 if (SMB_VFS_CHOWN(conn,fname,set_owner, (gid_t)-1) != 0)
4339 return(UNIXERROR(ERRDOS,ERRnoaccess));
4343 * Deal with the UNIX specific gid set.
4346 if ((set_grp != (uid_t)SMB_GID_NO_CHANGE) && (sbuf.st_gid != set_grp)) {
4347 DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_BASIC changing group %u for file %s\n",
4348 (unsigned int)set_owner, fname ));
4349 if (SMB_VFS_CHOWN(conn,fname,(uid_t)-1, set_grp) != 0)
4350 return(UNIXERROR(ERRDOS,ERRnoaccess));
4355 case SMB_SET_FILE_UNIX_LINK:
4357 pstring link_target;
4358 char *newname = fname;
4360 /* Set a symbolic link. */
4361 /* Don't allow this if follow links is false. */
4363 if (!lp_symlinks(SNUM(conn)))
4364 return(ERROR_DOS(ERRDOS,ERRnoaccess));
4366 srvstr_pull(inbuf, link_target, pdata, sizeof(link_target), -1, STR_TERMINATE);
4368 /* !widelinks forces the target path to be within the share. */
4369 /* This means we can interpret the target as a pathname. */
4370 if (!lp_widelinks(SNUM(conn))) {
4372 char *last_dirp = NULL;
4374 unix_format(link_target);
4375 if (*link_target == '/') {
4376 /* No absolute paths allowed. */
4377 return(UNIXERROR(ERRDOS,ERRnoaccess));
4379 pstrcpy(rel_name, newname);
4380 last_dirp = strrchr_m(rel_name, '/');
4382 last_dirp[1] = '\0';
4384 pstrcpy(rel_name, "./");
4386 pstrcat(rel_name, link_target);
4388 if (!check_name(rel_name, conn)) {
4389 return(UNIXERROR(ERRDOS,ERRnoaccess));
4393 DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_LINK doing symlink %s -> %s\n",
4394 fname, link_target ));
4396 if (SMB_VFS_SYMLINK(conn,link_target,newname) != 0)
4397 return(UNIXERROR(ERRDOS,ERRnoaccess));
4399 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0, max_data_bytes);
4403 case SMB_SET_FILE_UNIX_HLINK:
4406 char *newname = fname;
4408 /* Set a hard link. */
4409 srvstr_get_path(inbuf, oldname, pdata, sizeof(oldname), -1, STR_TERMINATE, &status);
4410 if (!NT_STATUS_IS_OK(status)) {
4411 return ERROR_NT(status);
4414 DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_LINK doing hard link %s -> %s\n",
4417 status = hardlink_internals(conn, oldname, newname);
4418 if (!NT_STATUS_IS_OK(status)) {
4419 return ERROR_NT(status);
4423 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0, max_data_bytes);
4427 case SMB_FILE_RENAME_INFORMATION:
4430 /* uint32 root_fid; */ /* Not used */
4436 if (total_data < 12) {
4437 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
4440 overwrite = (CVAL(pdata,0) ? True : False);
4441 /* root_fid = IVAL(pdata,4); */
4442 len = IVAL(pdata,8);
4443 srvstr_get_path(inbuf, newname, &pdata[12], sizeof(newname), len, 0, &status);
4444 if (!NT_STATUS_IS_OK(status)) {
4445 return ERROR_NT(status);
4448 /* Check the new name has no '/' characters. */
4449 if (strchr_m(newname, '/'))
4450 return ERROR_NT(NT_STATUS_NOT_SUPPORTED);
4452 RESOLVE_DFSPATH(newname, conn, inbuf, outbuf);
4454 /* Create the base directory. */
4455 pstrcpy(base_name, fname);
4456 p = strrchr_m(base_name, '/');
4459 /* Append the new name. */
4460 pstrcat(base_name, "/");
4461 pstrcat(base_name, newname);
4464 DEBUG(10,("call_trans2setfilepathinfo: SMB_FILE_RENAME_INFORMATION (fnum %d) %s -> %s\n",
4465 fsp->fnum, fsp->fsp_name, base_name ));
4466 status = rename_internals_fsp(conn, fsp, base_name, 0, overwrite);
4468 DEBUG(10,("call_trans2setfilepathinfo: SMB_FILE_RENAME_INFORMATION %s -> %s\n",
4470 status = rename_internals(conn, fname, base_name, 0, overwrite, False);
4472 if (!NT_STATUS_IS_OK(status)) {
4473 return ERROR_NT(status);
4475 process_pending_change_notify_queue((time_t)0);
4477 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0, max_data_bytes);
4481 #if defined(HAVE_POSIX_ACLS)
4482 case SMB_SET_POSIX_ACL:
4484 uint16 posix_acl_version;
4485 uint16 num_file_acls;
4486 uint16 num_def_acls;
4487 BOOL valid_file_acls = True;
4488 BOOL valid_def_acls = True;
4490 if (total_data < SMB_POSIX_ACL_HEADER_SIZE) {
4491 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
4493 posix_acl_version = SVAL(pdata,0);
4494 num_file_acls = SVAL(pdata,2);
4495 num_def_acls = SVAL(pdata,4);
4497 if (num_file_acls == SMB_POSIX_IGNORE_ACE_ENTRIES) {
4498 valid_file_acls = False;
4502 if (num_def_acls == SMB_POSIX_IGNORE_ACE_ENTRIES) {
4503 valid_def_acls = False;
4507 if (posix_acl_version != SMB_POSIX_ACL_VERSION) {
4508 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
4511 if (total_data < SMB_POSIX_ACL_HEADER_SIZE +
4512 (num_file_acls+num_def_acls)*SMB_POSIX_ACL_ENTRY_SIZE) {
4513 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
4516 if (valid_file_acls && !set_unix_posix_acl(conn, fsp, fname, num_file_acls,
4517 pdata + SMB_POSIX_ACL_HEADER_SIZE)) {
4518 return(UNIXERROR(ERRDOS,ERRnoaccess));
4521 if (valid_def_acls && !set_unix_posix_default_acl(conn, fname, &sbuf, num_def_acls,
4522 pdata + SMB_POSIX_ACL_HEADER_SIZE +
4523 (num_file_acls*SMB_POSIX_ACL_ENTRY_SIZE))) {
4524 return(UNIXERROR(ERRDOS,ERRnoaccess));
4528 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0, max_data_bytes);
4533 case SMB_SET_POSIX_LOCK:
4536 SMB_BIG_UINT offset;
4538 BOOL blocking_lock = False;
4539 enum brl_type lock_type;
4541 if (fsp == NULL || fsp->fh->fd == -1) {
4542 return ERROR_NT(NT_STATUS_INVALID_HANDLE);
4545 if (total_data != POSIX_LOCK_DATA_SIZE) {
4546 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
4549 switch (SVAL(pdata, POSIX_LOCK_TYPE_OFFSET)) {
4550 case POSIX_LOCK_TYPE_READ:
4551 lock_type = READ_LOCK;
4553 case POSIX_LOCK_TYPE_WRITE:
4554 /* Return the right POSIX-mappable error code for files opened read-only. */
4555 if (!fsp->can_write) {
4556 return ERROR_NT(NT_STATUS_INVALID_HANDLE);
4558 lock_type = WRITE_LOCK;
4560 case POSIX_LOCK_TYPE_UNLOCK:
4561 lock_type = UNLOCK_LOCK;
4564 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
4567 if (SVAL(pdata,POSIX_LOCK_FLAGS_OFFSET) == POSIX_LOCK_FLAG_NOWAIT) {
4568 blocking_lock = False;
4569 } else if (SVAL(pdata,POSIX_LOCK_FLAGS_OFFSET) == POSIX_LOCK_FLAG_WAIT) {
4570 blocking_lock = True;
4572 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
4575 if (!lp_blocking_locks(SNUM(conn))) {
4576 blocking_lock = False;
4579 lock_pid = IVAL(pdata, POSIX_LOCK_PID_OFFSET);
4580 #if defined(HAVE_LONGLONG)
4581 offset = (((SMB_BIG_UINT) IVAL(pdata,(POSIX_LOCK_START_OFFSET+4))) << 32) |
4582 ((SMB_BIG_UINT) IVAL(pdata,POSIX_LOCK_START_OFFSET));
4583 count = (((SMB_BIG_UINT) IVAL(pdata,(POSIX_LOCK_LEN_OFFSET+4))) << 32) |
4584 ((SMB_BIG_UINT) IVAL(pdata,POSIX_LOCK_LEN_OFFSET));
4585 #else /* HAVE_LONGLONG */
4586 offset = (SMB_BIG_UINT)IVAL(pdata,POSIX_LOCK_START_OFFSET);
4587 count = (SMB_BIG_UINT)IVAL(pdata,POSIX_LOCK_LEN_OFFSET);
4588 #endif /* HAVE_LONGLONG */
4590 if (lock_type == UNLOCK_LOCK) {
4591 status = do_unlock(fsp,
4597 struct byte_range_lock *br_lck = do_lock(fsp,
4606 if (br_lck && blocking_lock && ERROR_WAS_LOCK_DENIED(status)) {
4608 * A blocking lock was requested. Package up
4609 * this smb into a queued request and push it
4610 * onto the blocking lock queue.
4612 if(push_blocking_lock_request(br_lck,
4615 -1, /* infinite timeout. */
4622 TALLOC_FREE(br_lck);
4626 TALLOC_FREE(br_lck);
4629 if (!NT_STATUS_IS_OK(status)) {
4630 return ERROR_NT(status);
4634 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0, max_data_bytes);
4639 return ERROR_NT(NT_STATUS_INVALID_LEVEL);
4642 /* get some defaults (no modifications) if any info is zero or -1. */
4643 if (null_mtime(tvs.actime)) {
4644 tvs.actime = sbuf.st_atime;
4647 if (null_mtime(tvs.modtime)) {
4648 tvs.modtime = sbuf.st_mtime;
4651 DEBUG(6,("actime: %s " , ctime(&tvs.actime)));
4652 DEBUG(6,("modtime: %s ", ctime(&tvs.modtime)));
4653 DEBUG(6,("size: %.0f ", (double)size));
4656 if (S_ISDIR(sbuf.st_mode))
4662 DEBUG(6,("dosmode: %x\n" , dosmode));
4664 if(!((info_level == SMB_SET_FILE_END_OF_FILE_INFO) ||
4665 (info_level == SMB_SET_FILE_ALLOCATION_INFO) ||
4666 (info_level == SMB_FILE_ALLOCATION_INFORMATION) ||
4667 (info_level == SMB_FILE_END_OF_FILE_INFORMATION))) {
4670 * Only do this test if we are not explicitly
4671 * changing the size of a file.
4674 size = get_file_size(sbuf);
4678 * Try and set the times, size and mode of this file -
4679 * if they are different from the current values
4682 /* check the mode isn't different, before changing it */
4683 if ((dosmode != 0) && (dosmode != dos_mode(conn, fname, &sbuf))) {
4685 DEBUG(10,("call_trans2setfilepathinfo: file %s : setting dos mode %x\n", fname, dosmode ));
4687 if(file_set_dosmode(conn, fname, dosmode, &sbuf, False)) {
4688 DEBUG(2,("file_set_dosmode of %s failed (%s)\n", fname, strerror(errno)));
4689 return(UNIXERROR(ERRDOS,ERRnoaccess));
4694 if (size != get_file_size(sbuf)) {
4698 DEBUG(10,("call_trans2setfilepathinfo: file %s : setting new size to %.0f\n",
4699 fname, (double)size ));
4702 files_struct *new_fsp = NULL;
4704 status = open_file_ntcreate(conn, fname, &sbuf,
4706 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4709 FILE_ATTRIBUTE_NORMAL,
4710 FORCE_OPLOCK_BREAK_TO_NONE,
4713 if (!NT_STATUS_IS_OK(status)) {
4714 if (open_was_deferred(SVAL(inbuf,smb_mid))) {
4715 /* We have re-scheduled this call. */
4718 return(UNIXERROR(ERRDOS,ERRnoaccess));
4720 ret = vfs_set_filelen(new_fsp, size);
4721 close_file(new_fsp,NORMAL_CLOSE);
4723 ret = vfs_set_filelen(fsp, size);
4727 return (UNIXERROR(ERRHRD,ERRdiskfull));
4732 * Finally the times.
4734 if (sbuf.st_mtime != tvs.modtime || sbuf.st_atime != tvs.actime) {
4737 * This was a setfileinfo on an open file.
4738 * NT does this a lot. We also need to
4739 * set the time here, as it can be read by
4740 * FindFirst/FindNext and with the patch for bug #2045
4741 * in smbd/fileio.c it ensures that this timestamp is
4742 * kept sticky even after a write. We save the request
4743 * away and will set it on file close and after a write. JRA.
4746 if (tvs.modtime != (time_t)0 && tvs.modtime != (time_t)-1) {
4747 DEBUG(10,("call_trans2setfilepathinfo: setting pending modtime to %s\n", ctime(&tvs.modtime) ));
4748 fsp_set_pending_modtime(fsp, tvs.modtime);
4752 DEBUG(10,("call_trans2setfilepathinfo: setting utimes to modified values.\n"));
4754 if(file_utime(conn, fname, &tvs)!=0) {
4755 return(UNIXERROR(ERRDOS,ERRnoaccess));
4760 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0, max_data_bytes);
4765 /****************************************************************************
4766 Reply to a TRANS2_MKDIR (make directory with extended attributes).
4767 ****************************************************************************/
4769 static int call_trans2mkdir(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize,
4770 char **pparams, int total_params, char **ppdata, int total_data,
4771 unsigned int max_data_bytes)
4773 char *params = *pparams;
4774 char *pdata = *ppdata;
4777 SMB_STRUCT_STAT sbuf;
4778 BOOL bad_path = False;
4779 NTSTATUS status = NT_STATUS_OK;
4780 TALLOC_CTX *ctx = NULL;
4781 struct ea_list *ea_list = NULL;
4783 if (!CAN_WRITE(conn))
4784 return ERROR_DOS(ERRSRV,ERRaccess);
4786 if (total_params < 4) {
4787 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
4790 srvstr_get_path(inbuf, directory, ¶ms[4], sizeof(directory), -1, STR_TERMINATE, &status);
4791 if (!NT_STATUS_IS_OK(status)) {
4792 return ERROR_NT(status);
4795 DEBUG(3,("call_trans2mkdir : name = %s\n", directory));
4797 unix_convert(directory,conn,0,&bad_path,&sbuf);
4799 return ERROR_NT(NT_STATUS_OBJECT_PATH_NOT_FOUND);
4802 /* Any data in this call is an EA list. */
4803 if (total_data && (total_data != 4) && !lp_ea_support(SNUM(conn))) {
4804 return ERROR_NT(NT_STATUS_EAS_NOT_SUPPORTED);
4808 * OS/2 workplace shell seems to send SET_EA requests of "null"
4809 * length (4 bytes containing IVAL 4).
4810 * They seem to have no effect. Bug #3212. JRA.
4813 if (total_data != 4) {
4814 if (total_data < 10) {
4815 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
4818 if (IVAL(pdata,0) > total_data) {
4819 DEBUG(10,("call_trans2mkdir: bad total data size (%u) > %u\n",
4820 IVAL(pdata,0), (unsigned int)total_data));
4821 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
4824 ctx = talloc_init("TRANS2_MKDIR_SET_EA");
4826 return ERROR_NT(NT_STATUS_NO_MEMORY);
4828 ea_list = read_ea_list(ctx, pdata + 4, total_data - 4);
4830 talloc_destroy(ctx);
4831 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
4833 } else if (IVAL(pdata,0) != 4) {
4834 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
4837 if (check_name(directory,conn)) {
4838 ret = vfs_MkDir(conn,directory,unix_mode(conn,aDIR,directory,True));
4842 talloc_destroy(ctx);
4843 DEBUG(5,("call_trans2mkdir error (%s)\n", strerror(errno)));
4844 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRnoaccess);
4847 /* Try and set any given EA. */
4849 status = set_ea(conn, NULL, directory, ea_list);
4850 talloc_destroy(ctx);
4851 if (!NT_STATUS_IS_OK(status)) {
4852 return ERROR_NT(status);
4856 /* Realloc the parameter and data sizes */
4857 *pparams = (char *)SMB_REALLOC(*pparams,2);
4858 if(*pparams == NULL) {
4859 return ERROR_NT(NT_STATUS_NO_MEMORY);
4865 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0, max_data_bytes);
4870 /****************************************************************************
4871 Reply to a TRANS2_FINDNOTIFYFIRST (start monitoring a directory for changes).
4872 We don't actually do this - we just send a null response.
4873 ****************************************************************************/
4875 static int call_trans2findnotifyfirst(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize,
4876 char **pparams, int total_params, char **ppdata, int total_data,
4877 unsigned int max_data_bytes)
4879 static uint16 fnf_handle = 257;
4880 char *params = *pparams;
4883 if (total_params < 6) {
4884 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
4887 info_level = SVAL(params,4);
4888 DEBUG(3,("call_trans2findnotifyfirst - info_level %d\n", info_level));
4890 switch (info_level) {
4895 return ERROR_NT(NT_STATUS_INVALID_LEVEL);
4898 /* Realloc the parameter and data sizes */
4899 *pparams = (char *)SMB_REALLOC(*pparams,6);
4900 if (*pparams == NULL) {
4901 return ERROR_NT(NT_STATUS_NO_MEMORY);
4905 SSVAL(params,0,fnf_handle);
4906 SSVAL(params,2,0); /* No changes */
4907 SSVAL(params,4,0); /* No EA errors */
4914 send_trans2_replies(outbuf, bufsize, params, 6, *ppdata, 0, max_data_bytes);
4919 /****************************************************************************
4920 Reply to a TRANS2_FINDNOTIFYNEXT (continue monitoring a directory for
4921 changes). Currently this does nothing.
4922 ****************************************************************************/
4924 static int call_trans2findnotifynext(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize,
4925 char **pparams, int total_params, char **ppdata, int total_data,
4926 unsigned int max_data_bytes)
4928 char *params = *pparams;
4930 DEBUG(3,("call_trans2findnotifynext\n"));
4932 /* Realloc the parameter and data sizes */
4933 *pparams = (char *)SMB_REALLOC(*pparams,4);
4934 if (*pparams == NULL) {
4935 return ERROR_NT(NT_STATUS_NO_MEMORY);
4939 SSVAL(params,0,0); /* No changes */
4940 SSVAL(params,2,0); /* No EA errors */
4942 send_trans2_replies(outbuf, bufsize, params, 4, *ppdata, 0, max_data_bytes);
4947 /****************************************************************************
4948 Reply to a TRANS2_GET_DFS_REFERRAL - Shirish Kalele <kalele@veritas.com>.
4949 ****************************************************************************/
4951 static int call_trans2getdfsreferral(connection_struct *conn, char* inbuf, char* outbuf, int length, int bufsize,
4952 char **pparams, int total_params, char **ppdata, int total_data,
4953 unsigned int max_data_bytes)
4955 char *params = *pparams;
4958 int max_referral_level;
4960 DEBUG(10,("call_trans2getdfsreferral\n"));
4962 if (total_params < 2) {
4963 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
4966 max_referral_level = SVAL(params,0);
4968 if(!lp_host_msdfs())
4969 return ERROR_DOS(ERRDOS,ERRbadfunc);
4971 srvstr_pull(inbuf, pathname, ¶ms[2], sizeof(pathname), -1, STR_TERMINATE);
4972 if((reply_size = setup_dfs_referral(conn, pathname,max_referral_level,ppdata)) < 0)
4973 return UNIXERROR(ERRDOS,ERRbadfile);
4975 SSVAL(outbuf,smb_flg2,SVAL(outbuf,smb_flg2) | FLAGS2_DFS_PATHNAMES);
4976 send_trans2_replies(outbuf,bufsize,0,0,*ppdata,reply_size, max_data_bytes);
4981 #define LMCAT_SPL 0x53
4982 #define LMFUNC_GETJOBID 0x60
4984 /****************************************************************************
4985 Reply to a TRANS2_IOCTL - used for OS/2 printing.
4986 ****************************************************************************/
4988 static int call_trans2ioctl(connection_struct *conn, char* inbuf, char* outbuf, int length, int bufsize,
4989 char **pparams, int total_params, char **ppdata, int total_data,
4990 unsigned int max_data_bytes)
4992 char *pdata = *ppdata;
4993 files_struct *fsp = file_fsp(inbuf,smb_vwv15);
4995 /* check for an invalid fid before proceeding */
4998 return(ERROR_DOS(ERRDOS,ERRbadfid));
5000 if ((SVAL(inbuf,(smb_setup+4)) == LMCAT_SPL) &&
5001 (SVAL(inbuf,(smb_setup+6)) == LMFUNC_GETJOBID)) {
5002 *ppdata = (char *)SMB_REALLOC(*ppdata, 32);
5003 if (*ppdata == NULL) {
5004 return ERROR_NT(NT_STATUS_NO_MEMORY);
5008 /* NOTE - THIS IS ASCII ONLY AT THE MOMENT - NOT SURE IF OS/2
5009 CAN ACCEPT THIS IN UNICODE. JRA. */
5011 SSVAL(pdata,0,fsp->rap_print_jobid); /* Job number */
5012 srvstr_push( outbuf, pdata + 2, global_myname(), 15, STR_ASCII|STR_TERMINATE); /* Our NetBIOS name */
5013 srvstr_push( outbuf, pdata+18, lp_servicename(SNUM(conn)), 13, STR_ASCII|STR_TERMINATE); /* Service name */
5014 send_trans2_replies(outbuf,bufsize,*pparams,0,*ppdata,32, max_data_bytes);
5017 DEBUG(2,("Unknown TRANS2_IOCTL\n"));
5018 return ERROR_DOS(ERRSRV,ERRerror);
5022 /****************************************************************************
5023 Reply to a SMBfindclose (stop trans2 directory search).
5024 ****************************************************************************/
5026 int reply_findclose(connection_struct *conn,
5027 char *inbuf,char *outbuf,int length,int bufsize)
5030 int dptr_num=SVALS(inbuf,smb_vwv0);
5031 START_PROFILE(SMBfindclose);
5033 DEBUG(3,("reply_findclose, dptr_num = %d\n", dptr_num));
5035 dptr_close(&dptr_num);
5037 outsize = set_message(outbuf,0,0,False);
5039 DEBUG(3,("SMBfindclose dptr_num = %d\n", dptr_num));
5041 END_PROFILE(SMBfindclose);
5045 /****************************************************************************
5046 Reply to a SMBfindnclose (stop FINDNOTIFYFIRST directory search).
5047 ****************************************************************************/
5049 int reply_findnclose(connection_struct *conn,
5050 char *inbuf,char *outbuf,int length,int bufsize)
5054 START_PROFILE(SMBfindnclose);
5056 dptr_num = SVAL(inbuf,smb_vwv0);
5058 DEBUG(3,("reply_findnclose, dptr_num = %d\n", dptr_num));
5060 /* We never give out valid handles for a
5061 findnotifyfirst - so any dptr_num is ok here.
5064 outsize = set_message(outbuf,0,0,False);
5066 DEBUG(3,("SMB_findnclose dptr_num = %d\n", dptr_num));
5068 END_PROFILE(SMBfindnclose);
5072 int handle_trans2(connection_struct *conn,
5073 struct trans_state *state,
5074 char *inbuf, char *outbuf, int size, int bufsize)
5078 if (Protocol >= PROTOCOL_NT1) {
5079 SSVAL(outbuf,smb_flg2,SVAL(outbuf,smb_flg2) | 0x40); /* IS_LONG_NAME */
5082 /* Now we must call the relevant TRANS2 function */
5083 switch(state->call) {
5084 case TRANSACT2_OPEN:
5086 START_PROFILE_NESTED(Trans2_open);
5087 outsize = call_trans2open(
5088 conn, inbuf, outbuf, bufsize,
5089 &state->param, state->total_param,
5090 &state->data, state->total_data,
5091 state->max_data_return);
5092 END_PROFILE_NESTED(Trans2_open);
5096 case TRANSACT2_FINDFIRST:
5098 START_PROFILE_NESTED(Trans2_findfirst);
5099 outsize = call_trans2findfirst(
5100 conn, inbuf, outbuf, bufsize,
5101 &state->param, state->total_param,
5102 &state->data, state->total_data,
5103 state->max_data_return);
5104 END_PROFILE_NESTED(Trans2_findfirst);
5108 case TRANSACT2_FINDNEXT:
5110 START_PROFILE_NESTED(Trans2_findnext);
5111 outsize = call_trans2findnext(
5112 conn, inbuf, outbuf, size, bufsize,
5113 &state->param, state->total_param,
5114 &state->data, state->total_data,
5115 state->max_data_return);
5116 END_PROFILE_NESTED(Trans2_findnext);
5120 case TRANSACT2_QFSINFO:
5122 START_PROFILE_NESTED(Trans2_qfsinfo);
5123 outsize = call_trans2qfsinfo(
5124 conn, inbuf, outbuf, size, bufsize,
5125 &state->param, state->total_param,
5126 &state->data, state->total_data,
5127 state->max_data_return);
5128 END_PROFILE_NESTED(Trans2_qfsinfo);
5132 case TRANSACT2_SETFSINFO:
5134 START_PROFILE_NESTED(Trans2_setfsinfo);
5135 outsize = call_trans2setfsinfo(
5136 conn, inbuf, outbuf, size, bufsize,
5137 &state->param, state->total_param,
5138 &state->data, state->total_data,
5139 state->max_data_return);
5140 END_PROFILE_NESTED(Trans2_setfsinfo);
5144 case TRANSACT2_QPATHINFO:
5145 case TRANSACT2_QFILEINFO:
5147 START_PROFILE_NESTED(Trans2_qpathinfo);
5148 outsize = call_trans2qfilepathinfo(
5149 conn, inbuf, outbuf, size, bufsize, state->call,
5150 &state->param, state->total_param,
5151 &state->data, state->total_data,
5152 state->max_data_return);
5153 END_PROFILE_NESTED(Trans2_qpathinfo);
5157 case TRANSACT2_SETPATHINFO:
5158 case TRANSACT2_SETFILEINFO:
5160 START_PROFILE_NESTED(Trans2_setpathinfo);
5161 outsize = call_trans2setfilepathinfo(
5162 conn, inbuf, outbuf, size, bufsize, state->call,
5163 &state->param, state->total_param,
5164 &state->data, state->total_data,
5165 state->max_data_return);
5166 END_PROFILE_NESTED(Trans2_setpathinfo);
5170 case TRANSACT2_FINDNOTIFYFIRST:
5172 START_PROFILE_NESTED(Trans2_findnotifyfirst);
5173 outsize = call_trans2findnotifyfirst(
5174 conn, inbuf, outbuf, size, bufsize,
5175 &state->param, state->total_param,
5176 &state->data, state->total_data,
5177 state->max_data_return);
5178 END_PROFILE_NESTED(Trans2_findnotifyfirst);
5182 case TRANSACT2_FINDNOTIFYNEXT:
5184 START_PROFILE_NESTED(Trans2_findnotifynext);
5185 outsize = call_trans2findnotifynext(
5186 conn, inbuf, outbuf, size, bufsize,
5187 &state->param, state->total_param,
5188 &state->data, state->total_data,
5189 state->max_data_return);
5190 END_PROFILE_NESTED(Trans2_findnotifynext);
5194 case TRANSACT2_MKDIR:
5196 START_PROFILE_NESTED(Trans2_mkdir);
5197 outsize = call_trans2mkdir(
5198 conn, inbuf, outbuf, size, bufsize,
5199 &state->param, state->total_param,
5200 &state->data, state->total_data,
5201 state->max_data_return);
5202 END_PROFILE_NESTED(Trans2_mkdir);
5206 case TRANSACT2_GET_DFS_REFERRAL:
5208 START_PROFILE_NESTED(Trans2_get_dfs_referral);
5209 outsize = call_trans2getdfsreferral(
5210 conn, inbuf, outbuf, size, bufsize,
5211 &state->param, state->total_param,
5212 &state->data, state->total_data,
5213 state->max_data_return);
5214 END_PROFILE_NESTED(Trans2_get_dfs_referral);
5218 case TRANSACT2_IOCTL:
5220 START_PROFILE_NESTED(Trans2_ioctl);
5221 outsize = call_trans2ioctl(
5222 conn, inbuf, outbuf, size, bufsize,
5223 &state->param, state->total_param,
5224 &state->data, state->total_data,
5225 state->max_data_return);
5226 END_PROFILE_NESTED(Trans2_ioctl);
5231 /* Error in request */
5232 DEBUG(2,("Unknown request %d in trans2 call\n", state->call));
5233 outsize = ERROR_DOS(ERRSRV,ERRerror);
5239 /****************************************************************************
5240 Reply to a SMBtrans2.
5241 ****************************************************************************/
5243 int reply_trans2(connection_struct *conn, char *inbuf,char *outbuf,
5244 int size, int bufsize)
5247 unsigned int dsoff = SVAL(inbuf, smb_dsoff);
5248 unsigned int dscnt = SVAL(inbuf, smb_dscnt);
5249 unsigned int psoff = SVAL(inbuf, smb_psoff);
5250 unsigned int pscnt = SVAL(inbuf, smb_pscnt);
5251 unsigned int tran_call = SVAL(inbuf, smb_setup0);
5252 struct trans_state *state;
5255 START_PROFILE(SMBtrans2);
5257 result = allow_new_trans(conn->pending_trans, SVAL(inbuf, smb_mid));
5258 if (!NT_STATUS_IS_OK(result)) {
5259 DEBUG(2, ("Got invalid trans2 request: %s\n",
5260 nt_errstr(result)));
5261 END_PROFILE(SMBtrans2);
5262 return ERROR_NT(result);
5265 if (IS_IPC(conn) && (tran_call != TRANSACT2_OPEN)
5266 && (tran_call != TRANSACT2_GET_DFS_REFERRAL)) {
5267 END_PROFILE(SMBtrans2);
5268 return ERROR_DOS(ERRSRV,ERRaccess);
5271 if ((state = TALLOC_P(conn->mem_ctx, struct trans_state)) == NULL) {
5272 DEBUG(0, ("talloc failed\n"));
5273 END_PROFILE(SMBtrans2);
5274 return ERROR_NT(NT_STATUS_NO_MEMORY);
5277 state->cmd = SMBtrans2;
5279 state->mid = SVAL(inbuf, smb_mid);
5280 state->vuid = SVAL(inbuf, smb_uid);
5281 state->setup_count = SVAL(inbuf, smb_suwcnt);
5282 state->setup = NULL;
5283 state->total_param = SVAL(inbuf, smb_tpscnt);
5284 state->param = NULL;
5285 state->total_data = SVAL(inbuf, smb_tdscnt);
5287 state->max_param_return = SVAL(inbuf, smb_mprcnt);
5288 state->max_data_return = SVAL(inbuf, smb_mdrcnt);
5289 state->max_setup_return = SVAL(inbuf, smb_msrcnt);
5290 state->close_on_completion = BITSETW(inbuf+smb_vwv5,0);
5291 state->one_way = BITSETW(inbuf+smb_vwv5,1);
5293 state->call = tran_call;
5295 /* All trans2 messages we handle have smb_sucnt == 1 - ensure this
5296 is so as a sanity check */
5297 if (state->setup_count != 1) {
5299 * Need to have rc=0 for ioctl to get job id for OS/2.
5300 * Network printing will fail if function is not successful.
5301 * Similar function in reply.c will be used if protocol
5302 * is LANMAN1.0 instead of LM1.2X002.
5303 * Until DosPrintSetJobInfo with PRJINFO3 is supported,
5304 * outbuf doesn't have to be set(only job id is used).
5306 if ( (state->setup_count == 4) && (tran_call == TRANSACT2_IOCTL) &&
5307 (SVAL(inbuf,(smb_setup+4)) == LMCAT_SPL) &&
5308 (SVAL(inbuf,(smb_setup+6)) == LMFUNC_GETJOBID)) {
5309 DEBUG(2,("Got Trans2 DevIOctl jobid\n"));
5311 DEBUG(2,("Invalid smb_sucnt in trans2 call(%u)\n",state->setup_count));
5312 DEBUG(2,("Transaction is %d\n",tran_call));
5314 END_PROFILE(SMBtrans2);
5315 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
5319 if ((dscnt > state->total_data) || (pscnt > state->total_param))
5322 if (state->total_data) {
5323 /* Can't use talloc here, the core routines do realloc on the
5324 * params and data. */
5325 state->data = (char *)SMB_MALLOC(state->total_data);
5326 if (state->data == NULL) {
5327 DEBUG(0,("reply_trans2: data malloc fail for %u "
5328 "bytes !\n", (unsigned int)state->total_data));
5330 END_PROFILE(SMBtrans2);
5331 return(ERROR_DOS(ERRDOS,ERRnomem));
5333 if ((dsoff+dscnt < dsoff) || (dsoff+dscnt < dscnt))
5335 if ((smb_base(inbuf)+dsoff+dscnt > inbuf + size) ||
5336 (smb_base(inbuf)+dsoff+dscnt < smb_base(inbuf)))
5339 memcpy(state->data,smb_base(inbuf)+dsoff,dscnt);
5342 if (state->total_param) {
5343 /* Can't use talloc here, the core routines do realloc on the
5344 * params and data. */
5345 state->param = (char *)SMB_MALLOC(state->total_param);
5346 if (state->param == NULL) {
5347 DEBUG(0,("reply_trans: param malloc fail for %u "
5348 "bytes !\n", (unsigned int)state->total_param));
5349 SAFE_FREE(state->data);
5351 END_PROFILE(SMBtrans2);
5352 return(ERROR_DOS(ERRDOS,ERRnomem));
5354 if ((psoff+pscnt < psoff) || (psoff+pscnt < pscnt))
5356 if ((smb_base(inbuf)+psoff+pscnt > inbuf + size) ||
5357 (smb_base(inbuf)+psoff+pscnt < smb_base(inbuf)))
5360 memcpy(state->param,smb_base(inbuf)+psoff,pscnt);
5363 state->received_data = dscnt;
5364 state->received_param = pscnt;
5366 if ((state->received_param == state->total_param) &&
5367 (state->received_data == state->total_data)) {
5369 outsize = handle_trans2(conn, state, inbuf, outbuf,
5371 SAFE_FREE(state->data);
5372 SAFE_FREE(state->param);
5374 END_PROFILE(SMBtrans2);
5378 DLIST_ADD(conn->pending_trans, state);
5380 /* We need to send an interim response then receive the rest
5381 of the parameter/data bytes */
5382 outsize = set_message(outbuf,0,0,False);
5384 END_PROFILE(SMBtrans2);
5389 DEBUG(0,("reply_trans2: invalid trans parameters\n"));
5390 SAFE_FREE(state->data);
5391 SAFE_FREE(state->param);
5393 END_PROFILE(SMBtrans2);
5394 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
5398 /****************************************************************************
5399 Reply to a SMBtranss2
5400 ****************************************************************************/
5402 int reply_transs2(connection_struct *conn,
5403 char *inbuf,char *outbuf,int size,int bufsize)
5406 unsigned int pcnt,poff,dcnt,doff,pdisp,ddisp;
5407 struct trans_state *state;
5409 START_PROFILE(SMBtranss2);
5413 for (state = conn->pending_trans; state != NULL;
5414 state = state->next) {
5415 if (state->mid == SVAL(inbuf,smb_mid)) {
5420 if ((state == NULL) || (state->cmd != SMBtrans2)) {
5421 END_PROFILE(SMBtranss2);
5422 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
5425 /* Revise state->total_param and state->total_data in case they have
5426 changed downwards */
5428 if (SVAL(inbuf, smb_tpscnt) < state->total_param)
5429 state->total_param = SVAL(inbuf, smb_tpscnt);
5430 if (SVAL(inbuf, smb_tdscnt) < state->total_data)
5431 state->total_data = SVAL(inbuf, smb_tdscnt);
5433 pcnt = SVAL(inbuf, smb_spscnt);
5434 poff = SVAL(inbuf, smb_spsoff);
5435 pdisp = SVAL(inbuf, smb_spsdisp);
5437 dcnt = SVAL(inbuf, smb_sdscnt);
5438 doff = SVAL(inbuf, smb_sdsoff);
5439 ddisp = SVAL(inbuf, smb_sdsdisp);
5441 state->received_param += pcnt;
5442 state->received_data += dcnt;
5444 if ((state->received_data > state->total_data) ||
5445 (state->received_param > state->total_param))
5449 if (pdisp+pcnt > state->total_param)
5451 if ((pdisp+pcnt < pdisp) || (pdisp+pcnt < pcnt))
5453 if (pdisp > state->total_param)
5455 if ((smb_base(inbuf) + poff + pcnt > inbuf + size) ||
5456 (smb_base(inbuf) + poff + pcnt < smb_base(inbuf)))
5458 if (state->param + pdisp < state->param)
5461 memcpy(state->param+pdisp,smb_base(inbuf)+poff,
5466 if (ddisp+dcnt > state->total_data)
5468 if ((ddisp+dcnt < ddisp) || (ddisp+dcnt < dcnt))
5470 if (ddisp > state->total_data)
5472 if ((smb_base(inbuf) + doff + dcnt > inbuf + size) ||
5473 (smb_base(inbuf) + doff + dcnt < smb_base(inbuf)))
5475 if (state->data + ddisp < state->data)
5478 memcpy(state->data+ddisp, smb_base(inbuf)+doff,
5482 if ((state->received_param < state->total_param) ||
5483 (state->received_data < state->total_data)) {
5484 END_PROFILE(SMBtranss2);
5488 /* construct_reply_common has done us the favor to pre-fill the
5489 * command field with SMBtranss2 which is wrong :-)
5491 SCVAL(outbuf,smb_com,SMBtrans2);
5493 outsize = handle_trans2(conn, state, inbuf, outbuf, size, bufsize);
5495 DLIST_REMOVE(conn->pending_trans, state);
5496 SAFE_FREE(state->data);
5497 SAFE_FREE(state->param);
5501 END_PROFILE(SMBtranss2);
5502 return(ERROR_DOS(ERRSRV,ERRnosupport));
5505 END_PROFILE(SMBtranss2);
5510 DEBUG(0,("reply_transs2: invalid trans parameters\n"));
5511 DLIST_REMOVE(conn->pending_trans, state);
5512 SAFE_FREE(state->data);
5513 SAFE_FREE(state->param);
5515 END_PROFILE(SMBtranss2);
5516 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);