2 Unix SMB/CIFS implementation.
3 SMB transaction2 handling
4 Copyright (C) Jeremy Allison 1994-2003
5 Copyright (C) Stefan (metze) Metzmacher 2003
7 Extensively modified by Andrew Tridgell, 1995
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26 extern enum protocol_types Protocol;
27 extern int smb_read_error;
28 extern int global_oplock_break;
29 extern uint32 global_client_caps;
30 extern struct current_user current_user;
32 #define get_file_size(sbuf) ((sbuf).st_size)
33 #define DIR_ENTRY_SAFETY_MARGIN 4096
35 /********************************************************************
36 Roundup a value to the nearest allocation roundup size boundary.
37 Only do this for Windows clients.
38 ********************************************************************/
40 SMB_BIG_UINT smb_roundup(connection_struct *conn, SMB_BIG_UINT val)
42 SMB_BIG_UINT rval = lp_allocation_roundup_size(SNUM(conn));
44 /* Only roundup for Windows clients. */
45 enum remote_arch_types ra_type = get_remote_arch();
46 if (rval && (ra_type != RA_SAMBA) && (ra_type != RA_CIFSFS)) {
47 val = SMB_ROUNDUP(val,rval);
52 /********************************************************************
53 Given a stat buffer return the allocated size on disk, taking into
55 ********************************************************************/
57 SMB_BIG_UINT get_allocation_size(connection_struct *conn, files_struct *fsp, SMB_STRUCT_STAT *sbuf)
61 #if defined(HAVE_STAT_ST_BLOCKS) && defined(STAT_ST_BLOCKSIZE)
62 ret = (SMB_BIG_UINT)STAT_ST_BLOCKSIZE * (SMB_BIG_UINT)sbuf->st_blocks;
64 ret = (SMB_BIG_UINT)get_file_size(*sbuf);
67 if (!ret && fsp && fsp->initial_allocation_size)
68 ret = fsp->initial_allocation_size;
70 return smb_roundup(conn, ret);
73 /****************************************************************************
74 Utility functions for dealing with extended attributes.
75 ****************************************************************************/
77 static const char *prohibited_ea_names[] = {
78 SAMBA_POSIX_INHERITANCE_EA_NAME,
79 SAMBA_XATTR_DOS_ATTRIB,
83 /****************************************************************************
84 Refuse to allow clients to overwrite our private xattrs.
85 ****************************************************************************/
87 static BOOL samba_private_attr_name(const char *unix_ea_name)
91 for (i = 0; prohibited_ea_names[i]; i++) {
92 if (strequal( prohibited_ea_names[i], unix_ea_name))
99 struct ea_list *next, *prev;
103 /****************************************************************************
104 Get one EA value. Fill in a struct ea_struct.
105 ****************************************************************************/
107 static BOOL get_ea_value(TALLOC_CTX *mem_ctx, connection_struct *conn, files_struct *fsp,
108 const char *fname, char *ea_name, struct ea_struct *pea)
110 /* Get the value of this xattr. Max size is 64k. */
111 size_t attr_size = 256;
117 val = TALLOC_REALLOC_ARRAY(mem_ctx, val, char, attr_size);
122 if (fsp && fsp->fd != -1) {
123 sizeret = SMB_VFS_FGETXATTR(fsp, fsp->fd, ea_name, val, attr_size);
125 sizeret = SMB_VFS_GETXATTR(conn, fname, ea_name, val, attr_size);
128 if (sizeret == -1 && errno == ERANGE && attr_size != 65536) {
137 DEBUG(10,("get_ea_value: EA %s is of length %d: ", ea_name, sizeret));
138 dump_data(10, val, sizeret);
141 if (strnequal(ea_name, "user.", 5)) {
142 pea->name = &ea_name[5];
146 pea->value.data = (unsigned char *)val;
147 pea->value.length = (size_t)sizeret;
151 /****************************************************************************
152 Return a linked list of the total EA's. Plus the total size
153 ****************************************************************************/
155 static struct ea_list *get_ea_list_from_file(TALLOC_CTX *mem_ctx, connection_struct *conn, files_struct *fsp,
156 const char *fname, size_t *pea_total_len)
158 /* Get a list of all xattrs. Max namesize is 64k. */
159 size_t ea_namelist_size = 1024;
164 struct ea_list *ea_list_head = NULL;
168 if (!lp_ea_support(SNUM(conn))) {
172 for (i = 0, ea_namelist = TALLOC(mem_ctx, ea_namelist_size); i < 6;
173 ea_namelist = TALLOC_REALLOC_ARRAY(mem_ctx, ea_namelist, char, ea_namelist_size), i++) {
174 if (fsp && fsp->fd != -1) {
175 sizeret = SMB_VFS_FLISTXATTR(fsp, fsp->fd, ea_namelist, ea_namelist_size);
177 sizeret = SMB_VFS_LISTXATTR(conn, fname, ea_namelist, ea_namelist_size);
180 if (sizeret == -1 && errno == ERANGE) {
181 ea_namelist_size *= 2;
190 DEBUG(10,("get_ea_list_from_file: ea_namelist size = %d\n", sizeret ));
193 for (p = ea_namelist; p - ea_namelist < sizeret; p += strlen(p) + 1) {
194 struct ea_list *listp, *tmp;
196 if (strnequal(p, "system.", 7) || samba_private_attr_name(p))
199 listp = TALLOC_P(mem_ctx, struct ea_list);
203 if (!get_ea_value(mem_ctx, conn, fsp, fname, p, &listp->ea)) {
209 push_ascii_fstring(dos_ea_name, listp->ea.name);
210 *pea_total_len += 4 + strlen(dos_ea_name) + 1 + listp->ea.value.length;
211 DEBUG(10,("get_ea_list_from_file: total_len = %u, %s, val len = %u\n",
212 *pea_total_len, dos_ea_name,
213 (unsigned int)listp->ea.value.length ));
215 DLIST_ADD_END(ea_list_head, listp, tmp);
217 /* Add on 4 for total length. */
218 if (*pea_total_len) {
223 DEBUG(10,("get_ea_list_from_file: total_len = %u\n", *pea_total_len));
227 /****************************************************************************
228 Fill a qfilepathinfo buffer with EA's. Returns the length of the buffer
230 ****************************************************************************/
232 static unsigned int fill_ea_buffer(TALLOC_CTX *mem_ctx, char *pdata, unsigned int total_data_size,
233 connection_struct *conn, struct ea_list *ea_list)
235 unsigned int ret_data_size = 4;
238 SMB_ASSERT(total_data_size >= 4);
241 if (!lp_ea_support(SNUM(conn))) {
245 for (p = pdata + 4; ea_list; ea_list = ea_list->next) {
248 push_ascii_fstring(dos_ea_name, ea_list->ea.name);
249 dos_namelen = strlen(dos_ea_name);
250 if (dos_namelen > 255 || dos_namelen == 0) {
253 if (ea_list->ea.value.length > 65535) {
256 if (4 + dos_namelen + 1 + ea_list->ea.value.length > total_data_size) {
260 /* We know we have room. */
261 SCVAL(p,0,ea_list->ea.flags);
262 SCVAL(p,1,dos_namelen);
263 SSVAL(p,2,ea_list->ea.value.length);
264 fstrcpy(p+4, dos_ea_name);
265 memcpy( p + 4 + dos_namelen + 1, ea_list->ea.value.data, ea_list->ea.value.length);
267 total_data_size -= 4 + dos_namelen + 1 + ea_list->ea.value.length;
268 p += 4 + dos_namelen + 1 + ea_list->ea.value.length;
271 ret_data_size = PTR_DIFF(p, pdata);
272 DEBUG(10,("fill_ea_buffer: data_size = %u\n", ret_data_size ));
273 SIVAL(pdata,0,ret_data_size);
274 return ret_data_size;
277 static unsigned int estimate_ea_size(connection_struct *conn, files_struct *fsp, const char *fname)
279 size_t total_ea_len = 0;
280 TALLOC_CTX *mem_ctx = NULL;
282 if (!lp_ea_support(SNUM(conn))) {
285 mem_ctx = talloc_init("estimate_ea_size");
286 (void)get_ea_list_from_file(mem_ctx, conn, fsp, fname, &total_ea_len);
287 talloc_destroy(mem_ctx);
291 /****************************************************************************
292 Ensure the EA name is case insensitive by matching any existing EA name.
293 ****************************************************************************/
295 static void canonicalize_ea_name(connection_struct *conn, files_struct *fsp, const char *fname, fstring unix_ea_name)
298 TALLOC_CTX *mem_ctx = talloc_init("canonicalize_ea_name");
299 struct ea_list *ea_list = get_ea_list_from_file(mem_ctx, conn, fsp, fname, &total_ea_len);
301 for (; ea_list; ea_list = ea_list->next) {
302 if (strequal(&unix_ea_name[5], ea_list->ea.name)) {
303 DEBUG(10,("canonicalize_ea_name: %s -> %s\n",
304 &unix_ea_name[5], ea_list->ea.name));
305 safe_strcpy(&unix_ea_name[5], ea_list->ea.name, sizeof(fstring)-6);
309 talloc_destroy(mem_ctx);
312 /****************************************************************************
313 Set or delete an extended attribute.
314 ****************************************************************************/
316 static NTSTATUS set_ea(connection_struct *conn, files_struct *fsp, const char *fname, struct ea_list *ea_list)
318 if (!lp_ea_support(SNUM(conn))) {
319 return NT_STATUS_EAS_NOT_SUPPORTED;
322 for (;ea_list; ea_list = ea_list->next) {
324 fstring unix_ea_name;
326 fstrcpy(unix_ea_name, "user."); /* All EA's must start with user. */
327 fstrcat(unix_ea_name, ea_list->ea.name);
329 canonicalize_ea_name(conn, fsp, fname, unix_ea_name);
331 DEBUG(10,("set_ea: ea_name %s ealen = %u\n", unix_ea_name, ea_list->ea.value.length));
333 if (samba_private_attr_name(unix_ea_name)) {
334 DEBUG(10,("set_ea: ea name %s is a private Samba name.\n", unix_ea_name));
335 return NT_STATUS_ACCESS_DENIED;
338 if (ea_list->ea.value.length == 0) {
339 /* Remove the attribute. */
340 if (fsp && (fsp->fd != -1)) {
341 DEBUG(10,("set_ea: deleting ea name %s on file %s by file descriptor.\n",
342 unix_ea_name, fsp->fsp_name));
343 ret = SMB_VFS_FREMOVEXATTR(fsp, fsp->fd, unix_ea_name);
345 DEBUG(10,("set_ea: deleting ea name %s on file %s.\n",
346 unix_ea_name, fname));
347 ret = SMB_VFS_REMOVEXATTR(conn, fname, unix_ea_name);
350 /* Removing a non existent attribute always succeeds. */
351 if (ret == -1 && errno == ENOATTR) {
352 DEBUG(10,("set_ea: deleting ea name %s didn't exist - succeeding by default.\n",
358 if (fsp && (fsp->fd != -1)) {
359 DEBUG(10,("set_ea: setting ea name %s on file %s by file descriptor.\n",
360 unix_ea_name, fsp->fsp_name));
361 ret = SMB_VFS_FSETXATTR(fsp, fsp->fd, unix_ea_name,
362 ea_list->ea.value.data, ea_list->ea.value.length, 0);
364 DEBUG(10,("set_ea: setting ea name %s on file %s.\n",
365 unix_ea_name, fname));
366 ret = SMB_VFS_SETXATTR(conn, fname, unix_ea_name,
367 ea_list->ea.value.data, ea_list->ea.value.length, 0);
373 if (errno == ENOTSUP) {
374 return NT_STATUS_EAS_NOT_SUPPORTED;
377 return map_nt_error_from_unix(errno);
383 /****************************************************************************
384 Read a list of EA names from an incoming data buffer. Create an ea_list with them.
385 ****************************************************************************/
387 static struct ea_list *read_ea_name_list(TALLOC_CTX *ctx, const char *pdata, size_t data_size)
389 struct ea_list *ea_list_head = NULL;
392 while (offset + 2 < data_size) {
394 struct ea_list *eal = TALLOC_ZERO_P(ctx, struct ea_list);
395 unsigned int namelen = CVAL(pdata,offset);
397 offset++; /* Go past the namelen byte. */
398 if (offset + namelen >= data_size) {
401 /* Ensure the name is null terminated. */
402 if (pdata[offset + namelen] != '\0') {
405 pull_ascii_talloc(ctx, &eal->ea.name, &pdata[offset]);
410 offset += (namelen + 1); /* Go past the name + terminating zero. */
411 DLIST_ADD_END(ea_list_head, eal, tmp);
412 DEBUG(10,("read_ea_name_list: read ea name %s\n", eal->ea.name));
418 /****************************************************************************
419 Read a list of EA names and data from an incoming data buffer. Create an ea_list with them.
420 ****************************************************************************/
422 static struct ea_list *read_ea_list(TALLOC_CTX *ctx, const char *pdata, size_t data_size)
424 struct ea_list *ea_list_head = NULL;
427 if (data_size < 10) {
431 if (IVAL(pdata,0) > data_size) {
432 DEBUG(10,("read_ea_list: bad total data size (%u) > %u\n", IVAL(pdata,0), (unsigned int)data_size));
436 /* Each entry must be at least 6 bytes in length. */
437 while (offset + 6 <= data_size) {
439 struct ea_list *eal = TALLOC_ZERO_P(ctx, struct ea_list);
441 unsigned int namelen;
443 eal->ea.flags = CVAL(pdata,offset);
444 namelen = CVAL(pdata,offset + 1);
445 val_len = SVAL(pdata,offset + 2);
447 if (offset + 4 + namelen + 1 + val_len > data_size) {
451 /* Ensure the name is null terminated. */
452 if (pdata[offset + 4 + namelen] != '\0') {
455 pull_ascii_talloc(ctx, &eal->ea.name, pdata + offset + 4);
460 eal->ea.value = data_blob(NULL, (size_t)val_len + 1);
461 if (!eal->ea.value.data) {
465 memcpy(eal->ea.value.data, pdata + offset + 4 + namelen + 1, val_len);
467 /* Ensure we're null terminated just in case we print the value. */
468 eal->ea.value.data[val_len] = '\0';
469 /* But don't count the null. */
470 eal->ea.value.length--;
472 offset += 4 + namelen + 1 + val_len;
474 DLIST_ADD_END(ea_list_head, eal, tmp);
476 DEBUG(10,("read_ea_name_list: read ea name %s\n", eal->ea.name));
477 dump_data(10, eal->ea.value.data, eal->ea.value.length);
483 /****************************************************************************
484 Count the total EA size needed.
485 ****************************************************************************/
487 static size_t ea_list_size(struct ea_list *ealist)
490 struct ea_list *listp;
493 for (listp = ealist; listp; listp = listp->next) {
494 push_ascii_fstring(dos_ea_name, listp->ea.name);
495 ret += 4 + strlen(dos_ea_name) + 1 + listp->ea.value.length;
497 /* Add on 4 for total length. */
505 /****************************************************************************
506 Return a union of EA's from a file list and a list of names.
507 The TALLOC context for the two lists *MUST* be identical as we steal
508 memory from one list to another. JRA.
509 ****************************************************************************/
511 static struct ea_list *ea_list_union(struct ea_list *name_list, struct ea_list *file_list, size_t *total_ea_len)
513 struct ea_list *nlistp, *flistp;
515 for (nlistp = name_list; nlistp; nlistp = nlistp->next) {
516 for (flistp = file_list; flistp; flistp = flistp->next) {
517 if (strequal(nlistp->ea.name, flistp->ea.name)) {
523 /* Copy the data from this entry. */
524 nlistp->ea.flags = flistp->ea.flags;
525 nlistp->ea.value = flistp->ea.value;
528 nlistp->ea.flags = 0;
529 ZERO_STRUCT(nlistp->ea.value);
533 *total_ea_len = ea_list_size(name_list);
537 /****************************************************************************
538 Send the required number of replies back.
539 We assume all fields other than the data fields are
540 set correctly for the type of call.
541 HACK ! Always assumes smb_setup field is zero.
542 ****************************************************************************/
544 static int send_trans2_replies(char *outbuf,
551 /* As we are using a protocol > LANMAN1 then the max_send
552 variable must have been set in the sessetupX call.
553 This takes precedence over the max_xmit field in the
554 global struct. These different max_xmit variables should
555 be merged as this is now too confusing */
558 int data_to_send = datasize;
559 int params_to_send = paramsize;
563 int params_sent_thistime, data_sent_thistime, total_sent_thistime;
564 int alignment_offset = 1; /* JRA. This used to be 3. Set to 1 to make netmon parse ok. */
565 int data_alignment_offset = 0;
567 /* Initially set the wcnt area to be 10 - this is true for all trans2 replies */
569 set_message(outbuf,10,0,True);
571 /* If there genuinely are no parameters or data to send just send the empty packet */
573 if(params_to_send == 0 && data_to_send == 0) {
574 if (!send_smb(smbd_server_fd(),outbuf))
575 exit_server("send_trans2_replies: send_smb failed.");
579 /* When sending params and data ensure that both are nicely aligned */
580 /* Only do this alignment when there is also data to send - else
581 can cause NT redirector problems. */
583 if (((params_to_send % 4) != 0) && (data_to_send != 0))
584 data_alignment_offset = 4 - (params_to_send % 4);
586 /* Space is bufsize minus Netbios over TCP header minus SMB header */
587 /* The alignment_offset is to align the param bytes on an even byte
588 boundary. NT 4.0 Beta needs this to work correctly. */
590 useable_space = bufsize - ((smb_buf(outbuf)+ alignment_offset+data_alignment_offset) - outbuf);
592 /* useable_space can never be more than max_send minus the alignment offset. */
594 useable_space = MIN(useable_space, max_send - (alignment_offset+data_alignment_offset));
596 while (params_to_send || data_to_send) {
597 /* Calculate whether we will totally or partially fill this packet */
599 total_sent_thistime = params_to_send + data_to_send + alignment_offset + data_alignment_offset;
601 /* We can never send more than useable_space */
603 * Note that 'useable_space' does not include the alignment offsets,
604 * but we must include the alignment offsets in the calculation of
605 * the length of the data we send over the wire, as the alignment offsets
606 * are sent here. Fix from Marc_Jacobsen@hp.com.
609 total_sent_thistime = MIN(total_sent_thistime, useable_space+ alignment_offset + data_alignment_offset);
611 set_message(outbuf, 10, total_sent_thistime, True);
613 /* Set total params and data to be sent */
614 SSVAL(outbuf,smb_tprcnt,paramsize);
615 SSVAL(outbuf,smb_tdrcnt,datasize);
617 /* Calculate how many parameters and data we can fit into
618 * this packet. Parameters get precedence
621 params_sent_thistime = MIN(params_to_send,useable_space);
622 data_sent_thistime = useable_space - params_sent_thistime;
623 data_sent_thistime = MIN(data_sent_thistime,data_to_send);
625 SSVAL(outbuf,smb_prcnt, params_sent_thistime);
627 /* smb_proff is the offset from the start of the SMB header to the
628 parameter bytes, however the first 4 bytes of outbuf are
629 the Netbios over TCP header. Thus use smb_base() to subtract
630 them from the calculation */
632 SSVAL(outbuf,smb_proff,((smb_buf(outbuf)+alignment_offset) - smb_base(outbuf)));
634 if(params_sent_thistime == 0)
635 SSVAL(outbuf,smb_prdisp,0);
637 /* Absolute displacement of param bytes sent in this packet */
638 SSVAL(outbuf,smb_prdisp,pp - params);
640 SSVAL(outbuf,smb_drcnt, data_sent_thistime);
641 if(data_sent_thistime == 0) {
642 SSVAL(outbuf,smb_droff,0);
643 SSVAL(outbuf,smb_drdisp, 0);
645 /* The offset of the data bytes is the offset of the
646 parameter bytes plus the number of parameters being sent this time */
647 SSVAL(outbuf,smb_droff,((smb_buf(outbuf)+alignment_offset) -
648 smb_base(outbuf)) + params_sent_thistime + data_alignment_offset);
649 SSVAL(outbuf,smb_drdisp, pd - pdata);
652 /* Copy the param bytes into the packet */
654 if(params_sent_thistime)
655 memcpy((smb_buf(outbuf)+alignment_offset),pp,params_sent_thistime);
657 /* Copy in the data bytes */
658 if(data_sent_thistime)
659 memcpy(smb_buf(outbuf)+alignment_offset+params_sent_thistime+
660 data_alignment_offset,pd,data_sent_thistime);
662 DEBUG(9,("t2_rep: params_sent_thistime = %d, data_sent_thistime = %d, useable_space = %d\n",
663 params_sent_thistime, data_sent_thistime, useable_space));
664 DEBUG(9,("t2_rep: params_to_send = %d, data_to_send = %d, paramsize = %d, datasize = %d\n",
665 params_to_send, data_to_send, paramsize, datasize));
667 /* Send the packet */
668 if (!send_smb(smbd_server_fd(),outbuf))
669 exit_server("send_trans2_replies: send_smb failed.");
671 pp += params_sent_thistime;
672 pd += data_sent_thistime;
674 params_to_send -= params_sent_thistime;
675 data_to_send -= data_sent_thistime;
678 if(params_to_send < 0 || data_to_send < 0) {
679 DEBUG(0,("send_trans2_replies failed sanity check pts = %d, dts = %d\n!!!",
680 params_to_send, data_to_send));
688 /****************************************************************************
689 Reply to a TRANSACT2_OPEN.
690 ****************************************************************************/
692 static int call_trans2open(connection_struct *conn, char *inbuf, char *outbuf, int bufsize,
693 char **pparams, int total_params, char **ppdata, int total_data,
694 unsigned int max_data_bytes)
696 char *params = *pparams;
701 BOOL return_additional_info;
710 int fmode=0,mtime=0,rmode;
712 SMB_STRUCT_STAT sbuf;
714 BOOL bad_path = False;
719 * Ensure we have enough parameters to perform the operation.
722 if (total_params < 29) {
723 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
726 open_mode = SVAL(params, 2);
727 open_attr = SVAL(params,6);
728 oplock_request = (((SVAL(params,0)|(1<<1))>>1) | ((SVAL(params,0)|(1<<2))>>1));
730 return_additional_info = BITSETW(params,0);
731 open_sattr = SVAL(params, 4);
732 open_time = make_unix_date3(params+8);
734 open_ofun = SVAL(params,12);
735 open_size = IVAL(params,14);
739 return(ERROR_DOS(ERRSRV,ERRaccess));
741 srvstr_get_path(inbuf, fname, pname, sizeof(fname), -1, STR_TERMINATE, &status, False);
742 if (!NT_STATUS_IS_OK(status)) {
743 return ERROR_NT(status);
746 DEBUG(3,("trans2open %s mode=%d attr=%d ofun=%d size=%d\n",
747 fname,open_mode, open_attr, open_ofun, open_size));
749 /* XXXX we need to handle passed times, sattr and flags */
751 unix_convert(fname,conn,0,&bad_path,&sbuf);
753 return ERROR_NT(NT_STATUS_OBJECT_PATH_NOT_FOUND);
756 if (!check_name(fname,conn)) {
757 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRnoaccess);
760 fsp = open_file_shared(conn,fname,&sbuf,open_mode,open_ofun,(uint32)open_attr,
761 oplock_request, &rmode,&smb_action);
764 if (open_was_deferred(SVAL(inbuf,smb_mid))) {
765 /* We have re-scheduled this call. */
766 clear_cached_errors();
769 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRnoaccess);
772 size = get_file_size(sbuf);
773 fmode = dos_mode(conn,fname,&sbuf);
774 mtime = sbuf.st_mtime;
777 close_file(fsp,False);
778 return(ERROR_DOS(ERRDOS,ERRnoaccess));
781 /* Realloc the size of parameters and data we will return */
782 params = SMB_REALLOC(*pparams, 28);
783 if( params == NULL ) {
784 return ERROR_NT(NT_STATUS_NO_MEMORY);
788 memset((char *)params,'\0',28);
789 SSVAL(params,0,fsp->fnum);
790 SSVAL(params,2,fmode);
791 put_dos_date2(params,4, mtime);
792 SIVAL(params,8, (uint32)size);
793 SSVAL(params,12,rmode);
795 if (oplock_request && lp_fake_oplocks(SNUM(conn)))
796 smb_action |= EXTENDED_OPLOCK_GRANTED;
798 SSVAL(params,18,smb_action);
801 * WARNING - this may need to be changed if SMB_INO_T <> 4 bytes.
803 SIVAL(params,20,inode);
805 /* Send the required number of replies */
806 send_trans2_replies(outbuf, bufsize, params, 28, *ppdata, 0);
811 /*********************************************************
812 Routine to check if a given string matches exactly.
813 as a special case a mask of "." does NOT match. That
814 is required for correct wildcard semantics
815 Case can be significant or not.
816 **********************************************************/
818 static BOOL exact_match(char *str,char *mask, BOOL case_sig)
820 if (mask[0] == '.' && mask[1] == 0)
823 return strcmp(str,mask)==0;
824 if (StrCaseCmp(str,mask) != 0) {
827 if (ms_has_wild(str)) {
833 /****************************************************************************
834 Return the filetype for UNIX extensions.
835 ****************************************************************************/
837 static uint32 unix_filetype(mode_t mode)
840 return UNIX_TYPE_FILE;
841 else if(S_ISDIR(mode))
842 return UNIX_TYPE_DIR;
844 else if(S_ISLNK(mode))
845 return UNIX_TYPE_SYMLINK;
848 else if(S_ISCHR(mode))
849 return UNIX_TYPE_CHARDEV;
852 else if(S_ISBLK(mode))
853 return UNIX_TYPE_BLKDEV;
856 else if(S_ISFIFO(mode))
857 return UNIX_TYPE_FIFO;
860 else if(S_ISSOCK(mode))
861 return UNIX_TYPE_SOCKET;
864 DEBUG(0,("unix_filetype: unknown filetype %u", (unsigned)mode));
865 return UNIX_TYPE_UNKNOWN;
868 /****************************************************************************
869 Map wire perms onto standard UNIX permissions. Obey share restrictions.
870 ****************************************************************************/
872 static mode_t unix_perms_from_wire( connection_struct *conn, SMB_STRUCT_STAT *pst, uint32 perms)
876 if (perms == SMB_MODE_NO_CHANGE)
879 ret |= ((perms & UNIX_X_OTH ) ? S_IXOTH : 0);
880 ret |= ((perms & UNIX_W_OTH ) ? S_IWOTH : 0);
881 ret |= ((perms & UNIX_R_OTH ) ? S_IROTH : 0);
882 ret |= ((perms & UNIX_X_GRP ) ? S_IXGRP : 0);
883 ret |= ((perms & UNIX_W_GRP ) ? S_IWGRP : 0);
884 ret |= ((perms & UNIX_R_GRP ) ? S_IRGRP : 0);
885 ret |= ((perms & UNIX_X_USR ) ? S_IXUSR : 0);
886 ret |= ((perms & UNIX_W_USR ) ? S_IWUSR : 0);
887 ret |= ((perms & UNIX_R_USR ) ? S_IRUSR : 0);
889 ret |= ((perms & UNIX_STICKY ) ? S_ISVTX : 0);
892 ret |= ((perms & UNIX_SET_GID ) ? S_ISGID : 0);
895 ret |= ((perms & UNIX_SET_UID ) ? S_ISUID : 0);
898 if (VALID_STAT(*pst) && S_ISDIR(pst->st_mode)) {
899 ret &= lp_dir_mask(SNUM(conn));
900 /* Add in force bits */
901 ret |= lp_force_dir_mode(SNUM(conn));
903 /* Apply mode mask */
904 ret &= lp_create_mask(SNUM(conn));
905 /* Add in force bits */
906 ret |= lp_force_create_mode(SNUM(conn));
912 /****************************************************************************
913 Get a level dependent lanman2 dir entry.
914 ****************************************************************************/
916 static BOOL get_lanman2_dir_entry(connection_struct *conn,
917 void *inbuf, void *outbuf,
918 char *path_mask,int dirtype,int info_level,
919 int requires_resume_key,
920 BOOL dont_descend,char **ppdata,
921 char *base_data, int space_remaining,
922 BOOL *out_of_space, BOOL *got_exact_match,
923 int *last_entry_off, struct ea_list *name_list, TALLOC_CTX *ea_ctx)
927 SMB_STRUCT_STAT sbuf;
931 char *p, *q, *pdata = *ppdata;
935 SMB_OFF_T file_size = 0;
936 SMB_BIG_UINT allocation_size = 0;
938 time_t mdate=0, adate=0, cdate=0;
940 char *last_entry_ptr;
942 int nt_extmode; /* Used for NT connections instead of mode */
943 BOOL needslash = ( conn->dirpath[strlen(conn->dirpath) -1] != '/');
946 *out_of_space = False;
947 *got_exact_match = False;
952 p = strrchr_m(path_mask,'/');
959 pstrcpy(mask, path_mask);
964 /* Needed if we run out of space */
965 long curr_dirpos = prev_dirpos = dptr_TellDir(conn->dirptr);
966 dname = dptr_ReadDirName(conn->dirptr,&curr_dirpos,&sbuf);
969 * Due to bugs in NT client redirectors we are not using
970 * resume keys any more - set them to zero.
971 * Check out the related comments in findfirst/findnext.
977 DEBUG(8,("get_lanman2_dir_entry:readdir on dirptr 0x%lx now at offset %ld\n",
978 (long)conn->dirptr,curr_dirpos));
983 pstrcpy(fname,dname);
985 if(!(got_match = *got_exact_match = exact_match(fname, mask, conn->case_sensitive)))
986 got_match = mask_match(fname, mask, conn->case_sensitive);
988 if(!got_match && !mangle_is_8_3(fname, False)) {
991 * It turns out that NT matches wildcards against
992 * both long *and* short names. This may explain some
993 * of the wildcard wierdness from old DOS clients
994 * that some people have been seeing.... JRA.
998 pstrcpy( newname, fname);
999 mangle_map( newname, True, False, SNUM(conn));
1000 if(!(got_match = *got_exact_match = exact_match(newname, mask, conn->case_sensitive)))
1001 got_match = mask_match(newname, mask, conn->case_sensitive);
1005 BOOL isdots = (strequal(fname,"..") || strequal(fname,"."));
1006 if (dont_descend && !isdots)
1009 pstrcpy(pathreal,conn->dirpath);
1011 pstrcat(pathreal,"/");
1012 pstrcat(pathreal,dname);
1014 if (INFO_LEVEL_IS_UNIX(info_level)) {
1015 if (SMB_VFS_LSTAT(conn,pathreal,&sbuf) != 0) {
1016 DEBUG(5,("get_lanman2_dir_entry:Couldn't lstat [%s] (%s)\n",
1017 pathreal,strerror(errno)));
1020 } else if (!VALID_STAT(sbuf) && SMB_VFS_STAT(conn,pathreal,&sbuf) != 0) {
1022 /* Needed to show the msdfs symlinks as
1025 if(lp_host_msdfs() &&
1026 lp_msdfs_root(SNUM(conn)) &&
1027 is_msdfs_link(conn, pathreal, NULL, NULL,
1030 DEBUG(5,("get_lanman2_dir_entry: Masquerading msdfs link %s as a directory\n", pathreal));
1031 sbuf.st_mode = (sbuf.st_mode & 0xFFF) | S_IFDIR;
1035 DEBUG(5,("get_lanman2_dir_entry:Couldn't stat [%s] (%s)\n",
1036 pathreal,strerror(errno)));
1041 mode = dos_mode(conn,pathreal,&sbuf);
1043 if (!dir_check_ftype(conn,mode,dirtype)) {
1044 DEBUG(5,("[%s] attribs didn't match %x\n",fname,dirtype));
1048 file_size = get_file_size(sbuf);
1049 allocation_size = get_allocation_size(conn,NULL,&sbuf);
1050 mdate = sbuf.st_mtime;
1051 adate = sbuf.st_atime;
1052 cdate = get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(conn)));
1054 if (lp_dos_filetime_resolution(SNUM(conn))) {
1061 /* This is necessary, as otherwise the
1062 * desktop.ini file in this folder is
1064 mode |= (lp_profile_acls(SNUM(conn)) ? aRONLY : 0);
1068 DEBUG(5,("get_lanman2_dir_entry found %s fname=%s\n",pathreal,fname));
1074 mangle_map(fname,False,True,SNUM(conn));
1079 nt_extmode = mode ? mode : FILE_ATTRIBUTE_NORMAL;
1081 switch (info_level) {
1082 case SMB_FIND_INFO_STANDARD:
1083 DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_INFO_STANDARD\n"));
1084 if(requires_resume_key) {
1088 put_dos_date2(p,l1_fdateCreation,cdate);
1089 put_dos_date2(p,l1_fdateLastAccess,adate);
1090 put_dos_date2(p,l1_fdateLastWrite,mdate);
1091 SIVAL(p,l1_cbFile,(uint32)file_size);
1092 SIVAL(p,l1_cbFileAlloc,(uint32)allocation_size);
1093 SSVAL(p,l1_attrFile,mode);
1096 p += align_string(outbuf, p, 0);
1097 len = srvstr_push(outbuf, p, fname, -1, STR_TERMINATE);
1098 if (SVAL(outbuf, smb_flg2) & FLAGS2_UNICODE_STRINGS) {
1100 SCVAL(nameptr, -1, len - 2);
1102 SCVAL(nameptr, -1, 0);
1106 SCVAL(nameptr, -1, len - 1);
1108 SCVAL(nameptr, -1, 0);
1114 case SMB_FIND_EA_SIZE:
1115 DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_EA_SIZE\n"));
1116 if(requires_resume_key) {
1120 put_dos_date2(p,l2_fdateCreation,cdate);
1121 put_dos_date2(p,l2_fdateLastAccess,adate);
1122 put_dos_date2(p,l2_fdateLastWrite,mdate);
1123 SIVAL(p,l2_cbFile,(uint32)file_size);
1124 SIVAL(p,l2_cbFileAlloc,(uint32)allocation_size);
1125 SSVAL(p,l2_attrFile,mode);
1127 unsigned int ea_size = estimate_ea_size(conn, NULL, pathreal);
1128 SIVAL(p,l2_cbList,ea_size); /* Extended attributes */
1132 len = srvstr_push(outbuf, p, fname, -1, STR_TERMINATE | STR_NOALIGN);
1133 if (SVAL(outbuf, smb_flg2) & FLAGS2_UNICODE_STRINGS) {
1146 SCVAL(nameptr,0,len);
1148 SCVAL(p,0,0); p += 1; /* Extra zero byte ? - why.. */
1151 case SMB_FIND_EA_LIST:
1153 struct ea_list *file_list = NULL;
1156 DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_EA_LIST\n"));
1160 if(requires_resume_key) {
1164 put_dos_date2(p,l2_fdateCreation,cdate);
1165 put_dos_date2(p,l2_fdateLastAccess,adate);
1166 put_dos_date2(p,l2_fdateLastWrite,mdate);
1167 SIVAL(p,l2_cbFile,(uint32)file_size);
1168 SIVAL(p,l2_cbFileAlloc,(uint32)allocation_size);
1169 SSVAL(p,l2_attrFile,mode);
1170 p += l2_cbList; /* p now points to the EA area. */
1172 file_list = get_ea_list_from_file(ea_ctx, conn, NULL, pathreal, &ea_len);
1173 name_list = ea_list_union(name_list, file_list, &ea_len);
1175 /* We need to determine if this entry will fit in the space available. */
1176 /* Max string size is 255 bytes. */
1177 if (PTR_DIFF(p + 255 + ea_len,pdata) > space_remaining) {
1178 /* Move the dirptr back to prev_dirpos */
1179 dptr_SeekDir(conn->dirptr, prev_dirpos);
1180 *out_of_space = True;
1181 DEBUG(9,("get_lanman2_dir_entry: out of space\n"));
1182 return False; /* Not finished - just out of space */
1185 /* Push the ea_data followed by the name. */
1186 p += fill_ea_buffer(ea_ctx, p, space_remaining, conn, name_list);
1188 len = srvstr_push(outbuf, p + 1, fname, -1, STR_TERMINATE | STR_NOALIGN);
1189 if (SVAL(outbuf, smb_flg2) & FLAGS2_UNICODE_STRINGS) {
1202 SCVAL(nameptr,0,len);
1204 SCVAL(p,0,0); p += 1; /* Extra zero byte ? - why.. */
1208 case SMB_FIND_FILE_BOTH_DIRECTORY_INFO:
1209 DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_FILE_BOTH_DIRECTORY_INFO\n"));
1210 was_8_3 = mangle_is_8_3(fname, True);
1212 SIVAL(p,0,reskey); p += 4;
1213 put_long_date(p,cdate); p += 8;
1214 put_long_date(p,adate); p += 8;
1215 put_long_date(p,mdate); p += 8;
1216 put_long_date(p,mdate); p += 8;
1217 SOFF_T(p,0,file_size); p += 8;
1218 SOFF_T(p,0,allocation_size); p += 8;
1219 SIVAL(p,0,nt_extmode); p += 4;
1220 q = p; p += 4; /* q is placeholder for name length. */
1222 unsigned int ea_size = estimate_ea_size(conn, NULL, pathreal);
1223 SIVAL(p,0,ea_size); /* Extended attributes */
1226 /* Clear the short name buffer. This is
1227 * IMPORTANT as not doing so will trigger
1228 * a Win2k client bug. JRA.
1231 if (!was_8_3 && lp_manglednames(SNUM(conn))) {
1232 pstring mangled_name;
1233 pstrcpy(mangled_name, fname);
1234 mangle_map(mangled_name,True,True,SNUM(conn));
1235 mangled_name[12] = 0;
1236 len = srvstr_push(outbuf, p+2, mangled_name, 24, STR_UPPER|STR_UNICODE);
1243 len = srvstr_push(outbuf, p, fname, -1, STR_TERMINATE_ASCII);
1246 len = PTR_DIFF(p, pdata);
1247 len = (len + 3) & ~3;
1252 case SMB_FIND_FILE_DIRECTORY_INFO:
1253 DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_FILE_DIRECTORY_INFO\n"));
1255 SIVAL(p,0,reskey); p += 4;
1256 put_long_date(p,cdate); p += 8;
1257 put_long_date(p,adate); p += 8;
1258 put_long_date(p,mdate); p += 8;
1259 put_long_date(p,mdate); p += 8;
1260 SOFF_T(p,0,file_size); p += 8;
1261 SOFF_T(p,0,allocation_size); p += 8;
1262 SIVAL(p,0,nt_extmode); p += 4;
1263 len = srvstr_push(outbuf, p + 4, fname, -1, STR_TERMINATE_ASCII);
1266 len = PTR_DIFF(p, pdata);
1267 len = (len + 3) & ~3;
1272 case SMB_FIND_FILE_FULL_DIRECTORY_INFO:
1273 DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_FILE_FULL_DIRECTORY_INFO\n"));
1275 SIVAL(p,0,reskey); p += 4;
1276 put_long_date(p,cdate); p += 8;
1277 put_long_date(p,adate); p += 8;
1278 put_long_date(p,mdate); p += 8;
1279 put_long_date(p,mdate); p += 8;
1280 SOFF_T(p,0,file_size); p += 8;
1281 SOFF_T(p,0,allocation_size); p += 8;
1282 SIVAL(p,0,nt_extmode); p += 4;
1283 q = p; p += 4; /* q is placeholder for name length. */
1285 unsigned int ea_size = estimate_ea_size(conn, NULL, pathreal);
1286 SIVAL(p,0,ea_size); /* Extended attributes */
1289 len = srvstr_push(outbuf, p, fname, -1, STR_TERMINATE_ASCII);
1293 len = PTR_DIFF(p, pdata);
1294 len = (len + 3) & ~3;
1299 case SMB_FIND_FILE_NAMES_INFO:
1300 DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_FILE_NAMES_INFO\n"));
1302 SIVAL(p,0,reskey); p += 4;
1304 /* this must *not* be null terminated or w2k gets in a loop trying to set an
1305 acl on a dir (tridge) */
1306 len = srvstr_push(outbuf, p, fname, -1, STR_TERMINATE_ASCII);
1309 len = PTR_DIFF(p, pdata);
1310 len = (len + 3) & ~3;
1315 case SMB_FIND_ID_FULL_DIRECTORY_INFO:
1316 DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_ID_FULL_DIRECTORY_INFO\n"));
1318 SIVAL(p,0,reskey); p += 4;
1319 put_long_date(p,cdate); p += 8;
1320 put_long_date(p,adate); p += 8;
1321 put_long_date(p,mdate); p += 8;
1322 put_long_date(p,mdate); p += 8;
1323 SOFF_T(p,0,file_size); p += 8;
1324 SOFF_T(p,0,allocation_size); p += 8;
1325 SIVAL(p,0,nt_extmode); p += 4;
1326 q = p; p += 4; /* q is placeholder for name length. */
1328 unsigned int ea_size = estimate_ea_size(conn, NULL, pathreal);
1329 SIVAL(p,0,ea_size); /* Extended attributes */
1332 SIVAL(p,0,0); p += 4; /* Unknown - reserved ? */
1333 SIVAL(p,0,sbuf.st_dev); p += 4;
1334 SIVAL(p,0,sbuf.st_ino); p += 4;
1335 len = srvstr_push(outbuf, p, fname, -1, STR_TERMINATE_ASCII);
1338 len = PTR_DIFF(p, pdata);
1339 len = (len + 3) & ~3;
1344 case SMB_FIND_ID_BOTH_DIRECTORY_INFO:
1345 DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_ID_BOTH_DIRECTORY_INFO\n"));
1346 was_8_3 = mangle_is_8_3(fname, True);
1348 SIVAL(p,0,reskey); p += 4;
1349 put_long_date(p,cdate); p += 8;
1350 put_long_date(p,adate); p += 8;
1351 put_long_date(p,mdate); p += 8;
1352 put_long_date(p,mdate); p += 8;
1353 SOFF_T(p,0,file_size); p += 8;
1354 SOFF_T(p,0,allocation_size); p += 8;
1355 SIVAL(p,0,nt_extmode); p += 4;
1356 q = p; p += 4; /* q is placeholder for name length */
1358 unsigned int ea_size = estimate_ea_size(conn, NULL, pathreal);
1359 SIVAL(p,0,ea_size); /* Extended attributes */
1362 /* Clear the short name buffer. This is
1363 * IMPORTANT as not doing so will trigger
1364 * a Win2k client bug. JRA.
1367 if (!was_8_3 && lp_manglednames(SNUM(conn))) {
1368 pstring mangled_name;
1369 pstrcpy(mangled_name, fname);
1370 mangle_map(mangled_name,True,True,SNUM(conn));
1371 mangled_name[12] = 0;
1372 len = srvstr_push(outbuf, p+2, mangled_name, 24, STR_UPPER|STR_UNICODE);
1379 SSVAL(p,0,0); p += 2; /* Reserved ? */
1380 SIVAL(p,0,sbuf.st_dev); p += 4;
1381 SIVAL(p,0,sbuf.st_ino); p += 4;
1382 len = srvstr_push(outbuf, p, fname, -1, STR_TERMINATE_ASCII);
1385 len = PTR_DIFF(p, pdata);
1386 len = (len + 3) & ~3;
1391 /* CIFS UNIX Extension. */
1393 case SMB_FIND_FILE_UNIX:
1394 DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_FILE_UNIX\n"));
1396 SIVAL(p,0,reskey); p+= 4; /* Used for continuing search. */
1398 /* Begin of SMB_QUERY_FILE_UNIX_BASIC */
1399 SOFF_T(p,0,get_file_size(sbuf)); /* File size 64 Bit */
1402 SOFF_T(p,0,get_allocation_size(conn,NULL,&sbuf)); /* Number of bytes used on disk - 64 Bit */
1405 put_long_date(p,sbuf.st_ctime); /* Inode change Time 64 Bit */
1406 put_long_date(p+8,sbuf.st_atime); /* Last access time 64 Bit */
1407 put_long_date(p+16,sbuf.st_mtime); /* Last modification time 64 Bit */
1410 SIVAL(p,0,sbuf.st_uid); /* user id for the owner */
1414 SIVAL(p,0,sbuf.st_gid); /* group id of owner */
1418 SIVAL(p,0,unix_filetype(sbuf.st_mode));
1421 SIVAL(p,0,unix_dev_major(sbuf.st_rdev)); /* Major device number if type is device */
1425 SIVAL(p,0,unix_dev_minor(sbuf.st_rdev)); /* Minor device number if type is device */
1429 SINO_T(p,0,(SMB_INO_T)sbuf.st_ino); /* inode number */
1432 SIVAL(p,0, unix_perms_to_wire(sbuf.st_mode)); /* Standard UNIX file permissions */
1436 SIVAL(p,0,sbuf.st_nlink); /* number of hard links */
1440 len = srvstr_push(outbuf, p, fname, -1, STR_TERMINATE);
1443 len = PTR_DIFF(p, pdata);
1444 len = (len + 3) & ~3;
1445 SIVAL(pdata,0,len); /* Offset from this structure to the beginning of the next one */
1447 /* End of SMB_QUERY_FILE_UNIX_BASIC */
1456 if (PTR_DIFF(p,pdata) > space_remaining) {
1457 /* Move the dirptr back to prev_dirpos */
1458 dptr_SeekDir(conn->dirptr, prev_dirpos);
1459 *out_of_space = True;
1460 DEBUG(9,("get_lanman2_dir_entry: out of space\n"));
1461 return False; /* Not finished - just out of space */
1464 /* Setup the last entry pointer, as an offset from base_data */
1465 *last_entry_off = PTR_DIFF(last_entry_ptr,base_data);
1466 /* Advance the data pointer to the next slot */
1472 /****************************************************************************
1473 Reply to a TRANS2_FINDFIRST.
1474 ****************************************************************************/
1476 static int call_trans2findfirst(connection_struct *conn, char *inbuf, char *outbuf, int bufsize,
1477 char **pparams, int total_params, char **ppdata, int total_data,
1478 unsigned int max_data_bytes)
1480 /* We must be careful here that we don't return more than the
1481 allowed number of data bytes. If this means returning fewer than
1482 maxentries then so be it. We assume that the redirector has
1483 enough room for the fixed number of parameter bytes it has
1485 char *params = *pparams;
1486 char *pdata = *ppdata;
1487 int dirtype = SVAL(params,0);
1488 int maxentries = SVAL(params,2);
1489 uint16 findfirst_flags = SVAL(params,4);
1490 BOOL close_after_first = (findfirst_flags & FLAG_TRANS2_FIND_CLOSE);
1491 BOOL close_if_end = (findfirst_flags & FLAG_TRANS2_FIND_CLOSE_IF_END);
1492 BOOL requires_resume_key = (findfirst_flags & FLAG_TRANS2_FIND_REQUIRE_RESUME);
1493 int info_level = SVAL(params,6);
1497 int last_entry_off=0;
1501 BOOL finished = False;
1502 BOOL dont_descend = False;
1503 BOOL out_of_space = False;
1504 int space_remaining;
1505 BOOL bad_path = False;
1506 SMB_STRUCT_STAT sbuf;
1507 TALLOC_CTX *ea_ctx = NULL;
1508 struct ea_list *ea_list = NULL;
1509 NTSTATUS ntstatus = NT_STATUS_OK;
1511 if (total_params < 12) {
1512 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
1515 *directory = *mask = 0;
1517 DEBUG(3,("call_trans2findfirst: dirtype = %d, maxentries = %d, close_after_first=%d, \
1518 close_if_end = %d requires_resume_key = %d level = 0x%x, max_data_bytes = %d\n",
1519 dirtype, maxentries, close_after_first, close_if_end, requires_resume_key,
1520 info_level, max_data_bytes));
1523 /* W2K3 seems to treat zero as 1. */
1527 switch (info_level) {
1528 case SMB_FIND_INFO_STANDARD:
1529 case SMB_FIND_EA_SIZE:
1530 case SMB_FIND_EA_LIST:
1531 case SMB_FIND_FILE_DIRECTORY_INFO:
1532 case SMB_FIND_FILE_FULL_DIRECTORY_INFO:
1533 case SMB_FIND_FILE_NAMES_INFO:
1534 case SMB_FIND_FILE_BOTH_DIRECTORY_INFO:
1535 case SMB_FIND_ID_FULL_DIRECTORY_INFO:
1536 case SMB_FIND_ID_BOTH_DIRECTORY_INFO:
1538 case SMB_FIND_FILE_UNIX:
1539 if (!lp_unix_extensions())
1540 return(ERROR_DOS(ERRDOS,ERRunknownlevel));
1543 return(ERROR_DOS(ERRDOS,ERRunknownlevel));
1546 srvstr_get_path(inbuf, directory, params+12, sizeof(directory), -1, STR_TERMINATE, &ntstatus, True);
1547 if (!NT_STATUS_IS_OK(ntstatus)) {
1548 return ERROR_NT(ntstatus);
1551 RESOLVE_DFSPATH(directory, conn, inbuf, outbuf);
1553 unix_convert(directory,conn,0,&bad_path,&sbuf);
1555 return ERROR_NT(NT_STATUS_OBJECT_PATH_NOT_FOUND);
1557 if(!check_name(directory,conn)) {
1558 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRbadpath);
1561 p = strrchr_m(directory,'/');
1563 /* Windows and OS/2 systems treat search on the root '\' as if it were '\*' */
1564 if((directory[0] == '.') && (directory[1] == '\0'))
1567 pstrcpy(mask,directory);
1568 pstrcpy(directory,"./");
1574 DEBUG(5,("dir=%s, mask = %s\n",directory, mask));
1576 if (info_level == SMB_FIND_EA_LIST) {
1579 if (total_data < 4) {
1580 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
1583 ea_size = IVAL(pdata,0);
1584 if (ea_size != total_data) {
1585 DEBUG(4,("call_trans2findfirst: Rejecting EA request with incorrect \
1586 total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pdata,0) ));
1587 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
1590 if (!lp_ea_support(SNUM(conn))) {
1591 return ERROR_DOS(ERRDOS,ERReasnotsupported);
1594 if ((ea_ctx = talloc_init("findnext_ea_list")) == NULL) {
1595 return ERROR_NT(NT_STATUS_NO_MEMORY);
1598 /* Pull out the list of names. */
1599 ea_list = read_ea_name_list(ea_ctx, pdata, ea_size);
1601 talloc_destroy(ea_ctx);
1602 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
1606 pdata = SMB_REALLOC(*ppdata, max_data_bytes + DIR_ENTRY_SAFETY_MARGIN);
1607 if( pdata == NULL ) {
1608 talloc_destroy(ea_ctx);
1609 return ERROR_NT(NT_STATUS_NO_MEMORY);
1613 memset((char *)pdata,'\0',max_data_bytes + DIR_ENTRY_SAFETY_MARGIN);
1615 /* Realloc the params space */
1616 params = SMB_REALLOC(*pparams, 10);
1617 if (params == NULL) {
1618 talloc_destroy(ea_ctx);
1619 return ERROR_NT(NT_STATUS_NO_MEMORY);
1623 dptr_num = dptr_create(conn,directory, False, True ,SVAL(inbuf,smb_pid));
1625 talloc_destroy(ea_ctx);
1626 return(UNIXERROR(ERRDOS,ERRbadfile));
1629 /* Save the wildcard match and attribs we are using on this directory -
1630 needed as lanman2 assumes these are being saved between calls */
1632 if (!dptr_set_wcard_and_attributes(dptr_num, mask, dirtype)) {
1633 dptr_close(&dptr_num);
1634 talloc_destroy(ea_ctx);
1635 return ERROR_NT(NT_STATUS_NO_MEMORY);
1638 DEBUG(4,("dptr_num is %d, wcard = %s, attr = %d\n",dptr_num, mask, dirtype));
1640 /* We don't need to check for VOL here as this is returned by
1641 a different TRANS2 call. */
1643 DEBUG(8,("dirpath=<%s> dontdescend=<%s>\n", conn->dirpath,lp_dontdescend(SNUM(conn))));
1644 if (in_list(conn->dirpath,lp_dontdescend(SNUM(conn)),conn->case_sensitive))
1645 dont_descend = True;
1648 space_remaining = max_data_bytes;
1649 out_of_space = False;
1651 for (i=0;(i<maxentries) && !finished && !out_of_space;i++) {
1652 BOOL got_exact_match = False;
1654 /* this is a heuristic to avoid seeking the dirptr except when
1655 absolutely necessary. It allows for a filename of about 40 chars */
1656 if (space_remaining < DIRLEN_GUESS && numentries > 0) {
1657 out_of_space = True;
1660 finished = !get_lanman2_dir_entry(conn,
1662 mask,dirtype,info_level,
1663 requires_resume_key,dont_descend,
1664 &p,pdata,space_remaining, &out_of_space, &got_exact_match,
1665 &last_entry_off, ea_list, ea_ctx);
1668 if (finished && out_of_space)
1671 if (!finished && !out_of_space)
1675 * As an optimisation if we know we aren't looking
1676 * for a wildcard name (ie. the name matches the wildcard exactly)
1677 * then we can finish on any (first) match.
1678 * This speeds up large directory searches. JRA.
1684 space_remaining = max_data_bytes - PTR_DIFF(p,pdata);
1687 talloc_destroy(ea_ctx);
1689 /* Check if we can close the dirptr */
1690 if(close_after_first || (finished && close_if_end)) {
1691 DEBUG(5,("call_trans2findfirst - (2) closing dptr_num %d\n", dptr_num));
1692 dptr_close(&dptr_num);
1696 * If there are no matching entries we must return ERRDOS/ERRbadfile -
1697 * from observation of NT. NB. This changes to ERRDOS,ERRnofiles if
1698 * the protocol level is less than NT1. Tested with smbclient. JRA.
1699 * This should fix the OS/2 client bug #2335.
1702 if(numentries == 0) {
1703 dptr_close(&dptr_num);
1704 if (Protocol < PROTOCOL_NT1) {
1705 return ERROR_DOS(ERRDOS,ERRnofiles);
1707 return ERROR_BOTH(NT_STATUS_NO_SUCH_FILE,ERRDOS,ERRbadfile);
1711 /* At this point pdata points to numentries directory entries. */
1713 /* Set up the return parameter block */
1714 SSVAL(params,0,dptr_num);
1715 SSVAL(params,2,numentries);
1716 SSVAL(params,4,finished);
1717 SSVAL(params,6,0); /* Never an EA error */
1718 SSVAL(params,8,last_entry_off);
1720 send_trans2_replies( outbuf, bufsize, params, 10, pdata, PTR_DIFF(p,pdata));
1722 if ((! *directory) && dptr_path(dptr_num))
1723 slprintf(directory,sizeof(directory)-1, "(%s)",dptr_path(dptr_num));
1725 DEBUG( 4, ( "%s mask=%s directory=%s dirtype=%d numentries=%d\n",
1726 smb_fn_name(CVAL(inbuf,smb_com)),
1727 mask, directory, dirtype, numentries ) );
1730 * Force a name mangle here to ensure that the
1731 * mask as an 8.3 name is top of the mangled cache.
1732 * The reasons for this are subtle. Don't remove
1733 * this code unless you know what you are doing
1734 * (see PR#13758). JRA.
1737 if(!mangle_is_8_3_wildcards( mask, False))
1738 mangle_map(mask, True, True, SNUM(conn));
1743 /****************************************************************************
1744 Reply to a TRANS2_FINDNEXT.
1745 ****************************************************************************/
1747 static int call_trans2findnext(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize,
1748 char **pparams, int total_params, char **ppdata, int total_data,
1749 unsigned int max_data_bytes)
1751 /* We must be careful here that we don't return more than the
1752 allowed number of data bytes. If this means returning fewer than
1753 maxentries then so be it. We assume that the redirector has
1754 enough room for the fixed number of parameter bytes it has
1756 char *params = *pparams;
1757 char *pdata = *ppdata;
1758 int dptr_num = SVAL(params,0);
1759 int maxentries = SVAL(params,2);
1760 uint16 info_level = SVAL(params,4);
1761 uint32 resume_key = IVAL(params,6);
1762 uint16 findnext_flags = SVAL(params,10);
1763 BOOL close_after_request = (findnext_flags & FLAG_TRANS2_FIND_CLOSE);
1764 BOOL close_if_end = (findnext_flags & FLAG_TRANS2_FIND_CLOSE_IF_END);
1765 BOOL requires_resume_key = (findnext_flags & FLAG_TRANS2_FIND_REQUIRE_RESUME);
1766 BOOL continue_bit = (findnext_flags & FLAG_TRANS2_FIND_CONTINUE);
1767 pstring resume_name;
1773 int i, last_entry_off=0;
1774 BOOL finished = False;
1775 BOOL dont_descend = False;
1776 BOOL out_of_space = False;
1777 int space_remaining;
1778 TALLOC_CTX *ea_ctx = NULL;
1779 struct ea_list *ea_list = NULL;
1780 NTSTATUS ntstatus = NT_STATUS_OK;
1782 if (total_params < 12) {
1783 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
1786 *mask = *directory = *resume_name = 0;
1788 srvstr_get_path(inbuf, resume_name, params+12, sizeof(resume_name), -1, STR_TERMINATE, &ntstatus, True);
1789 if (!NT_STATUS_IS_OK(ntstatus)) {
1790 /* Win9x or OS/2 can send a resume name of ".." or ".". This will cause the parser to
1791 complain (it thinks we're asking for the directory above the shared
1792 path or an invalid name). Catch this as the resume name is only compared, never used in
1793 a file access. JRA. */
1794 if (NT_STATUS_EQUAL(ntstatus,NT_STATUS_OBJECT_PATH_SYNTAX_BAD)) {
1795 pstrcpy(resume_name, "..");
1796 } else if (NT_STATUS_EQUAL(ntstatus,NT_STATUS_OBJECT_NAME_INVALID)) {
1797 pstrcpy(resume_name, ".");
1799 return ERROR_NT(ntstatus);
1803 DEBUG(3,("call_trans2findnext: dirhandle = %d, max_data_bytes = %d, maxentries = %d, \
1804 close_after_request=%d, close_if_end = %d requires_resume_key = %d \
1805 resume_key = %d resume name = %s continue=%d level = %d\n",
1806 dptr_num, max_data_bytes, maxentries, close_after_request, close_if_end,
1807 requires_resume_key, resume_key, resume_name, continue_bit, info_level));
1810 /* W2K3 seems to treat zero as 1. */
1814 switch (info_level) {
1815 case SMB_FIND_INFO_STANDARD:
1816 case SMB_FIND_EA_SIZE:
1817 case SMB_FIND_EA_LIST:
1818 case SMB_FIND_FILE_DIRECTORY_INFO:
1819 case SMB_FIND_FILE_FULL_DIRECTORY_INFO:
1820 case SMB_FIND_FILE_NAMES_INFO:
1821 case SMB_FIND_FILE_BOTH_DIRECTORY_INFO:
1823 case SMB_FIND_FILE_UNIX:
1824 if (!lp_unix_extensions())
1825 return(ERROR_DOS(ERRDOS,ERRunknownlevel));
1828 return ERROR_DOS(ERRDOS,ERRunknownlevel);
1831 if (info_level == SMB_FIND_EA_LIST) {
1834 if (total_data < 4) {
1835 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
1838 ea_size = IVAL(pdata,0);
1839 if (ea_size != total_data) {
1840 DEBUG(4,("call_trans2findnext: Rejecting EA request with incorrect \
1841 total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pdata,0) ));
1842 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
1845 if (!lp_ea_support(SNUM(conn))) {
1846 return ERROR_DOS(ERRDOS,ERReasnotsupported);
1849 if ((ea_ctx = talloc_init("findnext_ea_list")) == NULL) {
1850 return ERROR_NT(NT_STATUS_NO_MEMORY);
1853 /* Pull out the list of names. */
1854 ea_list = read_ea_name_list(ea_ctx, pdata, ea_size);
1856 talloc_destroy(ea_ctx);
1857 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
1861 pdata = SMB_REALLOC( *ppdata, max_data_bytes + DIR_ENTRY_SAFETY_MARGIN);
1863 talloc_destroy(ea_ctx);
1864 return ERROR_NT(NT_STATUS_NO_MEMORY);
1868 memset((char *)pdata,'\0',max_data_bytes + DIR_ENTRY_SAFETY_MARGIN);
1870 /* Realloc the params space */
1871 params = SMB_REALLOC(*pparams, 6*SIZEOFWORD);
1872 if( params == NULL ) {
1873 talloc_destroy(ea_ctx);
1874 return ERROR_NT(NT_STATUS_NO_MEMORY);
1879 /* Check that the dptr is valid */
1880 if(!(conn->dirptr = dptr_fetch_lanman2(dptr_num))) {
1881 talloc_destroy(ea_ctx);
1882 return ERROR_DOS(ERRDOS,ERRnofiles);
1885 string_set(&conn->dirpath,dptr_path(dptr_num));
1887 /* Get the wildcard mask from the dptr */
1888 if((p = dptr_wcard(dptr_num))== NULL) {
1889 DEBUG(2,("dptr_num %d has no wildcard\n", dptr_num));
1890 talloc_destroy(ea_ctx);
1891 return ERROR_DOS(ERRDOS,ERRnofiles);
1895 pstrcpy(directory,conn->dirpath);
1897 /* Get the attr mask from the dptr */
1898 dirtype = dptr_attr(dptr_num);
1900 DEBUG(3,("dptr_num is %d, mask = %s, attr = %x, dirptr=(0x%lX,%ld)\n",
1901 dptr_num, mask, dirtype,
1903 dptr_TellDir(conn->dirptr)));
1905 /* We don't need to check for VOL here as this is returned by
1906 a different TRANS2 call. */
1908 DEBUG(8,("dirpath=<%s> dontdescend=<%s>\n",conn->dirpath,lp_dontdescend(SNUM(conn))));
1909 if (in_list(conn->dirpath,lp_dontdescend(SNUM(conn)),conn->case_sensitive))
1910 dont_descend = True;
1913 space_remaining = max_data_bytes;
1914 out_of_space = False;
1917 * Seek to the correct position. We no longer use the resume key but
1918 * depend on the last file name instead.
1921 if(*resume_name && !continue_bit) {
1924 long current_pos = 0;
1926 * Remember, mangle_map is called by
1927 * get_lanman2_dir_entry(), so the resume name
1928 * could be mangled. Ensure we check the unmangled name.
1931 if (mangle_is_mangled(resume_name)) {
1932 mangle_check_cache(resume_name, sizeof(resume_name)-1);
1936 * Fix for NT redirector problem triggered by resume key indexes
1937 * changing between directory scans. We now return a resume key of 0
1938 * and instead look for the filename to continue from (also given
1939 * to us by NT/95/smbfs/smbclient). If no other scans have been done between the
1940 * findfirst/findnext (as is usual) then the directory pointer
1941 * should already be at the correct place.
1944 finished = !dptr_SearchDir(conn->dirptr, resume_name, ¤t_pos, &st);
1945 } /* end if resume_name && !continue_bit */
1947 for (i=0;(i<(int)maxentries) && !finished && !out_of_space ;i++) {
1948 BOOL got_exact_match = False;
1950 /* this is a heuristic to avoid seeking the dirptr except when
1951 absolutely necessary. It allows for a filename of about 40 chars */
1952 if (space_remaining < DIRLEN_GUESS && numentries > 0) {
1953 out_of_space = True;
1956 finished = !get_lanman2_dir_entry(conn,
1958 mask,dirtype,info_level,
1959 requires_resume_key,dont_descend,
1960 &p,pdata,space_remaining, &out_of_space, &got_exact_match,
1961 &last_entry_off, ea_list, ea_ctx);
1964 if (finished && out_of_space)
1967 if (!finished && !out_of_space)
1971 * As an optimisation if we know we aren't looking
1972 * for a wildcard name (ie. the name matches the wildcard exactly)
1973 * then we can finish on any (first) match.
1974 * This speeds up large directory searches. JRA.
1980 space_remaining = max_data_bytes - PTR_DIFF(p,pdata);
1983 talloc_destroy(ea_ctx);
1985 /* Check if we can close the dirptr */
1986 if(close_after_request || (finished && close_if_end)) {
1987 DEBUG(5,("call_trans2findnext: closing dptr_num = %d\n", dptr_num));
1988 dptr_close(&dptr_num); /* This frees up the saved mask */
1991 /* Set up the return parameter block */
1992 SSVAL(params,0,numentries);
1993 SSVAL(params,2,finished);
1994 SSVAL(params,4,0); /* Never an EA error */
1995 SSVAL(params,6,last_entry_off);
1997 send_trans2_replies( outbuf, bufsize, params, 8, pdata, PTR_DIFF(p,pdata));
1999 if ((! *directory) && dptr_path(dptr_num))
2000 slprintf(directory,sizeof(directory)-1, "(%s)",dptr_path(dptr_num));
2002 DEBUG( 3, ( "%s mask=%s directory=%s dirtype=%d numentries=%d\n",
2003 smb_fn_name(CVAL(inbuf,smb_com)),
2004 mask, directory, dirtype, numentries ) );
2009 /****************************************************************************
2010 Reply to a TRANS2_QFSINFO (query filesystem info).
2011 ****************************************************************************/
2013 static int call_trans2qfsinfo(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize,
2014 char **pparams, int total_params, char **ppdata, int total_data,
2015 unsigned int max_data_bytes)
2017 char *pdata = *ppdata;
2018 char *params = *pparams;
2019 uint16 info_level = SVAL(params,0);
2022 char *vname = volume_label(SNUM(conn));
2023 int snum = SNUM(conn);
2024 char *fstype = lp_fstype(SNUM(conn));
2027 DEBUG(3,("call_trans2qfsinfo: level = %d\n", info_level));
2029 if(SMB_VFS_STAT(conn,".",&st)!=0) {
2030 DEBUG(2,("call_trans2qfsinfo: stat of . failed (%s)\n", strerror(errno)));
2031 return ERROR_DOS(ERRSRV,ERRinvdevice);
2034 pdata = SMB_REALLOC(*ppdata, max_data_bytes + DIR_ENTRY_SAFETY_MARGIN);
2035 if ( pdata == NULL ) {
2036 return ERROR_NT(NT_STATUS_NO_MEMORY);
2040 memset((char *)pdata,'\0',max_data_bytes + DIR_ENTRY_SAFETY_MARGIN);
2042 switch (info_level) {
2043 case SMB_INFO_ALLOCATION:
2045 SMB_BIG_UINT dfree,dsize,bsize,block_size,sectors_per_unit,bytes_per_sector;
2047 if (SMB_VFS_DISK_FREE(conn,".",False,&bsize,&dfree,&dsize) == (SMB_BIG_UINT)-1) {
2048 return(UNIXERROR(ERRHRD,ERRgeneral));
2051 block_size = lp_block_size(snum);
2052 if (bsize < block_size) {
2053 SMB_BIG_UINT factor = block_size/bsize;
2058 if (bsize > block_size) {
2059 SMB_BIG_UINT factor = bsize/block_size;
2064 bytes_per_sector = 512;
2065 sectors_per_unit = bsize/bytes_per_sector;
2067 DEBUG(5,("call_trans2qfsinfo : SMB_INFO_ALLOCATION id=%x, bsize=%u, cSectorUnit=%u, \
2068 cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)st.st_dev, (unsigned int)bsize, (unsigned int)sectors_per_unit,
2069 (unsigned int)bytes_per_sector, (unsigned int)dsize, (unsigned int)dfree));
2071 SIVAL(pdata,l1_idFileSystem,st.st_dev);
2072 SIVAL(pdata,l1_cSectorUnit,sectors_per_unit);
2073 SIVAL(pdata,l1_cUnit,dsize);
2074 SIVAL(pdata,l1_cUnitAvail,dfree);
2075 SSVAL(pdata,l1_cbSector,bytes_per_sector);
2079 case SMB_INFO_VOLUME:
2080 /* Return volume name */
2082 * Add volume serial number - hash of a combination of
2083 * the called hostname and the service name.
2085 SIVAL(pdata,0,str_checksum(lp_servicename(snum)) ^ (str_checksum(get_local_machine_name())<<16) );
2086 len = srvstr_push(outbuf, pdata+l2_vol_szVolLabel, vname, -1, STR_NOALIGN);
2087 SCVAL(pdata,l2_vol_cch,len);
2088 data_len = l2_vol_szVolLabel + len;
2089 DEBUG(5,("call_trans2qfsinfo : time = %x, namelen = %d, name = %s\n",
2090 (unsigned)st.st_ctime, len, vname));
2093 case SMB_QUERY_FS_ATTRIBUTE_INFO:
2094 case SMB_FS_ATTRIBUTE_INFORMATION:
2097 #if defined(HAVE_SYS_QUOTAS)
2098 quota_flag = FILE_VOLUME_QUOTAS;
2101 SIVAL(pdata,0,FILE_CASE_PRESERVED_NAMES|FILE_CASE_SENSITIVE_SEARCH|
2102 (lp_nt_acl_support(SNUM(conn)) ? FILE_PERSISTENT_ACLS : 0)|
2103 quota_flag); /* FS ATTRIBUTES */
2105 SIVAL(pdata,4,255); /* Max filename component length */
2106 /* NOTE! the fstype must *not* be null terminated or win98 won't recognise it
2107 and will think we can't do long filenames */
2108 len = srvstr_push(outbuf, pdata+12, fstype, -1, STR_UNICODE);
2110 data_len = 12 + len;
2113 case SMB_QUERY_FS_LABEL_INFO:
2114 case SMB_FS_LABEL_INFORMATION:
2115 len = srvstr_push(outbuf, pdata+4, vname, -1, 0);
2120 case SMB_QUERY_FS_VOLUME_INFO:
2121 case SMB_FS_VOLUME_INFORMATION:
2124 * Add volume serial number - hash of a combination of
2125 * the called hostname and the service name.
2127 SIVAL(pdata,8,str_checksum(lp_servicename(snum)) ^
2128 (str_checksum(get_local_machine_name())<<16));
2130 len = srvstr_push(outbuf, pdata+18, vname, -1, STR_UNICODE);
2131 SIVAL(pdata,12,len);
2133 DEBUG(5,("call_trans2qfsinfo : SMB_QUERY_FS_VOLUME_INFO namelen = %d, vol=%s serv=%s\n",
2134 (int)strlen(vname),vname, lp_servicename(snum)));
2137 case SMB_QUERY_FS_SIZE_INFO:
2138 case SMB_FS_SIZE_INFORMATION:
2140 SMB_BIG_UINT dfree,dsize,bsize,block_size,sectors_per_unit,bytes_per_sector;
2142 if (SMB_VFS_DISK_FREE(conn,".",False,&bsize,&dfree,&dsize) == (SMB_BIG_UINT)-1) {
2143 return(UNIXERROR(ERRHRD,ERRgeneral));
2145 block_size = lp_block_size(snum);
2146 if (bsize < block_size) {
2147 SMB_BIG_UINT factor = block_size/bsize;
2152 if (bsize > block_size) {
2153 SMB_BIG_UINT factor = bsize/block_size;
2158 bytes_per_sector = 512;
2159 sectors_per_unit = bsize/bytes_per_sector;
2160 DEBUG(5,("call_trans2qfsinfo : SMB_QUERY_FS_SIZE_INFO bsize=%u, cSectorUnit=%u, \
2161 cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize, (unsigned int)sectors_per_unit,
2162 (unsigned int)bytes_per_sector, (unsigned int)dsize, (unsigned int)dfree));
2163 SBIG_UINT(pdata,0,dsize);
2164 SBIG_UINT(pdata,8,dfree);
2165 SIVAL(pdata,16,sectors_per_unit);
2166 SIVAL(pdata,20,bytes_per_sector);
2170 case SMB_FS_FULL_SIZE_INFORMATION:
2172 SMB_BIG_UINT dfree,dsize,bsize,block_size,sectors_per_unit,bytes_per_sector;
2174 if (SMB_VFS_DISK_FREE(conn,".",False,&bsize,&dfree,&dsize) == (SMB_BIG_UINT)-1) {
2175 return(UNIXERROR(ERRHRD,ERRgeneral));
2177 block_size = lp_block_size(snum);
2178 if (bsize < block_size) {
2179 SMB_BIG_UINT factor = block_size/bsize;
2184 if (bsize > block_size) {
2185 SMB_BIG_UINT factor = bsize/block_size;
2190 bytes_per_sector = 512;
2191 sectors_per_unit = bsize/bytes_per_sector;
2192 DEBUG(5,("call_trans2qfsinfo : SMB_QUERY_FS_FULL_SIZE_INFO bsize=%u, cSectorUnit=%u, \
2193 cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize, (unsigned int)sectors_per_unit,
2194 (unsigned int)bytes_per_sector, (unsigned int)dsize, (unsigned int)dfree));
2195 SBIG_UINT(pdata,0,dsize); /* Total Allocation units. */
2196 SBIG_UINT(pdata,8,dfree); /* Caller available allocation units. */
2197 SBIG_UINT(pdata,16,dfree); /* Actual available allocation units. */
2198 SIVAL(pdata,24,sectors_per_unit); /* Sectors per allocation unit. */
2199 SIVAL(pdata,28,bytes_per_sector); /* Bytes per sector. */
2203 case SMB_QUERY_FS_DEVICE_INFO:
2204 case SMB_FS_DEVICE_INFORMATION:
2206 SIVAL(pdata,0,0); /* dev type */
2207 SIVAL(pdata,4,0); /* characteristics */
2210 #ifdef HAVE_SYS_QUOTAS
2211 case SMB_FS_QUOTA_INFORMATION:
2213 * what we have to send --metze:
2215 * Unknown1: 24 NULL bytes
2216 * Soft Quota Treshold: 8 bytes seems like SMB_BIG_UINT or so
2217 * Hard Quota Limit: 8 bytes seems like SMB_BIG_UINT or so
2218 * Quota Flags: 2 byte :
2219 * Unknown3: 6 NULL bytes
2223 * details for Quota Flags:
2225 * 0x0020 Log Limit: log if the user exceeds his Hard Quota
2226 * 0x0010 Log Warn: log if the user exceeds his Soft Quota
2227 * 0x0002 Deny Disk: deny disk access when the user exceeds his Hard Quota
2228 * 0x0001 Enable Quotas: enable quota for this fs
2232 /* we need to fake up a fsp here,
2233 * because its not send in this call
2236 SMB_NTQUOTA_STRUCT quotas;
2239 ZERO_STRUCT(quotas);
2246 if (current_user.uid != 0) {
2247 DEBUG(0,("set_user_quota: access_denied service [%s] user [%s]\n",
2248 lp_servicename(SNUM(conn)),conn->user));
2249 return ERROR_DOS(ERRDOS,ERRnoaccess);
2252 if (vfs_get_ntquota(&fsp, SMB_USER_FS_QUOTA_TYPE, NULL, "as)!=0) {
2253 DEBUG(0,("vfs_get_ntquota() failed for service [%s]\n",lp_servicename(SNUM(conn))));
2254 return ERROR_DOS(ERRSRV,ERRerror);
2259 DEBUG(10,("SMB_FS_QUOTA_INFORMATION: for service [%s]\n",lp_servicename(SNUM(conn))));
2261 /* Unknown1 24 NULL bytes*/
2262 SBIG_UINT(pdata,0,(SMB_BIG_UINT)0);
2263 SBIG_UINT(pdata,8,(SMB_BIG_UINT)0);
2264 SBIG_UINT(pdata,16,(SMB_BIG_UINT)0);
2266 /* Default Soft Quota 8 bytes */
2267 SBIG_UINT(pdata,24,quotas.softlim);
2269 /* Default Hard Quota 8 bytes */
2270 SBIG_UINT(pdata,32,quotas.hardlim);
2272 /* Quota flag 2 bytes */
2273 SSVAL(pdata,40,quotas.qflags);
2275 /* Unknown3 6 NULL bytes */
2281 #endif /* HAVE_SYS_QUOTAS */
2282 case SMB_FS_OBJECTID_INFORMATION:
2287 * Query the version and capabilities of the CIFS UNIX extensions
2291 case SMB_QUERY_CIFS_UNIX_INFO:
2292 if (!lp_unix_extensions())
2293 return ERROR_DOS(ERRDOS,ERRunknownlevel);
2295 SSVAL(pdata,0,CIFS_UNIX_MAJOR_VERSION);
2296 SSVAL(pdata,2,CIFS_UNIX_MINOR_VERSION);
2297 SBIG_UINT(pdata,4,((SMB_BIG_UINT)CIFS_UNIX_POSIX_ACLS_CAP)); /* We have POSIX ACLs. */
2300 case SMB_MAC_QUERY_FS_INFO:
2302 * Thursby MAC extension... ONLY on NTFS filesystems
2303 * once we do streams then we don't need this
2305 if (strequal(lp_fstype(SNUM(conn)),"NTFS")) {
2307 SIVAL(pdata,84,0x100); /* Don't support mac... */
2312 return ERROR_DOS(ERRDOS,ERRunknownlevel);
2316 send_trans2_replies( outbuf, bufsize, params, 0, pdata, data_len);
2318 DEBUG( 4, ( "%s info_level = %d\n", smb_fn_name(CVAL(inbuf,smb_com)), info_level) );
2323 #ifdef HAVE_SYS_QUOTAS
2324 /****************************************************************************
2325 Reply to a TRANS2_SETFSINFO (set filesystem info).
2326 ****************************************************************************/
2328 static int call_trans2setfsinfo(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize,
2329 char **pparams, int total_params, char **ppdata, int total_data,
2330 unsigned int max_data_bytes)
2332 char *pdata = *ppdata;
2333 char *params = *pparams;
2334 files_struct *fsp = NULL;
2337 SMB_NTQUOTA_STRUCT quotas;
2339 ZERO_STRUCT(quotas);
2341 DEBUG(10,("call_trans2setfsinfo: SET_FS_QUOTA: for service [%s]\n",lp_servicename(SNUM(conn))));
2344 if ((current_user.uid != 0)||!CAN_WRITE(conn)) {
2345 DEBUG(0,("set_user_quota: access_denied service [%s] user [%s]\n",
2346 lp_servicename(SNUM(conn)),conn->user));
2347 return ERROR_DOS(ERRSRV,ERRaccess);
2351 if (total_params < 4) {
2352 DEBUG(0,("call_trans2setfsinfo: requires total_params(%d) >= 4 bytes!\n",
2354 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
2357 fsp = file_fsp(params,0);
2359 if (!CHECK_NTQUOTA_HANDLE_OK(fsp,conn)) {
2360 DEBUG(3,("TRANSACT_GET_USER_QUOTA: no valid QUOTA HANDLE\n"));
2361 return ERROR_NT(NT_STATUS_INVALID_HANDLE);
2364 info_level = SVAL(params,2);
2366 switch(info_level) {
2367 case SMB_FS_QUOTA_INFORMATION:
2368 /* note: normaly there're 48 bytes,
2369 * but we didn't use the last 6 bytes for now
2372 if (total_data < 42) {
2373 DEBUG(0,("call_trans2setfsinfo: SET_FS_QUOTA: requires total_data(%d) >= 42 bytes!\n",
2375 return ERROR_DOS(ERRDOS,ERRunknownlevel);
2378 /* unknown_1 24 NULL bytes in pdata*/
2380 /* the soft quotas 8 bytes (SMB_BIG_UINT)*/
2381 quotas.softlim = (SMB_BIG_UINT)IVAL(pdata,24);
2382 #ifdef LARGE_SMB_OFF_T
2383 quotas.softlim |= (((SMB_BIG_UINT)IVAL(pdata,28)) << 32);
2384 #else /* LARGE_SMB_OFF_T */
2385 if ((IVAL(pdata,28) != 0)&&
2386 ((quotas.softlim != 0xFFFFFFFF)||
2387 (IVAL(pdata,28)!=0xFFFFFFFF))) {
2388 /* more than 32 bits? */
2389 return ERROR_DOS(ERRDOS,ERRunknownlevel);
2391 #endif /* LARGE_SMB_OFF_T */
2393 /* the hard quotas 8 bytes (SMB_BIG_UINT)*/
2394 quotas.hardlim = (SMB_BIG_UINT)IVAL(pdata,32);
2395 #ifdef LARGE_SMB_OFF_T
2396 quotas.hardlim |= (((SMB_BIG_UINT)IVAL(pdata,36)) << 32);
2397 #else /* LARGE_SMB_OFF_T */
2398 if ((IVAL(pdata,36) != 0)&&
2399 ((quotas.hardlim != 0xFFFFFFFF)||
2400 (IVAL(pdata,36)!=0xFFFFFFFF))) {
2401 /* more than 32 bits? */
2402 return ERROR_DOS(ERRDOS,ERRunknownlevel);
2404 #endif /* LARGE_SMB_OFF_T */
2406 /* quota_flags 2 bytes **/
2407 quotas.qflags = SVAL(pdata,40);
2409 /* unknown_2 6 NULL bytes follow*/
2411 /* now set the quotas */
2412 if (vfs_set_ntquota(fsp, SMB_USER_FS_QUOTA_TYPE, NULL, "as)!=0) {
2413 DEBUG(0,("vfs_set_ntquota() failed for service [%s]\n",lp_servicename(SNUM(conn))));
2414 return ERROR_DOS(ERRSRV,ERRerror);
2419 DEBUG(3,("call_trans2setfsinfo: unknown level (0x%X) not implemented yet.\n",
2421 return ERROR_DOS(ERRDOS,ERRunknownlevel);
2426 * sending this reply works fine,
2427 * but I'm not sure it's the same
2428 * like windows do...
2431 outsize = set_message(outbuf,10,0,True);
2435 #endif /* HAVE_SYS_QUOTAS */
2437 /****************************************************************************
2438 Utility function to set bad path error.
2439 ****************************************************************************/
2441 int set_bad_path_error(int err, BOOL bad_path, char *outbuf, int def_class, uint32 def_code)
2443 DEBUG(10,("set_bad_path_error: err = %d bad_path = %d\n",
2444 err, (int)bad_path ));
2448 return ERROR_NT(NT_STATUS_OBJECT_PATH_NOT_FOUND);
2450 return ERROR_NT(NT_STATUS_OBJECT_NAME_NOT_FOUND);
2453 return UNIXERROR(def_class,def_code);
2456 #if defined(HAVE_POSIX_ACLS)
2457 /****************************************************************************
2458 Utility function to count the number of entries in a POSIX acl.
2459 ****************************************************************************/
2461 static unsigned int count_acl_entries(connection_struct *conn, SMB_ACL_T posix_acl)
2463 unsigned int ace_count = 0;
2464 int entry_id = SMB_ACL_FIRST_ENTRY;
2465 SMB_ACL_ENTRY_T entry;
2467 while ( posix_acl && (SMB_VFS_SYS_ACL_GET_ENTRY(conn, posix_acl, entry_id, &entry) == 1)) {
2469 if (entry_id == SMB_ACL_FIRST_ENTRY) {
2470 entry_id = SMB_ACL_NEXT_ENTRY;
2477 /****************************************************************************
2478 Utility function to marshall a POSIX acl into wire format.
2479 ****************************************************************************/
2481 static BOOL marshall_posix_acl(connection_struct *conn, char *pdata, SMB_STRUCT_STAT *pst, SMB_ACL_T posix_acl)
2483 int entry_id = SMB_ACL_FIRST_ENTRY;
2484 SMB_ACL_ENTRY_T entry;
2486 while ( posix_acl && (SMB_VFS_SYS_ACL_GET_ENTRY(conn, posix_acl, entry_id, &entry) == 1)) {
2487 SMB_ACL_TAG_T tagtype;
2488 SMB_ACL_PERMSET_T permset;
2489 unsigned char perms = 0;
2490 unsigned int own_grp;
2493 if (entry_id == SMB_ACL_FIRST_ENTRY) {
2494 entry_id = SMB_ACL_NEXT_ENTRY;
2497 if (SMB_VFS_SYS_ACL_GET_TAG_TYPE(conn, entry, &tagtype) == -1) {
2498 DEBUG(0,("marshall_posix_acl: SMB_VFS_SYS_ACL_GET_TAG_TYPE failed.\n"));
2502 if (SMB_VFS_SYS_ACL_GET_PERMSET(conn, entry, &permset) == -1) {
2503 DEBUG(0,("marshall_posix_acl: SMB_VFS_SYS_ACL_GET_PERMSET failed.\n"));
2507 perms |= (SMB_VFS_SYS_ACL_GET_PERM(conn, permset, SMB_ACL_READ) ? SMB_POSIX_ACL_READ : 0);
2508 perms |= (SMB_VFS_SYS_ACL_GET_PERM(conn, permset, SMB_ACL_WRITE) ? SMB_POSIX_ACL_WRITE : 0);
2509 perms |= (SMB_VFS_SYS_ACL_GET_PERM(conn, permset, SMB_ACL_EXECUTE) ? SMB_POSIX_ACL_EXECUTE : 0);
2511 SCVAL(pdata,1,perms);
2514 case SMB_ACL_USER_OBJ:
2515 SCVAL(pdata,0,SMB_POSIX_ACL_USER_OBJ);
2516 own_grp = (unsigned int)pst->st_uid;
2517 SIVAL(pdata,2,own_grp);
2522 uid_t *puid = (uid_t *)SMB_VFS_SYS_ACL_GET_QUALIFIER(conn, entry);
2524 DEBUG(0,("marshall_posix_acl: SMB_VFS_SYS_ACL_GET_QUALIFIER failed.\n"));
2526 own_grp = (unsigned int)*puid;
2527 SMB_VFS_SYS_ACL_FREE_QUALIFIER(conn, (void *)puid,tagtype);
2528 SCVAL(pdata,0,SMB_POSIX_ACL_USER);
2529 SIVAL(pdata,2,own_grp);
2533 case SMB_ACL_GROUP_OBJ:
2534 SCVAL(pdata,0,SMB_POSIX_ACL_GROUP_OBJ);
2535 own_grp = (unsigned int)pst->st_gid;
2536 SIVAL(pdata,2,own_grp);
2541 gid_t *pgid= (gid_t *)SMB_VFS_SYS_ACL_GET_QUALIFIER(conn, entry);
2543 DEBUG(0,("marshall_posix_acl: SMB_VFS_SYS_ACL_GET_QUALIFIER failed.\n"));
2545 own_grp = (unsigned int)*pgid;
2546 SMB_VFS_SYS_ACL_FREE_QUALIFIER(conn, (void *)pgid,tagtype);
2547 SCVAL(pdata,0,SMB_POSIX_ACL_GROUP);
2548 SIVAL(pdata,2,own_grp);
2553 SCVAL(pdata,0,SMB_POSIX_ACL_MASK);
2554 SIVAL(pdata,2,0xFFFFFFFF);
2555 SIVAL(pdata,6,0xFFFFFFFF);
2558 SCVAL(pdata,0,SMB_POSIX_ACL_OTHER);
2559 SIVAL(pdata,2,0xFFFFFFFF);
2560 SIVAL(pdata,6,0xFFFFFFFF);
2563 DEBUG(0,("marshall_posix_acl: unknown tagtype.\n"));
2566 pdata += SMB_POSIX_ACL_ENTRY_SIZE;
2573 /****************************************************************************
2574 Reply to a TRANS2_QFILEPATHINFO or TRANSACT2_QFILEINFO (query file info by
2575 file name or file id).
2576 ****************************************************************************/
2578 static int call_trans2qfilepathinfo(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize,
2579 char **pparams, int total_params, char **ppdata, int total_data,
2580 unsigned int max_data_bytes)
2582 char *params = *pparams;
2583 char *pdata = *ppdata;
2584 uint16 tran_call = SVAL(inbuf, smb_setup0);
2587 SMB_OFF_T file_size=0;
2588 SMB_BIG_UINT allocation_size=0;
2589 unsigned int data_size = 0;
2590 unsigned int param_size = 2;
2591 SMB_STRUCT_STAT sbuf;
2592 pstring fname, dos_fname;
2597 BOOL bad_path = False;
2598 BOOL delete_pending = False;
2601 files_struct *fsp = NULL;
2602 TALLOC_CTX *ea_ctx = NULL;
2603 struct ea_list *ea_list = NULL;
2604 uint32 desired_access = 0x12019F; /* Default - GENERIC_EXECUTE mapping from Windows */
2607 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
2611 if (tran_call == TRANSACT2_QFILEINFO) {
2612 if (total_params < 4) {
2613 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
2616 fsp = file_fsp(params,0);
2617 info_level = SVAL(params,2);
2619 DEBUG(3,("call_trans2qfilepathinfo: TRANSACT2_QFILEINFO: level = %d\n", info_level));
2621 if(fsp && (fsp->fake_file_handle)) {
2623 * This is actually for the QUOTA_FAKE_FILE --metze
2626 pstrcpy(fname, fsp->fsp_name);
2627 /* We know this name is ok, it's already passed the checks. */
2629 } else if(fsp && (fsp->is_directory || fsp->fd == -1)) {
2631 * This is actually a QFILEINFO on a directory
2632 * handle (returned from an NT SMB). NT5.0 seems
2633 * to do this call. JRA.
2635 /* We know this name is ok, it's already passed the checks. */
2636 pstrcpy(fname, fsp->fsp_name);
2638 if (INFO_LEVEL_IS_UNIX(info_level)) {
2639 /* Always do lstat for UNIX calls. */
2640 if (SMB_VFS_LSTAT(conn,fname,&sbuf)) {
2641 DEBUG(3,("call_trans2qfilepathinfo: SMB_VFS_LSTAT of %s failed (%s)\n",fname,strerror(errno)));
2642 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRbadpath);
2644 } else if (SMB_VFS_STAT(conn,fname,&sbuf)) {
2645 DEBUG(3,("call_trans2qfilepathinfo: SMB_VFS_STAT of %s failed (%s)\n",fname,strerror(errno)));
2646 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRbadpath);
2649 delete_pending = fsp->is_directory ? fsp->directory_delete_on_close : 0;
2652 * Original code - this is an open file.
2654 CHECK_FSP(fsp,conn);
2656 pstrcpy(fname, fsp->fsp_name);
2657 if (SMB_VFS_FSTAT(fsp,fsp->fd,&sbuf) != 0) {
2658 DEBUG(3,("fstat of fnum %d failed (%s)\n", fsp->fnum, strerror(errno)));
2659 return(UNIXERROR(ERRDOS,ERRbadfid));
2661 pos = fsp->position_information;
2662 delete_pending = fsp->delete_on_close;
2663 desired_access = fsp->desired_access;
2666 NTSTATUS status = NT_STATUS_OK;
2669 if (total_params < 6) {
2670 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
2673 info_level = SVAL(params,0);
2675 DEBUG(3,("call_trans2qfilepathinfo: TRANSACT2_QPATHINFO: level = %d\n", info_level));
2677 srvstr_get_path(inbuf, fname, ¶ms[6], sizeof(fname), -1, STR_TERMINATE, &status, False);
2678 if (!NT_STATUS_IS_OK(status)) {
2679 return ERROR_NT(status);
2682 RESOLVE_DFSPATH(fname, conn, inbuf, outbuf);
2684 unix_convert(fname,conn,0,&bad_path,&sbuf);
2686 return ERROR_NT(NT_STATUS_OBJECT_PATH_NOT_FOUND);
2688 if (!check_name(fname,conn)) {
2689 DEBUG(3,("call_trans2qfilepathinfo: fileinfo of %s failed (%s)\n",fname,strerror(errno)));
2690 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRbadpath);
2693 if (INFO_LEVEL_IS_UNIX(info_level)) {
2694 /* Always do lstat for UNIX calls. */
2695 if (SMB_VFS_LSTAT(conn,fname,&sbuf)) {
2696 DEBUG(3,("call_trans2qfilepathinfo: SMB_VFS_LSTAT of %s failed (%s)\n",fname,strerror(errno)));
2697 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRbadpath);
2699 } else if (!VALID_STAT(sbuf) && SMB_VFS_STAT(conn,fname,&sbuf) && (info_level != SMB_INFO_IS_NAME_VALID)) {
2700 DEBUG(3,("call_trans2qfilepathinfo: SMB_VFS_STAT of %s failed (%s)\n",fname,strerror(errno)));
2701 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRbadpath);
2705 if (INFO_LEVEL_IS_UNIX(info_level) && !lp_unix_extensions())
2706 return ERROR_DOS(ERRDOS,ERRunknownlevel);
2708 DEBUG(3,("call_trans2qfilepathinfo %s (fnum = %d) level=%d call=%d total_data=%d\n",
2709 fname,fsp ? fsp->fnum : -1, info_level,tran_call,total_data));
2711 p = strrchr_m(fname,'/');
2717 mode = dos_mode(conn,fname,&sbuf);
2719 mode = FILE_ATTRIBUTE_NORMAL;
2721 fullpathname = fname;
2722 file_size = get_file_size(sbuf);
2723 allocation_size = get_allocation_size(conn,fsp,&sbuf);
2725 /* This is necessary, as otherwise the desktop.ini file in
2726 * this folder is ignored */
2727 mode |= (lp_profile_acls(SNUM(conn)) ? aRONLY : 0);
2731 /* Pull any EA list from the data portion. */
2732 if (info_level == SMB_INFO_QUERY_EAS_FROM_LIST) {
2733 uint32 ea_size = IVAL(pdata,0);
2735 if (total_data > 0 && ea_size != total_data) {
2736 DEBUG(4,("call_trans2qfilepathinfo: Rejecting EA request with incorrect \
2737 total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pdata,0) ));
2738 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
2741 if (!lp_ea_support(SNUM(conn))) {
2742 return ERROR_DOS(ERRDOS,ERReasnotsupported);
2745 if ((ea_ctx = talloc_init("ea_list")) == NULL) {
2746 return ERROR_NT(NT_STATUS_NO_MEMORY);
2749 /* Pull out the list of names. */
2750 ea_list = read_ea_name_list(ea_ctx, pdata, ea_size);
2752 talloc_destroy(ea_ctx);
2753 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
2757 params = SMB_REALLOC(*pparams,2);
2758 if (params == NULL) {
2759 talloc_destroy(ea_ctx);
2760 return ERROR_NT(NT_STATUS_NO_MEMORY);
2763 memset((char *)params,'\0',2);
2764 data_size = max_data_bytes + DIR_ENTRY_SAFETY_MARGIN;
2765 pdata = SMB_REALLOC(*ppdata, data_size);
2766 if ( pdata == NULL ) {
2767 talloc_destroy(ea_ctx);
2768 return ERROR_NT(NT_STATUS_NO_MEMORY);
2772 memset((char *)pdata,'\0',data_size);
2774 c_time = get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(conn)));
2777 if (fsp->pending_modtime) {
2778 /* the pending modtime overrides the current modtime */
2779 sbuf.st_mtime = fsp->pending_modtime;
2782 /* Do we have this path open ? */
2783 files_struct *fsp1 = file_find_di_first(sbuf.st_dev, sbuf.st_ino);
2784 if (fsp1 && fsp1->pending_modtime) {
2785 /* the pending modtime overrides the current modtime */
2786 sbuf.st_mtime = fsp1->pending_modtime;
2790 if (lp_dos_filetime_resolution(SNUM(conn))) {
2792 sbuf.st_atime &= ~1;
2793 sbuf.st_ctime &= ~1;
2794 sbuf.st_mtime &= ~1;
2797 /* NT expects the name to be in an exact form of the *full*
2798 filename. See the trans2 torture test */
2799 if (strequal(base_name,".")) {
2800 pstrcpy(dos_fname, "\\");
2802 pstr_sprintf(dos_fname, "\\%s", fname);
2803 string_replace(dos_fname, '/', '\\');
2806 switch (info_level) {
2807 case SMB_INFO_STANDARD:
2808 DEBUG(10,("call_trans2qfilepathinfo: SMB_INFO_STANDARD\n"));
2810 put_dos_date2(pdata,l1_fdateCreation,c_time);
2811 put_dos_date2(pdata,l1_fdateLastAccess,sbuf.st_atime);
2812 put_dos_date2(pdata,l1_fdateLastWrite,sbuf.st_mtime); /* write time */
2813 SIVAL(pdata,l1_cbFile,(uint32)file_size);
2814 SIVAL(pdata,l1_cbFileAlloc,(uint32)allocation_size);
2815 SSVAL(pdata,l1_attrFile,mode);
2818 case SMB_INFO_QUERY_EA_SIZE:
2820 unsigned int ea_size = estimate_ea_size(conn, fsp, fname);
2821 DEBUG(10,("call_trans2qfilepathinfo: SMB_INFO_QUERY_EA_SIZE\n"));
2823 put_dos_date2(pdata,l1_fdateCreation,c_time);
2824 put_dos_date2(pdata,l1_fdateLastAccess,sbuf.st_atime);
2825 put_dos_date2(pdata,l1_fdateLastWrite,sbuf.st_mtime); /* write time */
2826 SIVAL(pdata,l1_cbFile,(uint32)file_size);
2827 SIVAL(pdata,l1_cbFileAlloc,(uint32)allocation_size);
2828 SSVAL(pdata,l1_attrFile,mode);
2829 SIVAL(pdata,l1_attrFile+2,ea_size);
2833 case SMB_INFO_IS_NAME_VALID:
2834 DEBUG(10,("call_trans2qfilepathinfo: SMB_INFO_IS_NAME_VALID\n"));
2835 if (tran_call == TRANSACT2_QFILEINFO) {
2836 /* os/2 needs this ? really ?*/
2837 return ERROR_DOS(ERRDOS,ERRbadfunc);
2843 case SMB_INFO_QUERY_EAS_FROM_LIST:
2845 size_t total_ea_len = 0;
2846 struct ea_list *ea_file_list = NULL;
2848 DEBUG(10,("call_trans2qfilepathinfo: SMB_INFO_QUERY_EAS_FROM_LIST\n"));
2849 put_dos_date2(pdata,0,c_time);
2850 put_dos_date2(pdata,4,sbuf.st_atime);
2851 put_dos_date2(pdata,8,sbuf.st_mtime);
2852 SIVAL(pdata,12,(uint32)file_size);
2853 SIVAL(pdata,16,(uint32)allocation_size);
2854 SIVAL(pdata,20,mode);
2856 ea_file_list = get_ea_list_from_file(ea_ctx, conn, fsp, fname, &total_ea_len);
2858 ea_list = ea_list_union(ea_list, ea_file_list, &total_ea_len);
2860 if (!ea_list || (total_ea_len > data_size - 24)) {
2861 talloc_destroy(ea_ctx);
2866 data_size = fill_ea_buffer(ea_ctx, pdata + 24, data_size - 24, conn, ea_list);
2868 talloc_destroy(ea_ctx);
2872 case SMB_INFO_QUERY_ALL_EAS:
2874 /* We have data_size bytes to put EA's into. */
2875 size_t total_ea_len = 0;
2877 DEBUG(10,("call_trans2qfilepathinfo: SMB_INFO_QUERY_ALL_EAS\n"));
2879 ea_ctx = talloc_init("ea_ctx");
2881 return ERROR_NT(NT_STATUS_NO_MEMORY);
2884 ea_list = get_ea_list_from_file(ea_ctx, conn, fsp, fname, &total_ea_len);
2885 if (!ea_list || (total_ea_len > data_size)) {
2886 talloc_destroy(ea_ctx);
2891 data_size = fill_ea_buffer(ea_ctx, pdata, data_size, conn, ea_list);
2892 talloc_destroy(ea_ctx);
2896 case SMB_FILE_BASIC_INFORMATION:
2897 case SMB_QUERY_FILE_BASIC_INFO:
2899 if (info_level == SMB_QUERY_FILE_BASIC_INFO) {
2900 DEBUG(10,("call_trans2qfilepathinfo: SMB_QUERY_FILE_BASIC_INFO\n"));
2901 data_size = 36; /* w95 returns 40 bytes not 36 - why ?. */
2903 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_BASIC_INFORMATION\n"));
2907 put_long_date(pdata,c_time);
2908 put_long_date(pdata+8,sbuf.st_atime);
2909 put_long_date(pdata+16,sbuf.st_mtime); /* write time */
2910 put_long_date(pdata+24,sbuf.st_mtime); /* change time */
2911 SIVAL(pdata,32,mode);
2913 DEBUG(5,("SMB_QFBI - "));
2915 time_t create_time = c_time;
2916 DEBUG(5,("create: %s ", ctime(&create_time)));
2918 DEBUG(5,("access: %s ", ctime(&sbuf.st_atime)));
2919 DEBUG(5,("write: %s ", ctime(&sbuf.st_mtime)));
2920 DEBUG(5,("change: %s ", ctime(&sbuf.st_mtime)));
2921 DEBUG(5,("mode: %x\n", mode));
2925 case SMB_FILE_STANDARD_INFORMATION:
2926 case SMB_QUERY_FILE_STANDARD_INFO:
2928 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_STANDARD_INFORMATION\n"));
2930 SOFF_T(pdata,0,allocation_size);
2931 SOFF_T(pdata,8,file_size);
2932 if (delete_pending & sbuf.st_nlink)
2933 SIVAL(pdata,16,sbuf.st_nlink - 1);
2935 SIVAL(pdata,16,sbuf.st_nlink);
2937 SCVAL(pdata,21,(mode&aDIR)?1:0);
2940 case SMB_FILE_EA_INFORMATION:
2941 case SMB_QUERY_FILE_EA_INFO:
2943 unsigned int ea_size = estimate_ea_size(conn, fsp, fname);
2944 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_EA_INFORMATION\n"));
2946 SIVAL(pdata,0,ea_size);
2950 /* Get the 8.3 name - used if NT SMB was negotiated. */
2951 case SMB_QUERY_FILE_ALT_NAME_INFO:
2952 case SMB_FILE_ALTERNATE_NAME_INFORMATION:
2956 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_ALTERNATE_NAME_INFORMATION\n"));
2957 pstrcpy(short_name,base_name);
2958 /* Mangle if not already 8.3 */
2959 if(!mangle_is_8_3(short_name, True)) {
2960 mangle_map(short_name,True,True,SNUM(conn));
2962 len = srvstr_push(outbuf, pdata+4, short_name, -1, STR_UNICODE);
2963 data_size = 4 + len;
2968 case SMB_QUERY_FILE_NAME_INFO:
2970 this must be *exactly* right for ACLs on mapped drives to work
2972 len = srvstr_push(outbuf, pdata+4, dos_fname, -1, STR_UNICODE);
2973 DEBUG(10,("call_trans2qfilepathinfo: SMB_QUERY_FILE_NAME_INFO\n"));
2974 data_size = 4 + len;
2978 case SMB_FILE_ALLOCATION_INFORMATION:
2979 case SMB_QUERY_FILE_ALLOCATION_INFO:
2980 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_ALLOCATION_INFORMATION\n"));
2982 SOFF_T(pdata,0,allocation_size);
2985 case SMB_FILE_END_OF_FILE_INFORMATION:
2986 case SMB_QUERY_FILE_END_OF_FILEINFO:
2987 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_END_OF_FILE_INFORMATION\n"));
2989 SOFF_T(pdata,0,file_size);
2992 case SMB_QUERY_FILE_ALL_INFO:
2993 case SMB_FILE_ALL_INFORMATION:
2995 unsigned int ea_size = estimate_ea_size(conn, fsp, fname);
2996 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_ALL_INFORMATION\n"));
2997 put_long_date(pdata,c_time);
2998 put_long_date(pdata+8,sbuf.st_atime);
2999 put_long_date(pdata+16,sbuf.st_mtime); /* write time */
3000 put_long_date(pdata+24,sbuf.st_mtime); /* change time */
3001 SIVAL(pdata,32,mode);
3003 SOFF_T(pdata,0,allocation_size);
3004 SOFF_T(pdata,8,file_size);
3005 if (delete_pending && sbuf.st_nlink)
3006 SIVAL(pdata,16,sbuf.st_nlink - 1);
3008 SIVAL(pdata,16,sbuf.st_nlink);
3009 SCVAL(pdata,20,delete_pending);
3010 SCVAL(pdata,21,(mode&aDIR)?1:0);
3012 SIVAL(pdata,0,ea_size);
3013 pdata += 4; /* EA info */
3014 len = srvstr_push(outbuf, pdata+4, dos_fname, -1, STR_UNICODE);
3017 data_size = PTR_DIFF(pdata,(*ppdata));
3020 case SMB_FILE_INTERNAL_INFORMATION:
3021 /* This should be an index number - looks like
3024 I think this causes us to fail the IFSKIT
3025 BasicFileInformationTest. -tpot */
3027 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_INTERNAL_INFORMATION\n"));
3028 SIVAL(pdata,0,sbuf.st_dev);
3029 SIVAL(pdata,4,sbuf.st_ino);
3033 case SMB_FILE_ACCESS_INFORMATION:
3034 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_ACCESS_INFORMATION\n"));
3035 SIVAL(pdata,0,desired_access);
3039 case SMB_FILE_NAME_INFORMATION:
3040 /* Pathname with leading '\'. */
3043 byte_len = dos_PutUniCode(pdata+4,dos_fname,max_data_bytes,False);
3044 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_NAME_INFORMATION\n"));
3045 SIVAL(pdata,0,byte_len);
3046 data_size = 4 + byte_len;
3050 case SMB_FILE_DISPOSITION_INFORMATION:
3051 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_DISPOSITION_INFORMATION\n"));
3053 SCVAL(pdata,0,delete_pending);
3056 case SMB_FILE_POSITION_INFORMATION:
3057 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_POSITION_INFORMATION\n"));
3059 SOFF_T(pdata,0,pos);
3062 case SMB_FILE_MODE_INFORMATION:
3063 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_MODE_INFORMATION\n"));
3064 SIVAL(pdata,0,mode);
3068 case SMB_FILE_ALIGNMENT_INFORMATION:
3069 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_ALIGNMENT_INFORMATION\n"));
3070 SIVAL(pdata,0,0); /* No alignment needed. */
3076 * NT4 server just returns "invalid query" to this - if we try to answer
3077 * it then NTws gets a BSOD! (tridge).
3078 * W2K seems to want this. JRA.
3080 case SMB_QUERY_FILE_STREAM_INFO:
3082 case SMB_FILE_STREAM_INFORMATION:
3083 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_STREAM_INFORMATION\n"));
3087 size_t byte_len = dos_PutUniCode(pdata+24,"::$DATA", 0xE, False);
3088 SIVAL(pdata,0,0); /* ??? */
3089 SIVAL(pdata,4,byte_len); /* Byte length of unicode string ::$DATA */
3090 SOFF_T(pdata,8,file_size);
3091 SIVAL(pdata,16,allocation_size);
3092 SIVAL(pdata,20,0); /* ??? */
3093 data_size = 24 + byte_len;
3097 case SMB_QUERY_COMPRESSION_INFO:
3098 case SMB_FILE_COMPRESSION_INFORMATION:
3099 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_COMPRESSION_INFORMATION\n"));
3100 SOFF_T(pdata,0,file_size);
3101 SIVAL(pdata,8,0); /* ??? */
3102 SIVAL(pdata,12,0); /* ??? */
3106 case SMB_FILE_NETWORK_OPEN_INFORMATION:
3107 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_NETWORK_OPEN_INFORMATION\n"));
3108 put_long_date(pdata,c_time);
3109 put_long_date(pdata+8,sbuf.st_atime);
3110 put_long_date(pdata+16,sbuf.st_mtime); /* write time */
3111 put_long_date(pdata+24,sbuf.st_mtime); /* change time */
3112 SIVAL(pdata,32,allocation_size);
3113 SOFF_T(pdata,40,file_size);
3114 SIVAL(pdata,48,mode);
3115 SIVAL(pdata,52,0); /* ??? */
3119 case SMB_FILE_ATTRIBUTE_TAG_INFORMATION:
3120 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_ATTRIBUTE_TAG_INFORMATION\n"));
3121 SIVAL(pdata,0,mode);
3127 * CIFS UNIX Extensions.
3130 case SMB_QUERY_FILE_UNIX_BASIC:
3132 DEBUG(10,("call_trans2qfilepathinfo: SMB_QUERY_FILE_UNIX_BASIC\n"));
3133 DEBUG(4,("call_trans2qfilepathinfo: st_mode=%o\n",(int)sbuf.st_mode));
3135 SOFF_T(pdata,0,get_file_size(sbuf)); /* File size 64 Bit */
3138 SOFF_T(pdata,0,get_allocation_size(conn,fsp,&sbuf)); /* Number of bytes used on disk - 64 Bit */
3141 put_long_date(pdata,sbuf.st_ctime); /* Creation Time 64 Bit */
3142 put_long_date(pdata+8,sbuf.st_atime); /* Last access time 64 Bit */
3143 put_long_date(pdata+16,sbuf.st_mtime); /* Last modification time 64 Bit */
3146 SIVAL(pdata,0,sbuf.st_uid); /* user id for the owner */
3150 SIVAL(pdata,0,sbuf.st_gid); /* group id of owner */
3154 SIVAL(pdata,0,unix_filetype(sbuf.st_mode));
3157 SIVAL(pdata,0,unix_dev_major(sbuf.st_rdev)); /* Major device number if type is device */
3161 SIVAL(pdata,0,unix_dev_minor(sbuf.st_rdev)); /* Minor device number if type is device */
3165 SINO_T(pdata,0,(SMB_INO_T)sbuf.st_ino); /* inode number */
3168 SIVAL(pdata,0, unix_perms_to_wire(sbuf.st_mode)); /* Standard UNIX file permissions */
3172 SIVAL(pdata,0,sbuf.st_nlink); /* number of hard links */
3175 data_size = PTR_DIFF(pdata,(*ppdata));
3179 DEBUG(4,("call_trans2qfilepathinfo: SMB_QUERY_FILE_UNIX_BASIC"));
3181 for (i=0; i<100; i++)
3182 DEBUG(4,("%d=%x, ",i, (*ppdata)[i]));
3188 case SMB_QUERY_FILE_UNIX_LINK:
3192 DEBUG(10,("call_trans2qfilepathinfo: SMB_QUERY_FILE_UNIX_LINK\n"));
3194 if(!S_ISLNK(sbuf.st_mode))
3195 return(UNIXERROR(ERRSRV,ERRbadlink));
3197 return(UNIXERROR(ERRDOS,ERRbadlink));
3199 len = SMB_VFS_READLINK(conn,fullpathname, buffer, sizeof(pstring)-1); /* read link */
3201 return(UNIXERROR(ERRDOS,ERRnoaccess));
3203 len = srvstr_push(outbuf, pdata, buffer, -1, STR_TERMINATE);
3205 data_size = PTR_DIFF(pdata,(*ppdata));
3210 #if defined(HAVE_POSIX_ACLS)
3211 case SMB_QUERY_POSIX_ACL:
3213 SMB_ACL_T file_acl = NULL;
3214 SMB_ACL_T def_acl = NULL;
3215 uint16 num_file_acls = 0;
3216 uint16 num_def_acls = 0;
3218 if (fsp && !fsp->is_directory && (fsp->fd != -1)) {
3219 file_acl = SMB_VFS_SYS_ACL_GET_FD(fsp, fsp->fd);
3221 file_acl = SMB_VFS_SYS_ACL_GET_FILE(conn, fname, SMB_ACL_TYPE_ACCESS);
3224 if (file_acl == NULL && no_acl_syscall_error(errno)) {
3225 DEBUG(5,("call_trans2qfilepathinfo: ACLs not implemented on filesystem containing %s\n",
3227 return ERROR_NT(NT_STATUS_NOT_IMPLEMENTED);
3230 if (S_ISDIR(sbuf.st_mode)) {
3231 if (fsp && fsp->is_directory) {
3232 def_acl = SMB_VFS_SYS_ACL_GET_FILE(conn, fsp->fsp_name, SMB_ACL_TYPE_DEFAULT);
3234 def_acl = SMB_VFS_SYS_ACL_GET_FILE(conn, fname, SMB_ACL_TYPE_DEFAULT);
3236 def_acl = free_empty_sys_acl(conn, def_acl);
3239 num_file_acls = count_acl_entries(conn, file_acl);
3240 num_def_acls = count_acl_entries(conn, def_acl);
3242 if ( data_size < (num_file_acls + num_def_acls)*SMB_POSIX_ACL_ENTRY_SIZE + SMB_POSIX_ACL_HEADER_SIZE) {
3243 DEBUG(5,("call_trans2qfilepathinfo: data_size too small (%u) need %u\n",
3245 (unsigned int)((num_file_acls + num_def_acls)*SMB_POSIX_ACL_ENTRY_SIZE +
3246 SMB_POSIX_ACL_HEADER_SIZE) ));
3248 SMB_VFS_SYS_ACL_FREE_ACL(conn, file_acl);
3251 SMB_VFS_SYS_ACL_FREE_ACL(conn, def_acl);
3253 return ERROR_NT(NT_STATUS_BUFFER_TOO_SMALL);
3256 SSVAL(pdata,0,SMB_POSIX_ACL_VERSION);
3257 SSVAL(pdata,2,num_file_acls);
3258 SSVAL(pdata,4,num_def_acls);
3259 if (!marshall_posix_acl(conn, pdata + SMB_POSIX_ACL_HEADER_SIZE, &sbuf, file_acl)) {
3261 SMB_VFS_SYS_ACL_FREE_ACL(conn, file_acl);
3264 SMB_VFS_SYS_ACL_FREE_ACL(conn, def_acl);
3266 return ERROR_NT(NT_STATUS_INTERNAL_ERROR);
3268 if (!marshall_posix_acl(conn, pdata + SMB_POSIX_ACL_HEADER_SIZE + (num_file_acls*SMB_POSIX_ACL_ENTRY_SIZE), &sbuf, def_acl)) {
3270 SMB_VFS_SYS_ACL_FREE_ACL(conn, file_acl);
3273 SMB_VFS_SYS_ACL_FREE_ACL(conn, def_acl);
3275 return ERROR_NT(NT_STATUS_INTERNAL_ERROR);
3279 SMB_VFS_SYS_ACL_FREE_ACL(conn, file_acl);
3282 SMB_VFS_SYS_ACL_FREE_ACL(conn, def_acl);
3284 data_size = (num_file_acls + num_def_acls)*SMB_POSIX_ACL_ENTRY_SIZE + SMB_POSIX_ACL_HEADER_SIZE;
3290 return ERROR_DOS(ERRDOS,ERRunknownlevel);
3293 send_trans2_replies(outbuf, bufsize, params, param_size, *ppdata, data_size);
3298 /****************************************************************************
3299 Deal with the internal needs of setting the delete on close flag. Note that
3300 as the tdb locking is recursive, it is safe to call this from within
3301 open_file_shared. JRA.
3302 ****************************************************************************/
3304 NTSTATUS set_delete_on_close_internal(files_struct *fsp, BOOL delete_on_close, uint32 dosmode)
3306 if (delete_on_close) {
3308 * Only allow delete on close for writable files.
3311 if (!lp_delete_readonly(SNUM(fsp->conn))) {
3312 if (dosmode & aRONLY) {
3313 DEBUG(10,("set_delete_on_close_internal: file %s delete on close flag set but file attribute is readonly.\n",
3315 return NT_STATUS_CANNOT_DELETE;
3320 * Only allow delete on close for writable shares.
3323 if (!CAN_WRITE(fsp->conn)) {
3324 DEBUG(10,("set_delete_on_close_internal: file %s delete on close flag set but write access denied on share.\n",
3326 return NT_STATUS_ACCESS_DENIED;
3330 * Only allow delete on close for files/directories opened with delete intent.
3333 if (!(fsp->desired_access & DELETE_ACCESS)) {
3334 DEBUG(10,("set_delete_on_close_internal: file %s delete on close flag set but delete access denied.\n",
3336 return NT_STATUS_ACCESS_DENIED;
3340 if(fsp->is_directory) {
3341 fsp->directory_delete_on_close = delete_on_close;
3342 DEBUG(10, ("set_delete_on_close_internal: %s delete on close flag for fnum = %d, directory %s\n",
3343 delete_on_close ? "Added" : "Removed", fsp->fnum, fsp->fsp_name ));
3345 fsp->delete_on_close = delete_on_close;
3346 DEBUG(10, ("set_delete_on_close_internal: %s delete on close flag for fnum = %d, file %s\n",
3347 delete_on_close ? "Added" : "Removed", fsp->fnum, fsp->fsp_name ));
3350 return NT_STATUS_OK;
3353 /****************************************************************************
3354 Sets the delete on close flag over all share modes on this file.
3355 Modify the share mode entry for all files open
3356 on this device and inode to tell other smbds we have
3357 changed the delete on close flag. This will be noticed
3358 in the close code, the last closer will delete the file
3360 ****************************************************************************/
3362 NTSTATUS set_delete_on_close_over_all(files_struct *fsp, BOOL delete_on_close)
3364 DEBUG(10,("set_delete_on_close_over_all: %s delete on close flag for fnum = %d, file %s\n",
3365 delete_on_close ? "Adding" : "Removing", fsp->fnum, fsp->fsp_name ));
3367 if (fsp->is_directory || fsp->is_stat)
3368 return NT_STATUS_OK;
3370 if (lock_share_entry_fsp(fsp) == False)
3371 return NT_STATUS_ACCESS_DENIED;
3373 if (!modify_delete_flag(fsp->dev, fsp->inode, delete_on_close)) {
3374 DEBUG(0,("set_delete_on_close_over_all: failed to change delete on close flag for file %s\n",
3376 unlock_share_entry_fsp(fsp);
3377 return NT_STATUS_ACCESS_DENIED;
3380 unlock_share_entry_fsp(fsp);
3381 return NT_STATUS_OK;
3384 /****************************************************************************
3385 Set a hard link (called by UNIX extensions and by NT rename with HARD link
3387 ****************************************************************************/
3389 NTSTATUS hardlink_internals(connection_struct *conn, char *oldname, char *newname)
3391 BOOL bad_path_oldname = False;
3392 BOOL bad_path_newname = False;
3393 SMB_STRUCT_STAT sbuf1, sbuf2;
3394 pstring last_component_oldname;
3395 pstring last_component_newname;
3396 NTSTATUS status = NT_STATUS_OK;
3402 if (ms_has_wild(newname) || ms_has_wild(oldname)) {
3403 return NT_STATUS_OBJECT_PATH_SYNTAX_BAD;
3406 unix_convert(oldname,conn,last_component_oldname,&bad_path_oldname,&sbuf1);
3407 if (bad_path_oldname) {
3408 return NT_STATUS_OBJECT_PATH_NOT_FOUND;
3411 /* Quick check for "." and ".." */
3412 if (last_component_oldname[0] == '.') {
3413 if (!last_component_oldname[1] || (last_component_oldname[1] == '.' && !last_component_oldname[2])) {
3414 return NT_STATUS_OBJECT_NAME_INVALID;
3418 /* source must already exist. */
3419 if (!VALID_STAT(sbuf1)) {
3420 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3423 if (!check_name(oldname,conn)) {
3424 return NT_STATUS_ACCESS_DENIED;
3427 unix_convert(newname,conn,last_component_newname,&bad_path_newname,&sbuf2);
3428 if (bad_path_newname) {
3429 return NT_STATUS_OBJECT_PATH_NOT_FOUND;
3432 /* Quick check for "." and ".." */
3433 if (last_component_newname[0] == '.') {
3434 if (!last_component_newname[1] || (last_component_newname[1] == '.' && !last_component_newname[2])) {
3435 return NT_STATUS_OBJECT_NAME_INVALID;
3439 /* Disallow if newname already exists. */
3440 if (VALID_STAT(sbuf2)) {
3441 return NT_STATUS_OBJECT_NAME_COLLISION;
3444 if (!check_name(newname,conn)) {
3445 return NT_STATUS_ACCESS_DENIED;
3448 /* No links from a directory. */
3449 if (S_ISDIR(sbuf1.st_mode)) {
3450 return NT_STATUS_FILE_IS_A_DIRECTORY;
3453 /* Ensure this is within the share. */
3454 if (!reduce_name(conn, oldname) != 0)
3455 return NT_STATUS_ACCESS_DENIED;
3457 DEBUG(10,("hardlink_internals: doing hard link %s -> %s\n", newname, oldname ));
3459 if (SMB_VFS_LINK(conn,oldname,newname) != 0) {
3460 status = map_nt_error_from_unix(errno);
3461 DEBUG(3,("hardlink_internals: Error %s hard link %s -> %s\n",
3462 nt_errstr(status), newname, oldname));
3468 /****************************************************************************
3469 Reply to a TRANS2_SETFILEINFO (set file info by fileid).
3470 ****************************************************************************/
3472 static int call_trans2setfilepathinfo(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize,
3473 char **pparams, int total_params, char **ppdata, int total_data,
3474 unsigned int max_data_bytes)
3476 char *params = *pparams;
3477 char *pdata = *ppdata;
3478 uint16 tran_call = SVAL(inbuf, smb_setup0);
3483 SMB_STRUCT_STAT sbuf;
3486 BOOL bad_path = False;
3487 files_struct *fsp = NULL;
3488 uid_t set_owner = (uid_t)SMB_UID_NO_CHANGE;
3489 gid_t set_grp = (uid_t)SMB_GID_NO_CHANGE;
3490 mode_t unixmode = 0;
3491 NTSTATUS status = NT_STATUS_OK;
3494 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
3498 if (tran_call == TRANSACT2_SETFILEINFO) {
3499 if (total_params < 4) {
3500 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
3503 fsp = file_fsp(params,0);
3504 info_level = SVAL(params,2);
3506 if(fsp && (fsp->is_directory || fsp->fd == -1)) {
3508 * This is actually a SETFILEINFO on a directory
3509 * handle (returned from an NT SMB). NT5.0 seems
3510 * to do this call. JRA.
3512 pstrcpy(fname, fsp->fsp_name);
3513 if (SMB_VFS_STAT(conn,fname,&sbuf) != 0) {
3514 DEBUG(3,("call_trans2setfilepathinfo: fileinfo of %s failed (%s)\n",fname,strerror(errno)));
3515 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRbadpath);
3517 } else if (fsp && fsp->print_file) {
3519 * Doing a DELETE_ON_CLOSE should cancel a print job.
3521 if ((info_level == SMB_SET_FILE_DISPOSITION_INFO) && CVAL(pdata,0)) {
3522 fsp->share_mode = FILE_DELETE_ON_CLOSE;
3524 DEBUG(3,("call_trans2setfilepathinfo: Cancelling print job (%s)\n", fsp->fsp_name ));
3527 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
3530 return (UNIXERROR(ERRDOS,ERRbadpath));
3533 * Original code - this is an open file.
3535 CHECK_FSP(fsp,conn);
3537 pstrcpy(fname, fsp->fsp_name);
3540 if (SMB_VFS_FSTAT(fsp,fd,&sbuf) != 0) {
3541 DEBUG(3,("call_trans2setfilepathinfo: fstat of fnum %d failed (%s)\n",fsp->fnum, strerror(errno)));
3542 return(UNIXERROR(ERRDOS,ERRbadfid));
3547 if (total_params < 6) {
3548 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
3551 info_level = SVAL(params,0);
3552 srvstr_get_path(inbuf, fname, ¶ms[6], sizeof(fname), -1, STR_TERMINATE, &status, False);
3553 if (!NT_STATUS_IS_OK(status)) {
3554 return ERROR_NT(status);
3556 unix_convert(fname,conn,0,&bad_path,&sbuf);
3558 return ERROR_NT(NT_STATUS_OBJECT_PATH_NOT_FOUND);
3562 * For CIFS UNIX extensions the target name may not exist.
3565 if(!VALID_STAT(sbuf) && !INFO_LEVEL_IS_UNIX(info_level)) {
3566 DEBUG(3,("call_trans2setfilepathinfo: stat of %s failed (%s)\n", fname, strerror(errno)));
3567 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRbadpath);
3570 if(!check_name(fname, conn)) {
3571 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRbadpath);
3576 if (!CAN_WRITE(conn))
3577 return ERROR_DOS(ERRSRV,ERRaccess);
3579 if (INFO_LEVEL_IS_UNIX(info_level) && !lp_unix_extensions())
3580 return ERROR_DOS(ERRDOS,ERRunknownlevel);
3582 if (VALID_STAT(sbuf))
3583 unixmode = sbuf.st_mode;
3585 DEBUG(3,("call_trans2setfilepathinfo(%d) %s (fnum %d) info_level=%d totdata=%d\n",
3586 tran_call,fname, fsp ? fsp->fnum : -1, info_level,total_data));
3588 /* Realloc the parameter size */
3589 params = SMB_REALLOC(*pparams,2);
3590 if(params == NULL) {
3591 return ERROR_NT(NT_STATUS_NO_MEMORY);
3597 if (fsp && fsp->pending_modtime) {
3598 /* the pending modtime overrides the current modtime */
3599 sbuf.st_mtime = fsp->pending_modtime;
3602 size = get_file_size(sbuf);
3603 tvs.modtime = sbuf.st_mtime;
3604 tvs.actime = sbuf.st_atime;
3605 dosmode = dos_mode(conn,fname,&sbuf);
3606 unixmode = sbuf.st_mode;
3608 set_owner = VALID_STAT(sbuf) ? sbuf.st_uid : (uid_t)SMB_UID_NO_CHANGE;
3609 set_grp = VALID_STAT(sbuf) ? sbuf.st_gid : (gid_t)SMB_GID_NO_CHANGE;
3611 switch (info_level) {
3612 case SMB_INFO_STANDARD:
3614 if (total_data < 12) {
3615 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
3619 tvs.actime = make_unix_date2(pdata+l1_fdateLastAccess);
3621 tvs.modtime = make_unix_date2(pdata+l1_fdateLastWrite);
3625 case SMB_INFO_SET_EA:
3627 struct ea_list *ea_list = NULL;
3628 TALLOC_CTX *ctx = talloc_init("SMB_INFO_SET_EA");
3630 return ERROR_NT(NT_STATUS_NO_MEMORY);
3632 ea_list = read_ea_list(ctx, pdata, total_data);
3634 talloc_destroy(ctx);
3635 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
3637 status = set_ea(conn, fsp, fname, ea_list);
3638 talloc_destroy(ctx);
3640 if (NT_STATUS_V(status) != NT_STATUS_V(NT_STATUS_OK)) {
3641 return ERROR_NT(status);
3647 /* The following 2 info levels are only valid on query, not set. Remove them. JRA. */
3648 /* XXXX um, i don't think this is right.
3649 it's also not in the cifs6.txt spec.
3651 case SMB_INFO_QUERY_EAS_FROM_LIST:
3652 if (total_data < 28)
3653 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
3655 tvs.actime = make_unix_date2(pdata+8);
3656 tvs.modtime = make_unix_date2(pdata+12);
3657 size = IVAL(pdata,16);
3658 dosmode = IVAL(pdata,24);
3661 /* XXXX nor this. not in cifs6.txt, either. */
3662 case SMB_INFO_QUERY_ALL_EAS:
3663 if (total_data < 28)
3664 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
3666 tvs.actime = make_unix_date2(pdata+8);
3667 tvs.modtime = make_unix_date2(pdata+12);
3668 size = IVAL(pdata,16);
3669 dosmode = IVAL(pdata,24);
3673 case SMB_SET_FILE_BASIC_INFO:
3674 case SMB_FILE_BASIC_INFORMATION:
3676 /* Patch to do this correctly from Paul Eggert <eggert@twinsun.com>. */
3678 time_t changed_time;
3680 if (total_data < 36) {
3681 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
3684 /* Ignore create time at offset pdata. */
3687 tvs.actime = interpret_long_date(pdata+8);
3689 write_time = interpret_long_date(pdata+16);
3690 changed_time = interpret_long_date(pdata+24);
3692 tvs.modtime = MIN(write_time, changed_time);
3694 if (write_time > tvs.modtime && write_time != (time_t)-1) {
3695 tvs.modtime = write_time;
3697 /* Prefer a defined time to an undefined one. */
3698 if (null_mtime(tvs.modtime)) {
3699 tvs.modtime = null_mtime(write_time) ? changed_time : write_time;
3703 dosmode = IVAL(pdata,32);
3707 case SMB_FILE_ALLOCATION_INFORMATION:
3708 case SMB_SET_FILE_ALLOCATION_INFO:
3711 SMB_BIG_UINT allocation_size;
3713 if (total_data < 8) {
3714 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
3717 allocation_size = (SMB_BIG_UINT)IVAL(pdata,0);
3718 #ifdef LARGE_SMB_OFF_T
3719 allocation_size |= (((SMB_BIG_UINT)IVAL(pdata,4)) << 32);
3720 #else /* LARGE_SMB_OFF_T */
3721 if (IVAL(pdata,4) != 0) /* more than 32 bits? */
3722 return ERROR_DOS(ERRDOS,ERRunknownlevel);
3723 #endif /* LARGE_SMB_OFF_T */
3724 DEBUG(10,("call_trans2setfilepathinfo: Set file allocation info for file %s to %.0f\n",
3725 fname, (double)allocation_size ));
3727 if (allocation_size) {
3728 allocation_size = smb_roundup(conn, allocation_size);
3731 if(allocation_size != get_file_size(sbuf)) {
3732 SMB_STRUCT_STAT new_sbuf;
3734 DEBUG(10,("call_trans2setfilepathinfo: file %s : setting new allocation size to %.0f\n",
3735 fname, (double)allocation_size ));
3738 files_struct *new_fsp = NULL;
3739 int access_mode = 0;
3742 if(global_oplock_break) {
3743 /* Queue this file modify as we are the process of an oplock break. */
3745 DEBUG(2,("call_trans2setfilepathinfo: queueing message due to being "));
3746 DEBUGADD(2,( "in oplock break state.\n"));
3748 push_oplock_pending_smb_message(inbuf, length);
3752 new_fsp = open_file_shared1(conn, fname, &sbuf,FILE_WRITE_DATA,
3753 SET_OPEN_MODE(DOS_OPEN_RDWR),
3754 (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN),
3755 FILE_ATTRIBUTE_NORMAL,
3756 INTERNAL_OPEN_ONLY, &access_mode, &action);
3758 if (new_fsp == NULL)
3759 return(UNIXERROR(ERRDOS,ERRbadpath));
3760 ret = vfs_allocate_file_space(new_fsp, allocation_size);
3761 if (SMB_VFS_FSTAT(new_fsp,new_fsp->fd,&new_sbuf) != 0) {
3762 DEBUG(3,("call_trans2setfilepathinfo: fstat of fnum %d failed (%s)\n",
3763 new_fsp->fnum, strerror(errno)));
3766 close_file(new_fsp,True);
3768 ret = vfs_allocate_file_space(fsp, allocation_size);
3769 if (SMB_VFS_FSTAT(fsp,fd,&new_sbuf) != 0) {
3770 DEBUG(3,("call_trans2setfilepathinfo: fstat of fnum %d failed (%s)\n",
3771 fsp->fnum, strerror(errno)));
3776 return ERROR_NT(NT_STATUS_DISK_FULL);
3778 /* Allocate can truncate size... */
3779 size = get_file_size(new_sbuf);
3785 case SMB_FILE_END_OF_FILE_INFORMATION:
3786 case SMB_SET_FILE_END_OF_FILE_INFO:
3788 if (total_data < 8) {
3789 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
3792 size = IVAL(pdata,0);
3793 #ifdef LARGE_SMB_OFF_T
3794 size |= (((SMB_OFF_T)IVAL(pdata,4)) << 32);
3795 #else /* LARGE_SMB_OFF_T */
3796 if (IVAL(pdata,4) != 0) /* more than 32 bits? */
3797 return ERROR_DOS(ERRDOS,ERRunknownlevel);
3798 #endif /* LARGE_SMB_OFF_T */
3799 DEBUG(10,("call_trans2setfilepathinfo: Set end of file info for file %s to %.0f\n", fname, (double)size ));
3803 case SMB_FILE_DISPOSITION_INFORMATION:
3804 case SMB_SET_FILE_DISPOSITION_INFO: /* Set delete on close for open file. */
3806 BOOL delete_on_close;
3808 if (total_data < 1) {
3809 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
3812 delete_on_close = (CVAL(pdata,0) ? True : False);
3814 /* Just ignore this set on a path. */
3815 if (tran_call != TRANSACT2_SETFILEINFO)
3819 return(UNIXERROR(ERRDOS,ERRbadfid));
3821 status = set_delete_on_close_internal(fsp, delete_on_close, dosmode);
3823 if (NT_STATUS_V(status) != NT_STATUS_V(NT_STATUS_OK))
3824 return ERROR_NT(status);
3826 /* The set is across all open files on this dev/inode pair. */
3827 status =set_delete_on_close_over_all(fsp, delete_on_close);
3828 if (NT_STATUS_V(status) != NT_STATUS_V(NT_STATUS_OK))
3829 return ERROR_NT(status);
3834 case SMB_FILE_POSITION_INFORMATION:
3836 SMB_BIG_UINT position_information;
3838 if (total_data < 8) {
3839 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
3842 position_information = (SMB_BIG_UINT)IVAL(pdata,0);
3843 #ifdef LARGE_SMB_OFF_T
3844 position_information |= (((SMB_BIG_UINT)IVAL(pdata,4)) << 32);
3845 #else /* LARGE_SMB_OFF_T */
3846 if (IVAL(pdata,4) != 0) /* more than 32 bits? */
3847 return ERROR_DOS(ERRDOS,ERRunknownlevel);
3848 #endif /* LARGE_SMB_OFF_T */
3849 DEBUG(10,("call_trans2setfilepathinfo: Set file position information for file %s to %.0f\n",
3850 fname, (double)position_information ));
3852 fsp->position_information = position_information;
3856 /* From tridge Samba4 :
3857 * MODE_INFORMATION in setfileinfo (I have no
3858 * idea what "mode information" on a file is - it takes a value of 0,
3859 * 2, 4 or 6. What could it be?).
3862 case SMB_FILE_MODE_INFORMATION:
3866 if (total_data < 4) {
3867 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
3869 mode = IVAL(pdata,0);
3870 if (mode != 0 && mode != 2 && mode != 4 && mode != 6) {
3871 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
3877 * CIFS UNIX extensions.
3880 case SMB_SET_FILE_UNIX_BASIC:
3882 uint32 raw_unixmode;
3884 if (total_data < 100) {
3885 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
3888 if(IVAL(pdata, 0) != SMB_SIZE_NO_CHANGE_LO &&
3889 IVAL(pdata, 4) != SMB_SIZE_NO_CHANGE_HI) {
3890 size=IVAL(pdata,0); /* first 8 Bytes are size */
3891 #ifdef LARGE_SMB_OFF_T
3892 size |= (((SMB_OFF_T)IVAL(pdata,4)) << 32);
3893 #else /* LARGE_SMB_OFF_T */
3894 if (IVAL(pdata,4) != 0) /* more than 32 bits? */
3895 return ERROR_DOS(ERRDOS,ERRunknownlevel);
3896 #endif /* LARGE_SMB_OFF_T */
3898 pdata+=24; /* ctime & st_blocks are not changed */
3899 tvs.actime = interpret_long_date(pdata); /* access_time */
3900 tvs.modtime = interpret_long_date(pdata+8); /* modification_time */
3902 set_owner = (uid_t)IVAL(pdata,0);
3904 set_grp = (gid_t)IVAL(pdata,0);
3906 raw_unixmode = IVAL(pdata,28);
3907 unixmode = unix_perms_from_wire(conn, &sbuf, raw_unixmode);
3908 dosmode = 0; /* Ensure dos mode change doesn't override this. */
3910 DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_BASIC: name = %s \
3911 size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n",
3912 fname, (double)size, (unsigned int)set_owner, (unsigned int)set_grp, (int)raw_unixmode));
3914 if (!VALID_STAT(sbuf)) {
3917 * The only valid use of this is to create character and block
3918 * devices, and named pipes. This is deprecated (IMHO) and
3919 * a new info level should be used for mknod. JRA.
3922 uint32 file_type = IVAL(pdata,0);
3923 #if defined(HAVE_MAKEDEV)
3924 uint32 dev_major = IVAL(pdata,4);
3925 uint32 dev_minor = IVAL(pdata,12);
3928 uid_t myuid = geteuid();
3929 gid_t mygid = getegid();
3930 SMB_DEV_T dev = (SMB_DEV_T)0;
3932 if (tran_call == TRANSACT2_SETFILEINFO)
3933 return(ERROR_DOS(ERRDOS,ERRnoaccess));
3935 if (raw_unixmode == SMB_MODE_NO_CHANGE) {
3936 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
3939 #if defined(HAVE_MAKEDEV)
3940 dev = makedev(dev_major, dev_minor);
3943 /* We can only create as the owner/group we are. */
3945 if ((set_owner != myuid) && (set_owner != (uid_t)SMB_UID_NO_CHANGE))
3946 return(ERROR_DOS(ERRDOS,ERRnoaccess));
3947 if ((set_grp != mygid) && (set_grp != (gid_t)SMB_GID_NO_CHANGE))
3948 return(ERROR_DOS(ERRDOS,ERRnoaccess));
3950 switch (file_type) {
3951 #if defined(S_IFIFO)
3952 case UNIX_TYPE_FIFO:
3953 unixmode |= S_IFIFO;
3956 #if defined(S_IFSOCK)
3957 case UNIX_TYPE_SOCKET:
3958 unixmode |= S_IFSOCK;
3961 #if defined(S_IFCHR)
3962 case UNIX_TYPE_CHARDEV:
3963 unixmode |= S_IFCHR;
3966 #if defined(S_IFBLK)
3967 case UNIX_TYPE_BLKDEV:
3968 unixmode |= S_IFBLK;
3972 return(ERROR_DOS(ERRDOS,ERRnoaccess));
3975 DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_BASIC doing mknod dev %.0f mode \
3976 0%o for file %s\n", (double)dev, unixmode, fname ));
3978 /* Ok - do the mknod. */
3979 if (SMB_VFS_MKNOD(conn,fname, unixmode, dev) != 0)
3980 return(UNIXERROR(ERRDOS,ERRnoaccess));
3982 inherit_access_acl(conn, fname, unixmode);
3985 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
3990 * Deal with the UNIX specific mode set.
3993 if (raw_unixmode != SMB_MODE_NO_CHANGE) {
3994 DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_BASIC setting mode 0%o for file %s\n",
3995 (unsigned int)unixmode, fname ));
3996 if (SMB_VFS_CHMOD(conn,fname,unixmode) != 0)
3997 return(UNIXERROR(ERRDOS,ERRnoaccess));
4001 * Deal with the UNIX specific uid set.
4004 if ((set_owner != (uid_t)SMB_UID_NO_CHANGE) && (sbuf.st_uid != set_owner)) {
4005 DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_BASIC changing owner %u for file %s\n",
4006 (unsigned int)set_owner, fname ));
4007 if (SMB_VFS_CHOWN(conn,fname,set_owner, (gid_t)-1) != 0)
4008 return(UNIXERROR(ERRDOS,ERRnoaccess));
4012 * Deal with the UNIX specific gid set.
4015 if ((set_grp != (uid_t)SMB_GID_NO_CHANGE) && (sbuf.st_gid != set_grp)) {
4016 DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_BASIC changing group %u for file %s\n",
4017 (unsigned int)set_owner, fname ));
4018 if (SMB_VFS_CHOWN(conn,fname,(uid_t)-1, set_grp) != 0)
4019 return(UNIXERROR(ERRDOS,ERRnoaccess));
4024 case SMB_SET_FILE_UNIX_LINK:
4026 pstring link_target;
4027 char *newname = fname;
4029 /* Set a symbolic link. */
4030 /* Don't allow this if follow links is false. */
4032 if (!lp_symlinks(SNUM(conn)))
4033 return(ERROR_DOS(ERRDOS,ERRnoaccess));
4035 srvstr_pull(inbuf, link_target, pdata, sizeof(link_target), -1, STR_TERMINATE);
4037 /* !widelinks forces the target path to be within the share. */
4038 /* This means we can interpret the target as a pathname. */
4039 if (!lp_widelinks(SNUM(conn))) {
4041 char *last_dirp = NULL;
4043 unix_format(link_target);
4044 if (*link_target == '/') {
4045 /* No absolute paths allowed. */
4046 return(UNIXERROR(ERRDOS,ERRnoaccess));
4048 pstrcpy(rel_name, newname);
4049 last_dirp = strrchr_m(rel_name, '/');
4051 last_dirp[1] = '\0';
4053 pstrcpy(rel_name, "./");
4055 pstrcat(rel_name, link_target);
4057 if (!check_name(rel_name, conn)) {
4058 return(UNIXERROR(ERRDOS,ERRnoaccess));
4062 DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_LINK doing symlink %s -> %s\n",
4063 fname, link_target ));
4065 if (SMB_VFS_SYMLINK(conn,link_target,newname) != 0)
4066 return(UNIXERROR(ERRDOS,ERRnoaccess));
4068 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
4072 case SMB_SET_FILE_UNIX_HLINK:
4075 char *newname = fname;
4077 /* Set a hard link. */
4078 srvstr_get_path(inbuf, oldname, pdata, sizeof(oldname), -1, STR_TERMINATE, &status, False);
4079 if (!NT_STATUS_IS_OK(status)) {
4080 return ERROR_NT(status);
4083 DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_LINK doing hard link %s -> %s\n",
4086 status = hardlink_internals(conn, oldname, newname);
4087 if (!NT_STATUS_IS_OK(status)) {
4088 return ERROR_NT(status);
4092 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
4096 case SMB_FILE_RENAME_INFORMATION:
4105 if (total_data < 12) {
4106 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
4109 overwrite = (CVAL(pdata,0) ? True : False);
4110 root_fid = IVAL(pdata,4);
4111 len = IVAL(pdata,8);
4112 srvstr_get_path(inbuf, newname, &pdata[12], sizeof(newname), len, 0, &status, False);
4113 if (!NT_STATUS_IS_OK(status)) {
4114 return ERROR_NT(status);
4117 /* Check the new name has no '/' characters. */
4118 if (strchr_m(newname, '/'))
4119 return ERROR_NT(NT_STATUS_NOT_SUPPORTED);
4121 RESOLVE_DFSPATH(newname, conn, inbuf, outbuf);
4123 /* Create the base directory. */
4124 pstrcpy(base_name, fname);
4125 p = strrchr_m(base_name, '/');
4128 /* Append the new name. */
4129 pstrcat(base_name, "/");
4130 pstrcat(base_name, newname);
4133 DEBUG(10,("call_trans2setfilepathinfo: SMB_FILE_RENAME_INFORMATION (fnum %d) %s -> %s\n",
4134 fsp->fnum, fsp->fsp_name, base_name ));
4135 status = rename_internals_fsp(conn, fsp, base_name, 0, overwrite);
4137 DEBUG(10,("call_trans2setfilepathinfo: SMB_FILE_RENAME_INFORMATION %s -> %s\n",
4139 status = rename_internals(conn, fname, base_name, 0, overwrite);
4141 if (!NT_STATUS_IS_OK(status)) {
4142 return ERROR_NT(status);
4144 process_pending_change_notify_queue((time_t)0);
4146 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
4150 #if defined(HAVE_POSIX_ACLS)
4151 case SMB_SET_POSIX_ACL:
4153 uint16 posix_acl_version;
4154 uint16 num_file_acls;
4155 uint16 num_def_acls;
4156 BOOL valid_file_acls = True;
4157 BOOL valid_def_acls = True;
4159 if (total_data < SMB_POSIX_ACL_HEADER_SIZE) {
4160 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
4162 posix_acl_version = SVAL(pdata,0);
4163 num_file_acls = SVAL(pdata,2);
4164 num_def_acls = SVAL(pdata,4);
4166 if (num_file_acls == SMB_POSIX_IGNORE_ACE_ENTRIES) {
4167 valid_file_acls = False;
4171 if (num_def_acls == SMB_POSIX_IGNORE_ACE_ENTRIES) {
4172 valid_def_acls = False;
4176 if (posix_acl_version != SMB_POSIX_ACL_VERSION) {
4177 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
4180 if (total_data < SMB_POSIX_ACL_HEADER_SIZE +
4181 (num_file_acls+num_def_acls)*SMB_POSIX_ACL_ENTRY_SIZE) {
4182 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
4185 if (valid_file_acls && !set_unix_posix_acl(conn, fsp, fname, num_file_acls,
4186 pdata + SMB_POSIX_ACL_HEADER_SIZE)) {
4187 return(UNIXERROR(ERRDOS,ERRnoaccess));
4190 if (valid_def_acls && !set_unix_posix_default_acl(conn, fname, &sbuf, num_def_acls,
4191 pdata + SMB_POSIX_ACL_HEADER_SIZE +
4192 (num_file_acls*SMB_POSIX_ACL_ENTRY_SIZE))) {
4193 return(UNIXERROR(ERRDOS,ERRnoaccess));
4197 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
4203 return ERROR_DOS(ERRDOS,ERRunknownlevel);
4206 /* get some defaults (no modifications) if any info is zero or -1. */
4207 if (null_mtime(tvs.actime)) {
4208 tvs.actime = sbuf.st_atime;
4211 if (null_mtime(tvs.modtime)) {
4212 tvs.modtime = sbuf.st_mtime;
4215 DEBUG(6,("actime: %s " , ctime(&tvs.actime)));
4216 DEBUG(6,("modtime: %s ", ctime(&tvs.modtime)));
4217 DEBUG(6,("size: %.0f ", (double)size));
4220 if (S_ISDIR(sbuf.st_mode))
4226 DEBUG(6,("dosmode: %x\n" , dosmode));
4228 if(!((info_level == SMB_SET_FILE_END_OF_FILE_INFO) ||
4229 (info_level == SMB_SET_FILE_ALLOCATION_INFO) ||
4230 (info_level == SMB_FILE_ALLOCATION_INFORMATION) ||
4231 (info_level == SMB_FILE_END_OF_FILE_INFORMATION))) {
4234 * Only do this test if we are not explicitly
4235 * changing the size of a file.
4238 size = get_file_size(sbuf);
4242 * Try and set the times, size and mode of this file -
4243 * if they are different from the current values
4246 /* check the mode isn't different, before changing it */
4247 if ((dosmode != 0) && (dosmode != dos_mode(conn, fname, &sbuf))) {
4249 DEBUG(10,("call_trans2setfilepathinfo: file %s : setting dos mode %x\n", fname, dosmode ));
4251 if(file_set_dosmode(conn, fname, dosmode, &sbuf, False)) {
4252 DEBUG(2,("file_set_dosmode of %s failed (%s)\n", fname, strerror(errno)));
4253 return(UNIXERROR(ERRDOS,ERRnoaccess));
4258 if (size != get_file_size(sbuf)) {
4262 DEBUG(10,("call_trans2setfilepathinfo: file %s : setting new size to %.0f\n",
4263 fname, (double)size ));
4266 files_struct *new_fsp = NULL;
4267 int access_mode = 0;
4270 if(global_oplock_break) {
4271 /* Queue this file modify as we are the process of an oplock break. */
4273 DEBUG(2,("call_trans2setfilepathinfo: queueing message due to being "));
4274 DEBUGADD(2,( "in oplock break state.\n"));
4276 push_oplock_pending_smb_message(inbuf, length);
4280 new_fsp = open_file_shared(conn, fname, &sbuf,
4281 SET_OPEN_MODE(DOS_OPEN_RDWR),
4282 (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN),
4283 FILE_ATTRIBUTE_NORMAL,
4284 INTERNAL_OPEN_ONLY, &access_mode, &action);
4286 if (new_fsp == NULL)
4287 return(UNIXERROR(ERRDOS,ERRbadpath));
4288 ret = vfs_set_filelen(new_fsp, size);
4289 close_file(new_fsp,True);
4291 ret = vfs_set_filelen(fsp, size);
4295 return (UNIXERROR(ERRHRD,ERRdiskfull));
4299 * Finally the times.
4301 if (sbuf.st_mtime != tvs.modtime || sbuf.st_atime != tvs.actime) {
4304 * This was a setfileinfo on an open file.
4305 * NT does this a lot. We also need to
4306 * set the time here, as it can be read by
4307 * FindFirst/FindNext and with the patch for bug #2045
4308 * in smbd/fileio.c it ensures that this timestamp is
4309 * kept sticky even after a write. We save the request
4310 * away and will set it on file close and after a write. JRA.
4313 if (tvs.modtime != (time_t)0 && tvs.modtime != (time_t)-1) {
4314 DEBUG(10,("call_trans2setfilepathinfo: setting pending modtime to %s\n", ctime(&tvs.modtime) ));
4315 fsp_set_pending_modtime(fsp, tvs.modtime);
4319 DEBUG(10,("call_trans2setfilepathinfo: setting utimes to modified values.\n"));
4321 if(file_utime(conn, fname, &tvs)!=0) {
4322 return(UNIXERROR(ERRDOS,ERRnoaccess));
4327 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
4332 /****************************************************************************
4333 Reply to a TRANS2_MKDIR (make directory with extended attributes).
4334 ****************************************************************************/
4336 static int call_trans2mkdir(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize,
4337 char **pparams, int total_params, char **ppdata, int total_data,
4338 unsigned int max_data_bytes)
4340 char *params = *pparams;
4343 SMB_STRUCT_STAT sbuf;
4344 BOOL bad_path = False;
4345 NTSTATUS status = NT_STATUS_OK;
4347 if (!CAN_WRITE(conn))
4348 return ERROR_DOS(ERRSRV,ERRaccess);
4350 if (total_params < 4) {
4351 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
4354 srvstr_get_path(inbuf, directory, ¶ms[4], sizeof(directory), -1, STR_TERMINATE, &status, False);
4355 if (!NT_STATUS_IS_OK(status)) {
4356 return ERROR_NT(status);
4359 DEBUG(3,("call_trans2mkdir : name = %s\n", directory));
4361 unix_convert(directory,conn,0,&bad_path,&sbuf);
4363 return ERROR_NT(NT_STATUS_OBJECT_PATH_NOT_FOUND);
4365 if (check_name(directory,conn))
4366 ret = vfs_MkDir(conn,directory,unix_mode(conn,aDIR,directory,True));
4369 DEBUG(5,("call_trans2mkdir error (%s)\n", strerror(errno)));
4370 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRnoaccess);
4373 /* Realloc the parameter and data sizes */
4374 params = SMB_REALLOC(*pparams,2);
4375 if(params == NULL) {
4376 return ERROR_NT(NT_STATUS_NO_MEMORY);
4382 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
4387 /****************************************************************************
4388 Reply to a TRANS2_FINDNOTIFYFIRST (start monitoring a directory for changes).
4389 We don't actually do this - we just send a null response.
4390 ****************************************************************************/
4392 static int call_trans2findnotifyfirst(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize,
4393 char **pparams, int total_params, char **ppdata, int total_data,
4394 unsigned int max_data_bytes)
4396 static uint16 fnf_handle = 257;
4397 char *params = *pparams;
4400 if (total_params < 6) {
4401 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
4404 info_level = SVAL(params,4);
4405 DEBUG(3,("call_trans2findnotifyfirst - info_level %d\n", info_level));
4407 switch (info_level) {
4412 return ERROR_DOS(ERRDOS,ERRunknownlevel);
4415 /* Realloc the parameter and data sizes */
4416 params = SMB_REALLOC(*pparams,6);
4417 if(params == NULL) {
4418 return ERROR_NT(NT_STATUS_NO_MEMORY);
4422 SSVAL(params,0,fnf_handle);
4423 SSVAL(params,2,0); /* No changes */
4424 SSVAL(params,4,0); /* No EA errors */
4431 send_trans2_replies(outbuf, bufsize, params, 6, *ppdata, 0);
4436 /****************************************************************************
4437 Reply to a TRANS2_FINDNOTIFYNEXT (continue monitoring a directory for
4438 changes). Currently this does nothing.
4439 ****************************************************************************/
4441 static int call_trans2findnotifynext(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize,
4442 char **pparams, int total_params, char **ppdata, int total_data,
4443 unsigned int max_data_bytes)
4445 char *params = *pparams;
4447 DEBUG(3,("call_trans2findnotifynext\n"));
4449 /* Realloc the parameter and data sizes */
4450 params = SMB_REALLOC(*pparams,4);
4451 if(params == NULL) {
4452 return ERROR_NT(NT_STATUS_NO_MEMORY);
4456 SSVAL(params,0,0); /* No changes */
4457 SSVAL(params,2,0); /* No EA errors */
4459 send_trans2_replies(outbuf, bufsize, params, 4, *ppdata, 0);
4464 /****************************************************************************
4465 Reply to a TRANS2_GET_DFS_REFERRAL - Shirish Kalele <kalele@veritas.com>.
4466 ****************************************************************************/
4468 static int call_trans2getdfsreferral(connection_struct *conn, char* inbuf, char* outbuf, int length, int bufsize,
4469 char **pparams, int total_params, char **ppdata, int total_data,
4470 unsigned int max_data_bytes)
4472 char *params = *pparams;
4475 int max_referral_level;
4477 DEBUG(10,("call_trans2getdfsreferral\n"));
4479 if (total_params < 2) {
4480 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
4483 max_referral_level = SVAL(params,0);
4485 if(!lp_host_msdfs())
4486 return ERROR_DOS(ERRDOS,ERRbadfunc);
4488 srvstr_pull(inbuf, pathname, ¶ms[2], sizeof(pathname), -1, STR_TERMINATE);
4489 if((reply_size = setup_dfs_referral(conn, pathname,max_referral_level,ppdata)) < 0)
4490 return UNIXERROR(ERRDOS,ERRbadfile);
4492 SSVAL(outbuf,smb_flg2,SVAL(outbuf,smb_flg2) | FLAGS2_DFS_PATHNAMES);
4493 send_trans2_replies(outbuf,bufsize,0,0,*ppdata,reply_size);
4498 #define LMCAT_SPL 0x53
4499 #define LMFUNC_GETJOBID 0x60
4501 /****************************************************************************
4502 Reply to a TRANS2_IOCTL - used for OS/2 printing.
4503 ****************************************************************************/
4505 static int call_trans2ioctl(connection_struct *conn, char* inbuf, char* outbuf, int length, int bufsize,
4506 char **pparams, int total_params, char **ppdata, int total_data,
4507 unsigned int max_data_bytes)
4509 char *pdata = *ppdata;
4510 files_struct *fsp = file_fsp(inbuf,smb_vwv15);
4512 /* check for an invalid fid before proceeding */
4515 return(ERROR_DOS(ERRDOS,ERRbadfid));
4517 if ((SVAL(inbuf,(smb_setup+4)) == LMCAT_SPL) &&
4518 (SVAL(inbuf,(smb_setup+6)) == LMFUNC_GETJOBID)) {
4519 pdata = SMB_REALLOC(*ppdata, 32);
4521 return ERROR_NT(NT_STATUS_NO_MEMORY);
4525 /* NOTE - THIS IS ASCII ONLY AT THE MOMENT - NOT SURE IF OS/2
4526 CAN ACCEPT THIS IN UNICODE. JRA. */
4528 SSVAL(pdata,0,fsp->rap_print_jobid); /* Job number */
4529 srvstr_push( outbuf, pdata + 2, global_myname(), 15, STR_ASCII|STR_TERMINATE); /* Our NetBIOS name */
4530 srvstr_push( outbuf, pdata+18, lp_servicename(SNUM(conn)), 13, STR_ASCII|STR_TERMINATE); /* Service name */
4531 send_trans2_replies(outbuf,bufsize,*pparams,0,*ppdata,32);
4534 DEBUG(2,("Unknown TRANS2_IOCTL\n"));
4535 return ERROR_DOS(ERRSRV,ERRerror);
4539 /****************************************************************************
4540 Reply to a SMBfindclose (stop trans2 directory search).
4541 ****************************************************************************/
4543 int reply_findclose(connection_struct *conn,
4544 char *inbuf,char *outbuf,int length,int bufsize)
4547 int dptr_num=SVALS(inbuf,smb_vwv0);
4548 START_PROFILE(SMBfindclose);
4550 DEBUG(3,("reply_findclose, dptr_num = %d\n", dptr_num));
4552 dptr_close(&dptr_num);
4554 outsize = set_message(outbuf,0,0,True);
4556 DEBUG(3,("SMBfindclose dptr_num = %d\n", dptr_num));
4558 END_PROFILE(SMBfindclose);
4562 /****************************************************************************
4563 Reply to a SMBfindnclose (stop FINDNOTIFYFIRST directory search).
4564 ****************************************************************************/
4566 int reply_findnclose(connection_struct *conn,
4567 char *inbuf,char *outbuf,int length,int bufsize)
4571 START_PROFILE(SMBfindnclose);
4573 dptr_num = SVAL(inbuf,smb_vwv0);
4575 DEBUG(3,("reply_findnclose, dptr_num = %d\n", dptr_num));
4577 /* We never give out valid handles for a
4578 findnotifyfirst - so any dptr_num is ok here.
4581 outsize = set_message(outbuf,0,0,True);
4583 DEBUG(3,("SMB_findnclose dptr_num = %d\n", dptr_num));
4585 END_PROFILE(SMBfindnclose);
4589 /****************************************************************************
4590 Reply to a SMBtranss2 - just ignore it!
4591 ****************************************************************************/
4593 int reply_transs2(connection_struct *conn,
4594 char *inbuf,char *outbuf,int length,int bufsize)
4596 START_PROFILE(SMBtranss2);
4597 DEBUG(4,("Ignoring transs2 of length %d\n",length));
4598 END_PROFILE(SMBtranss2);
4602 /****************************************************************************
4603 Reply to a SMBtrans2.
4604 ****************************************************************************/
4606 int reply_trans2(connection_struct *conn,
4607 char *inbuf,char *outbuf,int length,int bufsize)
4610 unsigned int total_params = SVAL(inbuf, smb_tpscnt);
4611 unsigned int total_data =SVAL(inbuf, smb_tdscnt);
4612 unsigned int max_data_bytes = SVAL(inbuf, smb_mdrcnt);
4614 unsigned int max_param_reply = SVAL(inbuf, smb_mprcnt);
4615 unsigned int max_setup_fields = SVAL(inbuf, smb_msrcnt);
4616 BOOL close_tid = BITSETW(inbuf+smb_flags,0);
4617 BOOL no_final_response = BITSETW(inbuf+smb_flags,1);
4618 int32 timeout = IVALS(inbuf,smb_timeout);
4620 unsigned int suwcnt = SVAL(inbuf, smb_suwcnt);
4621 unsigned int tran_call = SVAL(inbuf, smb_setup0);
4622 char *params = NULL, *data = NULL;
4623 unsigned int num_params, num_params_sofar, num_data, num_data_sofar;
4624 START_PROFILE(SMBtrans2);
4626 if(global_oplock_break && (tran_call == TRANSACT2_OPEN)) {
4627 /* Queue this open message as we are the process of an
4630 DEBUG(2,("reply_trans2: queueing message trans2open due to being "));
4631 DEBUGADD(2,( "in oplock break state.\n"));
4633 push_oplock_pending_smb_message(inbuf, length);
4634 END_PROFILE(SMBtrans2);
4638 if (IS_IPC(conn) && (tran_call != TRANSACT2_OPEN)
4639 && (tran_call != TRANSACT2_GET_DFS_REFERRAL)) {
4640 END_PROFILE(SMBtrans2);
4641 return ERROR_DOS(ERRSRV,ERRaccess);
4644 outsize = set_message(outbuf,0,0,True);
4646 /* All trans2 messages we handle have smb_sucnt == 1 - ensure this
4647 is so as a sanity check */
4650 * Need to have rc=0 for ioctl to get job id for OS/2.
4651 * Network printing will fail if function is not successful.
4652 * Similar function in reply.c will be used if protocol
4653 * is LANMAN1.0 instead of LM1.2X002.
4654 * Until DosPrintSetJobInfo with PRJINFO3 is supported,
4655 * outbuf doesn't have to be set(only job id is used).
4657 if ( (suwcnt == 4) && (tran_call == TRANSACT2_IOCTL) &&
4658 (SVAL(inbuf,(smb_setup+4)) == LMCAT_SPL) &&
4659 (SVAL(inbuf,(smb_setup+6)) == LMFUNC_GETJOBID)) {
4660 DEBUG(2,("Got Trans2 DevIOctl jobid\n"));
4662 DEBUG(2,("Invalid smb_sucnt in trans2 call(%u)\n",suwcnt));
4663 DEBUG(2,("Transaction is %d\n",tran_call));
4664 END_PROFILE(SMBtrans2);
4665 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
4669 /* Allocate the space for the maximum needed parameters and data */
4670 if (total_params > 0)
4671 params = (char *)SMB_MALLOC(total_params);
4673 data = (char *)SMB_MALLOC(total_data);
4675 if ((total_params && !params) || (total_data && !data)) {
4676 DEBUG(2,("Out of memory in reply_trans2\n"));
4679 END_PROFILE(SMBtrans2);
4680 return ERROR_NT(NT_STATUS_NO_MEMORY);
4683 /* Copy the param and data bytes sent with this request into
4684 the params buffer */
4685 num_params = num_params_sofar = SVAL(inbuf,smb_pscnt);
4686 num_data = num_data_sofar = SVAL(inbuf, smb_dscnt);
4688 if (num_params > total_params || num_data > total_data)
4689 exit_server("invalid params in reply_trans2");
4692 unsigned int psoff = SVAL(inbuf, smb_psoff);
4693 if ((psoff + num_params < psoff) || (psoff + num_params < num_params))
4695 if ((smb_base(inbuf) + psoff + num_params > inbuf + length) ||
4696 (smb_base(inbuf) + psoff + num_params < smb_base(inbuf)))
4698 memcpy( params, smb_base(inbuf) + psoff, num_params);
4701 unsigned int dsoff = SVAL(inbuf, smb_dsoff);
4702 if ((dsoff + num_data < dsoff) || (dsoff + num_data < num_data))
4704 if ((smb_base(inbuf) + dsoff + num_data > inbuf + length) ||
4705 (smb_base(inbuf) + dsoff + num_data < smb_base(inbuf)))
4707 memcpy( data, smb_base(inbuf) + dsoff, num_data);
4710 srv_signing_trans_start(SVAL(inbuf,smb_mid));
4712 if(num_data_sofar < total_data || num_params_sofar < total_params) {
4713 /* We need to send an interim response then receive the rest
4714 of the parameter/data bytes */
4715 outsize = set_message(outbuf,0,0,True);
4716 srv_signing_trans_stop();
4717 if (!send_smb(smbd_server_fd(),outbuf))
4718 exit_server("reply_trans2: send_smb failed.");
4720 while (num_data_sofar < total_data ||
4721 num_params_sofar < total_params) {
4723 unsigned int param_disp;
4724 unsigned int param_off;
4725 unsigned int data_disp;
4726 unsigned int data_off;
4728 ret = receive_next_smb(inbuf,bufsize,SMB_SECONDARY_WAIT);
4731 * The sequence number for the trans reply is always
4732 * based on the last secondary received.
4735 srv_signing_trans_start(SVAL(inbuf,smb_mid));
4738 (CVAL(inbuf, smb_com) != SMBtranss2)) || !ret) {
4739 outsize = set_message(outbuf,0,0,True);
4741 DEBUG(0,("reply_trans2: Invalid secondary trans2 packet\n"));
4743 DEBUG(0,("reply_trans2: %s in getting secondary trans2 response.\n",
4744 (smb_read_error == READ_ERROR) ? "error" : "timeout" ));
4748 /* Revise total_params and total_data in case
4749 they have changed downwards */
4750 if (SVAL(inbuf, smb_tpscnt) < total_params)
4751 total_params = SVAL(inbuf, smb_tpscnt);
4752 if (SVAL(inbuf, smb_tdscnt) < total_data)
4753 total_data = SVAL(inbuf, smb_tdscnt);
4755 num_params = SVAL(inbuf,smb_spscnt);
4756 param_off = SVAL(inbuf, smb_spsoff);
4757 param_disp = SVAL(inbuf, smb_spsdisp);
4758 num_params_sofar += num_params;
4760 num_data = SVAL(inbuf, smb_sdscnt);
4761 data_off = SVAL(inbuf, smb_sdsoff);
4762 data_disp = SVAL(inbuf, smb_sdsdisp);
4763 num_data_sofar += num_data;
4765 if (num_params_sofar > total_params || num_data_sofar > total_data)
4769 if (param_disp + num_params > total_params)
4771 if ((param_disp + num_params < param_disp) ||
4772 (param_disp + num_params < num_params))
4774 if (param_disp > total_params)
4776 if ((smb_base(inbuf) + param_off + num_params >= inbuf + bufsize) ||
4777 (smb_base(inbuf) + param_off + num_params < smb_base(inbuf)))
4779 if (params + param_disp < params)
4782 memcpy( ¶ms[param_disp], smb_base(inbuf) + param_off, num_params);
4785 if (data_disp + num_data > total_data)
4787 if ((data_disp + num_data < data_disp) ||
4788 (data_disp + num_data < num_data))
4790 if (data_disp > total_data)
4792 if ((smb_base(inbuf) + data_off + num_data >= inbuf + bufsize) ||
4793 (smb_base(inbuf) + data_off + num_data < smb_base(inbuf)))
4795 if (data + data_disp < data)
4798 memcpy( &data[data_disp], smb_base(inbuf) + data_off, num_data);
4803 if (Protocol >= PROTOCOL_NT1) {
4804 SSVAL(outbuf,smb_flg2,SVAL(outbuf,smb_flg2) | 0x40); /* IS_LONG_NAME */
4807 /* Now we must call the relevant TRANS2 function */
4809 case TRANSACT2_OPEN:
4810 START_PROFILE_NESTED(Trans2_open);
4811 outsize = call_trans2open(conn, inbuf, outbuf, bufsize,
4812 ¶ms, total_params, &data, total_data, max_data_bytes);
4813 END_PROFILE_NESTED(Trans2_open);
4816 case TRANSACT2_FINDFIRST:
4817 START_PROFILE_NESTED(Trans2_findfirst);
4818 outsize = call_trans2findfirst(conn, inbuf, outbuf, bufsize,
4819 ¶ms, total_params, &data, total_data, max_data_bytes);
4820 END_PROFILE_NESTED(Trans2_findfirst);
4823 case TRANSACT2_FINDNEXT:
4824 START_PROFILE_NESTED(Trans2_findnext);
4825 outsize = call_trans2findnext(conn, inbuf, outbuf, length, bufsize,
4826 ¶ms, total_params, &data, total_data, max_data_bytes);
4827 END_PROFILE_NESTED(Trans2_findnext);
4830 case TRANSACT2_QFSINFO:
4831 START_PROFILE_NESTED(Trans2_qfsinfo);
4832 outsize = call_trans2qfsinfo(conn, inbuf, outbuf, length, bufsize,
4833 ¶ms, total_params, &data, total_data, max_data_bytes);
4834 END_PROFILE_NESTED(Trans2_qfsinfo);
4837 #ifdef HAVE_SYS_QUOTAS
4838 case TRANSACT2_SETFSINFO:
4839 START_PROFILE_NESTED(Trans2_setfsinfo);
4840 outsize = call_trans2setfsinfo(conn, inbuf, outbuf, length, bufsize,
4841 ¶ms, total_params, &data, total_data, max_data_bytes);
4842 END_PROFILE_NESTED(Trans2_setfsinfo);
4845 case TRANSACT2_QPATHINFO:
4846 case TRANSACT2_QFILEINFO:
4847 START_PROFILE_NESTED(Trans2_qpathinfo);
4848 outsize = call_trans2qfilepathinfo(conn, inbuf, outbuf, length, bufsize,
4849 ¶ms, total_params, &data, total_data, max_data_bytes);
4850 END_PROFILE_NESTED(Trans2_qpathinfo);
4852 case TRANSACT2_SETPATHINFO:
4853 case TRANSACT2_SETFILEINFO:
4854 START_PROFILE_NESTED(Trans2_setpathinfo);
4855 outsize = call_trans2setfilepathinfo(conn, inbuf, outbuf, length, bufsize,
4856 ¶ms, total_params, &data, total_data, max_data_bytes);
4857 END_PROFILE_NESTED(Trans2_setpathinfo);
4860 case TRANSACT2_FINDNOTIFYFIRST:
4861 START_PROFILE_NESTED(Trans2_findnotifyfirst);
4862 outsize = call_trans2findnotifyfirst(conn, inbuf, outbuf, length, bufsize,
4863 ¶ms, total_params, &data, total_data, max_data_bytes);
4864 END_PROFILE_NESTED(Trans2_findnotifyfirst);
4867 case TRANSACT2_FINDNOTIFYNEXT:
4868 START_PROFILE_NESTED(Trans2_findnotifynext);
4869 outsize = call_trans2findnotifynext(conn, inbuf, outbuf, length, bufsize,
4870 ¶ms, total_params, &data, total_data, max_data_bytes);
4871 END_PROFILE_NESTED(Trans2_findnotifynext);
4873 case TRANSACT2_MKDIR:
4874 START_PROFILE_NESTED(Trans2_mkdir);
4875 outsize = call_trans2mkdir(conn, inbuf, outbuf, length, bufsize,
4876 ¶ms, total_params, &data, total_data, max_data_bytes);
4877 END_PROFILE_NESTED(Trans2_mkdir);
4880 case TRANSACT2_GET_DFS_REFERRAL:
4881 START_PROFILE_NESTED(Trans2_get_dfs_referral);
4882 outsize = call_trans2getdfsreferral(conn,inbuf,outbuf,length, bufsize,
4883 ¶ms, total_params, &data, total_data, max_data_bytes);
4884 END_PROFILE_NESTED(Trans2_get_dfs_referral);
4886 case TRANSACT2_IOCTL:
4887 START_PROFILE_NESTED(Trans2_ioctl);
4888 outsize = call_trans2ioctl(conn,inbuf,outbuf,length, bufsize,
4889 ¶ms, total_params, &data, total_data, max_data_bytes);
4890 END_PROFILE_NESTED(Trans2_ioctl);
4893 /* Error in request */
4894 DEBUG(2,("Unknown request %d in trans2 call\n", tran_call));
4897 END_PROFILE(SMBtrans2);
4898 srv_signing_trans_stop();
4899 return ERROR_DOS(ERRSRV,ERRerror);
4902 /* As we do not know how many data packets will need to be
4903 returned here the various call_trans2xxxx calls
4904 must send their own. Thus a call_trans2xxx routine only
4905 returns a value other than -1 when it wants to send
4909 srv_signing_trans_stop();
4913 END_PROFILE(SMBtrans2);
4914 return outsize; /* If a correct response was needed the
4915 call_trans2xxx calls have already sent
4916 it. If outsize != -1 then it is returning */
4920 srv_signing_trans_stop();
4923 END_PROFILE(SMBtrans2);
4924 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);