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. */
399 /* integer wrap paranioa. */
400 if ((offset + namelen < offset) || (offset + namelen < namelen) ||
401 (offset > data_size) || (namelen > data_size) ||
402 (offset + namelen >= data_size)) {
405 /* Ensure the name is null terminated. */
406 if (pdata[offset + namelen] != '\0') {
409 pull_ascii_talloc(ctx, &eal->ea.name, &pdata[offset]);
414 offset += (namelen + 1); /* Go past the name + terminating zero. */
415 DLIST_ADD_END(ea_list_head, eal, tmp);
416 DEBUG(10,("read_ea_name_list: read ea name %s\n", eal->ea.name));
422 /****************************************************************************
423 Read a list of EA names and data from an incoming data buffer. Create an ea_list with them.
424 ****************************************************************************/
426 static struct ea_list *read_ea_list(TALLOC_CTX *ctx, const char *pdata, size_t data_size)
428 struct ea_list *ea_list_head = NULL;
431 if (data_size < 10) {
435 if (IVAL(pdata,0) > data_size) {
436 DEBUG(10,("read_ea_list: bad total data size (%u) > %u\n", IVAL(pdata,0), (unsigned int)data_size));
440 /* Each entry must be at least 6 bytes in length. */
441 while (offset + 6 <= data_size) {
443 struct ea_list *eal = TALLOC_ZERO_P(ctx, struct ea_list);
445 unsigned int namelen;
447 eal->ea.flags = CVAL(pdata,offset);
448 namelen = CVAL(pdata,offset + 1);
449 val_len = SVAL(pdata,offset + 2);
451 /* integer wrap paranioa. */
452 if ((offset + namelen + 5 + val_len < offset) ||
453 (offset + namelen + 5 + val_len < namelen) ||
454 (offset + namelen + 5 + val_len < val_len) ||
455 (offset > data_size) ||
456 (namelen > data_size) ||
457 (offset + namelen >= data_size)) {
461 if (offset + 4 + namelen + 1 + val_len > data_size) {
465 /* Ensure the name is null terminated. */
466 if (pdata[offset + 4 + namelen] != '\0') {
469 pull_ascii_talloc(ctx, &eal->ea.name, pdata + offset + 4);
474 eal->ea.value = data_blob(NULL, (size_t)val_len + 1);
475 if (!eal->ea.value.data) {
479 memcpy(eal->ea.value.data, pdata + offset + 4 + namelen + 1, val_len);
481 /* Ensure we're null terminated just in case we print the value. */
482 eal->ea.value.data[val_len] = '\0';
483 /* But don't count the null. */
484 eal->ea.value.length--;
486 offset += 4 + namelen + 1 + val_len;
488 DLIST_ADD_END(ea_list_head, eal, tmp);
490 DEBUG(10,("read_ea_list: read ea name %s\n", eal->ea.name));
491 dump_data(10, eal->ea.value.data, eal->ea.value.length);
497 /****************************************************************************
498 Count the total EA size needed.
499 ****************************************************************************/
501 static size_t ea_list_size(struct ea_list *ealist)
504 struct ea_list *listp;
507 for (listp = ealist; listp; listp = listp->next) {
508 push_ascii_fstring(dos_ea_name, listp->ea.name);
509 ret += 4 + strlen(dos_ea_name) + 1 + listp->ea.value.length;
511 /* Add on 4 for total length. */
519 /****************************************************************************
520 Return a union of EA's from a file list and a list of names.
521 The TALLOC context for the two lists *MUST* be identical as we steal
522 memory from one list to add to another. JRA.
523 ****************************************************************************/
525 static struct ea_list *ea_list_union(struct ea_list *name_list, struct ea_list *file_list, size_t *total_ea_len)
527 struct ea_list *nlistp, *flistp;
529 for (nlistp = name_list; nlistp; nlistp = nlistp->next) {
530 for (flistp = file_list; flistp; flistp = flistp->next) {
531 if (strequal(nlistp->ea.name, flistp->ea.name)) {
537 /* Copy the data from this entry. */
538 nlistp->ea.flags = flistp->ea.flags;
539 nlistp->ea.value = flistp->ea.value;
542 nlistp->ea.flags = 0;
543 ZERO_STRUCT(nlistp->ea.value);
547 *total_ea_len = ea_list_size(name_list);
551 /****************************************************************************
552 Send the required number of replies back.
553 We assume all fields other than the data fields are
554 set correctly for the type of call.
555 HACK ! Always assumes smb_setup field is zero.
556 ****************************************************************************/
558 static int send_trans2_replies(char *outbuf,
565 /* As we are using a protocol > LANMAN1 then the max_send
566 variable must have been set in the sessetupX call.
567 This takes precedence over the max_xmit field in the
568 global struct. These different max_xmit variables should
569 be merged as this is now too confusing */
572 int data_to_send = datasize;
573 int params_to_send = paramsize;
577 int params_sent_thistime, data_sent_thistime, total_sent_thistime;
578 int alignment_offset = 1; /* JRA. This used to be 3. Set to 1 to make netmon parse ok. */
579 int data_alignment_offset = 0;
581 /* Initially set the wcnt area to be 10 - this is true for all trans2 replies */
583 set_message(outbuf,10,0,True);
585 /* If there genuinely are no parameters or data to send just send the empty packet */
587 if(params_to_send == 0 && data_to_send == 0) {
588 if (!send_smb(smbd_server_fd(),outbuf))
589 exit_server("send_trans2_replies: send_smb failed.");
593 /* When sending params and data ensure that both are nicely aligned */
594 /* Only do this alignment when there is also data to send - else
595 can cause NT redirector problems. */
597 if (((params_to_send % 4) != 0) && (data_to_send != 0))
598 data_alignment_offset = 4 - (params_to_send % 4);
600 /* Space is bufsize minus Netbios over TCP header minus SMB header */
601 /* The alignment_offset is to align the param bytes on an even byte
602 boundary. NT 4.0 Beta needs this to work correctly. */
604 useable_space = bufsize - ((smb_buf(outbuf)+ alignment_offset+data_alignment_offset) - outbuf);
606 /* useable_space can never be more than max_send minus the alignment offset. */
608 useable_space = MIN(useable_space, max_send - (alignment_offset+data_alignment_offset));
610 while (params_to_send || data_to_send) {
611 /* Calculate whether we will totally or partially fill this packet */
613 total_sent_thistime = params_to_send + data_to_send + alignment_offset + data_alignment_offset;
615 /* We can never send more than useable_space */
617 * Note that 'useable_space' does not include the alignment offsets,
618 * but we must include the alignment offsets in the calculation of
619 * the length of the data we send over the wire, as the alignment offsets
620 * are sent here. Fix from Marc_Jacobsen@hp.com.
623 total_sent_thistime = MIN(total_sent_thistime, useable_space+ alignment_offset + data_alignment_offset);
625 set_message(outbuf, 10, total_sent_thistime, True);
627 /* Set total params and data to be sent */
628 SSVAL(outbuf,smb_tprcnt,paramsize);
629 SSVAL(outbuf,smb_tdrcnt,datasize);
631 /* Calculate how many parameters and data we can fit into
632 * this packet. Parameters get precedence
635 params_sent_thistime = MIN(params_to_send,useable_space);
636 data_sent_thistime = useable_space - params_sent_thistime;
637 data_sent_thistime = MIN(data_sent_thistime,data_to_send);
639 SSVAL(outbuf,smb_prcnt, params_sent_thistime);
641 /* smb_proff is the offset from the start of the SMB header to the
642 parameter bytes, however the first 4 bytes of outbuf are
643 the Netbios over TCP header. Thus use smb_base() to subtract
644 them from the calculation */
646 SSVAL(outbuf,smb_proff,((smb_buf(outbuf)+alignment_offset) - smb_base(outbuf)));
648 if(params_sent_thistime == 0)
649 SSVAL(outbuf,smb_prdisp,0);
651 /* Absolute displacement of param bytes sent in this packet */
652 SSVAL(outbuf,smb_prdisp,pp - params);
654 SSVAL(outbuf,smb_drcnt, data_sent_thistime);
655 if(data_sent_thistime == 0) {
656 SSVAL(outbuf,smb_droff,0);
657 SSVAL(outbuf,smb_drdisp, 0);
659 /* The offset of the data bytes is the offset of the
660 parameter bytes plus the number of parameters being sent this time */
661 SSVAL(outbuf,smb_droff,((smb_buf(outbuf)+alignment_offset) -
662 smb_base(outbuf)) + params_sent_thistime + data_alignment_offset);
663 SSVAL(outbuf,smb_drdisp, pd - pdata);
666 /* Copy the param bytes into the packet */
668 if(params_sent_thistime)
669 memcpy((smb_buf(outbuf)+alignment_offset),pp,params_sent_thistime);
671 /* Copy in the data bytes */
672 if(data_sent_thistime)
673 memcpy(smb_buf(outbuf)+alignment_offset+params_sent_thistime+
674 data_alignment_offset,pd,data_sent_thistime);
676 DEBUG(9,("t2_rep: params_sent_thistime = %d, data_sent_thistime = %d, useable_space = %d\n",
677 params_sent_thistime, data_sent_thistime, useable_space));
678 DEBUG(9,("t2_rep: params_to_send = %d, data_to_send = %d, paramsize = %d, datasize = %d\n",
679 params_to_send, data_to_send, paramsize, datasize));
681 /* Send the packet */
682 if (!send_smb(smbd_server_fd(),outbuf))
683 exit_server("send_trans2_replies: send_smb failed.");
685 pp += params_sent_thistime;
686 pd += data_sent_thistime;
688 params_to_send -= params_sent_thistime;
689 data_to_send -= data_sent_thistime;
692 if(params_to_send < 0 || data_to_send < 0) {
693 DEBUG(0,("send_trans2_replies failed sanity check pts = %d, dts = %d\n!!!",
694 params_to_send, data_to_send));
702 /****************************************************************************
703 Reply to a TRANSACT2_OPEN.
704 ****************************************************************************/
706 static int call_trans2open(connection_struct *conn, char *inbuf, char *outbuf, int bufsize,
707 char **pparams, int total_params, char **ppdata, int total_data,
708 unsigned int max_data_bytes)
710 char *params = *pparams;
715 BOOL return_additional_info;
724 int fmode=0,mtime=0,rmode;
726 SMB_STRUCT_STAT sbuf;
728 BOOL bad_path = False;
733 * Ensure we have enough parameters to perform the operation.
736 if (total_params < 29) {
737 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
740 open_mode = SVAL(params, 2);
741 open_attr = SVAL(params,6);
742 oplock_request = (((SVAL(params,0)|(1<<1))>>1) | ((SVAL(params,0)|(1<<2))>>1));
744 return_additional_info = BITSETW(params,0);
745 open_sattr = SVAL(params, 4);
746 open_time = make_unix_date3(params+8);
748 open_ofun = SVAL(params,12);
749 open_size = IVAL(params,14);
753 return(ERROR_DOS(ERRSRV,ERRaccess));
755 srvstr_get_path(inbuf, fname, pname, sizeof(fname), -1, STR_TERMINATE, &status, False);
756 if (!NT_STATUS_IS_OK(status)) {
757 return ERROR_NT(status);
760 DEBUG(3,("trans2open %s mode=%d attr=%d ofun=%d size=%d\n",
761 fname,open_mode, open_attr, open_ofun, open_size));
763 /* XXXX we need to handle passed times, sattr and flags */
765 unix_convert(fname,conn,0,&bad_path,&sbuf);
767 return ERROR_NT(NT_STATUS_OBJECT_PATH_NOT_FOUND);
770 if (!check_name(fname,conn)) {
771 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRnoaccess);
774 fsp = open_file_shared(conn,fname,&sbuf,open_mode,open_ofun,(uint32)open_attr,
775 oplock_request, &rmode,&smb_action);
778 if (open_was_deferred(SVAL(inbuf,smb_mid))) {
779 /* We have re-scheduled this call. */
780 clear_cached_errors();
783 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRnoaccess);
786 size = get_file_size(sbuf);
787 fmode = dos_mode(conn,fname,&sbuf);
788 mtime = sbuf.st_mtime;
791 close_file(fsp,False);
792 return(ERROR_DOS(ERRDOS,ERRnoaccess));
795 /* Realloc the size of parameters and data we will return */
796 params = SMB_REALLOC(*pparams, 28);
797 if( params == NULL ) {
798 return ERROR_NT(NT_STATUS_NO_MEMORY);
802 memset((char *)params,'\0',28);
803 SSVAL(params,0,fsp->fnum);
804 SSVAL(params,2,fmode);
805 put_dos_date2(params,4, mtime);
806 SIVAL(params,8, (uint32)size);
807 SSVAL(params,12,rmode);
809 if (oplock_request && lp_fake_oplocks(SNUM(conn)))
810 smb_action |= EXTENDED_OPLOCK_GRANTED;
812 SSVAL(params,18,smb_action);
815 * WARNING - this may need to be changed if SMB_INO_T <> 4 bytes.
817 SIVAL(params,20,inode);
819 /* Send the required number of replies */
820 send_trans2_replies(outbuf, bufsize, params, 28, *ppdata, 0);
825 /*********************************************************
826 Routine to check if a given string matches exactly.
827 as a special case a mask of "." does NOT match. That
828 is required for correct wildcard semantics
829 Case can be significant or not.
830 **********************************************************/
832 static BOOL exact_match(char *str,char *mask, BOOL case_sig)
834 if (mask[0] == '.' && mask[1] == 0)
837 return strcmp(str,mask)==0;
838 if (StrCaseCmp(str,mask) != 0) {
841 if (ms_has_wild(str)) {
847 /****************************************************************************
848 Return the filetype for UNIX extensions.
849 ****************************************************************************/
851 static uint32 unix_filetype(mode_t mode)
854 return UNIX_TYPE_FILE;
855 else if(S_ISDIR(mode))
856 return UNIX_TYPE_DIR;
858 else if(S_ISLNK(mode))
859 return UNIX_TYPE_SYMLINK;
862 else if(S_ISCHR(mode))
863 return UNIX_TYPE_CHARDEV;
866 else if(S_ISBLK(mode))
867 return UNIX_TYPE_BLKDEV;
870 else if(S_ISFIFO(mode))
871 return UNIX_TYPE_FIFO;
874 else if(S_ISSOCK(mode))
875 return UNIX_TYPE_SOCKET;
878 DEBUG(0,("unix_filetype: unknown filetype %u", (unsigned)mode));
879 return UNIX_TYPE_UNKNOWN;
882 /****************************************************************************
883 Map wire perms onto standard UNIX permissions. Obey share restrictions.
884 ****************************************************************************/
886 static mode_t unix_perms_from_wire( connection_struct *conn, SMB_STRUCT_STAT *pst, uint32 perms)
890 if (perms == SMB_MODE_NO_CHANGE)
893 ret |= ((perms & UNIX_X_OTH ) ? S_IXOTH : 0);
894 ret |= ((perms & UNIX_W_OTH ) ? S_IWOTH : 0);
895 ret |= ((perms & UNIX_R_OTH ) ? S_IROTH : 0);
896 ret |= ((perms & UNIX_X_GRP ) ? S_IXGRP : 0);
897 ret |= ((perms & UNIX_W_GRP ) ? S_IWGRP : 0);
898 ret |= ((perms & UNIX_R_GRP ) ? S_IRGRP : 0);
899 ret |= ((perms & UNIX_X_USR ) ? S_IXUSR : 0);
900 ret |= ((perms & UNIX_W_USR ) ? S_IWUSR : 0);
901 ret |= ((perms & UNIX_R_USR ) ? S_IRUSR : 0);
903 ret |= ((perms & UNIX_STICKY ) ? S_ISVTX : 0);
906 ret |= ((perms & UNIX_SET_GID ) ? S_ISGID : 0);
909 ret |= ((perms & UNIX_SET_UID ) ? S_ISUID : 0);
912 if (VALID_STAT(*pst) && S_ISDIR(pst->st_mode)) {
913 ret &= lp_dir_mask(SNUM(conn));
914 /* Add in force bits */
915 ret |= lp_force_dir_mode(SNUM(conn));
917 /* Apply mode mask */
918 ret &= lp_create_mask(SNUM(conn));
919 /* Add in force bits */
920 ret |= lp_force_create_mode(SNUM(conn));
926 /****************************************************************************
927 Get a level dependent lanman2 dir entry.
928 ****************************************************************************/
930 static BOOL get_lanman2_dir_entry(connection_struct *conn,
931 void *inbuf, void *outbuf,
932 char *path_mask,int dirtype,int info_level,
933 int requires_resume_key,
934 BOOL dont_descend,char **ppdata,
935 char *base_data, int space_remaining,
936 BOOL *out_of_space, BOOL *got_exact_match,
937 int *last_entry_off, struct ea_list *name_list, TALLOC_CTX *ea_ctx)
941 SMB_STRUCT_STAT sbuf;
945 char *p, *q, *pdata = *ppdata;
949 SMB_OFF_T file_size = 0;
950 SMB_BIG_UINT allocation_size = 0;
952 time_t mdate=0, adate=0, cdate=0;
954 char *last_entry_ptr;
956 int nt_extmode; /* Used for NT connections instead of mode */
957 BOOL needslash = ( conn->dirpath[strlen(conn->dirpath) -1] != '/');
960 *out_of_space = False;
961 *got_exact_match = False;
966 p = strrchr_m(path_mask,'/');
973 pstrcpy(mask, path_mask);
978 /* Needed if we run out of space */
979 long curr_dirpos = prev_dirpos = dptr_TellDir(conn->dirptr);
980 dname = dptr_ReadDirName(conn->dirptr,&curr_dirpos,&sbuf);
983 * Due to bugs in NT client redirectors we are not using
984 * resume keys any more - set them to zero.
985 * Check out the related comments in findfirst/findnext.
991 DEBUG(8,("get_lanman2_dir_entry:readdir on dirptr 0x%lx now at offset %ld\n",
992 (long)conn->dirptr,curr_dirpos));
997 pstrcpy(fname,dname);
999 if(!(got_match = *got_exact_match = exact_match(fname, mask, conn->case_sensitive)))
1000 got_match = mask_match(fname, mask, conn->case_sensitive);
1002 if(!got_match && !mangle_is_8_3(fname, False)) {
1005 * It turns out that NT matches wildcards against
1006 * both long *and* short names. This may explain some
1007 * of the wildcard wierdness from old DOS clients
1008 * that some people have been seeing.... JRA.
1012 pstrcpy( newname, fname);
1013 mangle_map( newname, True, False, SNUM(conn));
1014 if(!(got_match = *got_exact_match = exact_match(newname, mask, conn->case_sensitive)))
1015 got_match = mask_match(newname, mask, conn->case_sensitive);
1019 BOOL isdots = (strequal(fname,"..") || strequal(fname,"."));
1020 if (dont_descend && !isdots)
1023 pstrcpy(pathreal,conn->dirpath);
1025 pstrcat(pathreal,"/");
1026 pstrcat(pathreal,dname);
1028 if (INFO_LEVEL_IS_UNIX(info_level)) {
1029 if (SMB_VFS_LSTAT(conn,pathreal,&sbuf) != 0) {
1030 DEBUG(5,("get_lanman2_dir_entry:Couldn't lstat [%s] (%s)\n",
1031 pathreal,strerror(errno)));
1034 } else if (!VALID_STAT(sbuf) && SMB_VFS_STAT(conn,pathreal,&sbuf) != 0) {
1036 /* Needed to show the msdfs symlinks as
1039 if(lp_host_msdfs() &&
1040 lp_msdfs_root(SNUM(conn)) &&
1041 is_msdfs_link(conn, pathreal, NULL, NULL,
1044 DEBUG(5,("get_lanman2_dir_entry: Masquerading msdfs link %s as a directory\n", pathreal));
1045 sbuf.st_mode = (sbuf.st_mode & 0xFFF) | S_IFDIR;
1049 DEBUG(5,("get_lanman2_dir_entry:Couldn't stat [%s] (%s)\n",
1050 pathreal,strerror(errno)));
1055 mode = dos_mode(conn,pathreal,&sbuf);
1057 if (!dir_check_ftype(conn,mode,dirtype)) {
1058 DEBUG(5,("[%s] attribs didn't match %x\n",fname,dirtype));
1062 file_size = get_file_size(sbuf);
1063 allocation_size = get_allocation_size(conn,NULL,&sbuf);
1064 mdate = sbuf.st_mtime;
1065 adate = sbuf.st_atime;
1066 cdate = get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(conn)));
1068 if (lp_dos_filetime_resolution(SNUM(conn))) {
1075 /* This is necessary, as otherwise the
1076 * desktop.ini file in this folder is
1078 mode |= (lp_profile_acls(SNUM(conn)) ? aRONLY : 0);
1082 DEBUG(5,("get_lanman2_dir_entry found %s fname=%s\n",pathreal,fname));
1088 mangle_map(fname,False,True,SNUM(conn));
1093 nt_extmode = mode ? mode : FILE_ATTRIBUTE_NORMAL;
1095 switch (info_level) {
1096 case SMB_FIND_INFO_STANDARD:
1097 DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_INFO_STANDARD\n"));
1098 if(requires_resume_key) {
1102 put_dos_date2(p,l1_fdateCreation,cdate);
1103 put_dos_date2(p,l1_fdateLastAccess,adate);
1104 put_dos_date2(p,l1_fdateLastWrite,mdate);
1105 SIVAL(p,l1_cbFile,(uint32)file_size);
1106 SIVAL(p,l1_cbFileAlloc,(uint32)allocation_size);
1107 SSVAL(p,l1_attrFile,mode);
1110 p += align_string(outbuf, p, 0);
1111 len = srvstr_push(outbuf, p, fname, -1, STR_TERMINATE);
1112 if (SVAL(outbuf, smb_flg2) & FLAGS2_UNICODE_STRINGS) {
1114 SCVAL(nameptr, -1, len - 2);
1116 SCVAL(nameptr, -1, 0);
1120 SCVAL(nameptr, -1, len - 1);
1122 SCVAL(nameptr, -1, 0);
1128 case SMB_FIND_EA_SIZE:
1129 DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_EA_SIZE\n"));
1130 if(requires_resume_key) {
1134 put_dos_date2(p,l2_fdateCreation,cdate);
1135 put_dos_date2(p,l2_fdateLastAccess,adate);
1136 put_dos_date2(p,l2_fdateLastWrite,mdate);
1137 SIVAL(p,l2_cbFile,(uint32)file_size);
1138 SIVAL(p,l2_cbFileAlloc,(uint32)allocation_size);
1139 SSVAL(p,l2_attrFile,mode);
1141 unsigned int ea_size = estimate_ea_size(conn, NULL, pathreal);
1142 SIVAL(p,l2_cbList,ea_size); /* Extended attributes */
1146 len = srvstr_push(outbuf, p, fname, -1, STR_TERMINATE | STR_NOALIGN);
1147 if (SVAL(outbuf, smb_flg2) & FLAGS2_UNICODE_STRINGS) {
1160 SCVAL(nameptr,0,len);
1162 SCVAL(p,0,0); p += 1; /* Extra zero byte ? - why.. */
1165 case SMB_FIND_EA_LIST:
1167 struct ea_list *file_list = NULL;
1170 DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_EA_LIST\n"));
1174 if(requires_resume_key) {
1178 put_dos_date2(p,l2_fdateCreation,cdate);
1179 put_dos_date2(p,l2_fdateLastAccess,adate);
1180 put_dos_date2(p,l2_fdateLastWrite,mdate);
1181 SIVAL(p,l2_cbFile,(uint32)file_size);
1182 SIVAL(p,l2_cbFileAlloc,(uint32)allocation_size);
1183 SSVAL(p,l2_attrFile,mode);
1184 p += l2_cbList; /* p now points to the EA area. */
1186 file_list = get_ea_list_from_file(ea_ctx, conn, NULL, pathreal, &ea_len);
1187 name_list = ea_list_union(name_list, file_list, &ea_len);
1189 /* We need to determine if this entry will fit in the space available. */
1190 /* Max string size is 255 bytes. */
1191 if (PTR_DIFF(p + 255 + ea_len,pdata) > space_remaining) {
1192 /* Move the dirptr back to prev_dirpos */
1193 dptr_SeekDir(conn->dirptr, prev_dirpos);
1194 *out_of_space = True;
1195 DEBUG(9,("get_lanman2_dir_entry: out of space\n"));
1196 return False; /* Not finished - just out of space */
1199 /* Push the ea_data followed by the name. */
1200 p += fill_ea_buffer(ea_ctx, p, space_remaining, conn, name_list);
1202 len = srvstr_push(outbuf, p + 1, fname, -1, STR_TERMINATE | STR_NOALIGN);
1203 if (SVAL(outbuf, smb_flg2) & FLAGS2_UNICODE_STRINGS) {
1216 SCVAL(nameptr,0,len);
1218 SCVAL(p,0,0); p += 1; /* Extra zero byte ? - why.. */
1222 case SMB_FIND_FILE_BOTH_DIRECTORY_INFO:
1223 DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_FILE_BOTH_DIRECTORY_INFO\n"));
1224 was_8_3 = mangle_is_8_3(fname, True);
1226 SIVAL(p,0,reskey); p += 4;
1227 put_long_date(p,cdate); p += 8;
1228 put_long_date(p,adate); p += 8;
1229 put_long_date(p,mdate); p += 8;
1230 put_long_date(p,mdate); p += 8;
1231 SOFF_T(p,0,file_size); p += 8;
1232 SOFF_T(p,0,allocation_size); p += 8;
1233 SIVAL(p,0,nt_extmode); p += 4;
1234 q = p; p += 4; /* q is placeholder for name length. */
1236 unsigned int ea_size = estimate_ea_size(conn, NULL, pathreal);
1237 SIVAL(p,0,ea_size); /* Extended attributes */
1240 /* Clear the short name buffer. This is
1241 * IMPORTANT as not doing so will trigger
1242 * a Win2k client bug. JRA.
1245 if (!was_8_3 && lp_manglednames(SNUM(conn))) {
1246 pstring mangled_name;
1247 pstrcpy(mangled_name, fname);
1248 mangle_map(mangled_name,True,True,SNUM(conn));
1249 mangled_name[12] = 0;
1250 len = srvstr_push(outbuf, p+2, mangled_name, 24, STR_UPPER|STR_UNICODE);
1257 len = srvstr_push(outbuf, p, fname, -1, STR_TERMINATE_ASCII);
1260 len = PTR_DIFF(p, pdata);
1261 len = (len + 3) & ~3;
1266 case SMB_FIND_FILE_DIRECTORY_INFO:
1267 DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_FILE_DIRECTORY_INFO\n"));
1269 SIVAL(p,0,reskey); p += 4;
1270 put_long_date(p,cdate); p += 8;
1271 put_long_date(p,adate); p += 8;
1272 put_long_date(p,mdate); p += 8;
1273 put_long_date(p,mdate); p += 8;
1274 SOFF_T(p,0,file_size); p += 8;
1275 SOFF_T(p,0,allocation_size); p += 8;
1276 SIVAL(p,0,nt_extmode); p += 4;
1277 len = srvstr_push(outbuf, p + 4, fname, -1, STR_TERMINATE_ASCII);
1280 len = PTR_DIFF(p, pdata);
1281 len = (len + 3) & ~3;
1286 case SMB_FIND_FILE_FULL_DIRECTORY_INFO:
1287 DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_FILE_FULL_DIRECTORY_INFO\n"));
1289 SIVAL(p,0,reskey); p += 4;
1290 put_long_date(p,cdate); p += 8;
1291 put_long_date(p,adate); p += 8;
1292 put_long_date(p,mdate); p += 8;
1293 put_long_date(p,mdate); p += 8;
1294 SOFF_T(p,0,file_size); p += 8;
1295 SOFF_T(p,0,allocation_size); p += 8;
1296 SIVAL(p,0,nt_extmode); p += 4;
1297 q = p; p += 4; /* q is placeholder for name length. */
1299 unsigned int ea_size = estimate_ea_size(conn, NULL, pathreal);
1300 SIVAL(p,0,ea_size); /* Extended attributes */
1303 len = srvstr_push(outbuf, p, fname, -1, STR_TERMINATE_ASCII);
1307 len = PTR_DIFF(p, pdata);
1308 len = (len + 3) & ~3;
1313 case SMB_FIND_FILE_NAMES_INFO:
1314 DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_FILE_NAMES_INFO\n"));
1316 SIVAL(p,0,reskey); p += 4;
1318 /* this must *not* be null terminated or w2k gets in a loop trying to set an
1319 acl on a dir (tridge) */
1320 len = srvstr_push(outbuf, p, fname, -1, STR_TERMINATE_ASCII);
1323 len = PTR_DIFF(p, pdata);
1324 len = (len + 3) & ~3;
1329 case SMB_FIND_ID_FULL_DIRECTORY_INFO:
1330 DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_ID_FULL_DIRECTORY_INFO\n"));
1332 SIVAL(p,0,reskey); p += 4;
1333 put_long_date(p,cdate); p += 8;
1334 put_long_date(p,adate); p += 8;
1335 put_long_date(p,mdate); p += 8;
1336 put_long_date(p,mdate); p += 8;
1337 SOFF_T(p,0,file_size); p += 8;
1338 SOFF_T(p,0,allocation_size); p += 8;
1339 SIVAL(p,0,nt_extmode); p += 4;
1340 q = p; p += 4; /* q is placeholder for name length. */
1342 unsigned int ea_size = estimate_ea_size(conn, NULL, pathreal);
1343 SIVAL(p,0,ea_size); /* Extended attributes */
1346 SIVAL(p,0,0); p += 4; /* Unknown - reserved ? */
1347 SIVAL(p,0,sbuf.st_dev); p += 4;
1348 SIVAL(p,0,sbuf.st_ino); p += 4;
1349 len = srvstr_push(outbuf, p, fname, -1, STR_TERMINATE_ASCII);
1352 len = PTR_DIFF(p, pdata);
1353 len = (len + 3) & ~3;
1358 case SMB_FIND_ID_BOTH_DIRECTORY_INFO:
1359 DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_ID_BOTH_DIRECTORY_INFO\n"));
1360 was_8_3 = mangle_is_8_3(fname, True);
1362 SIVAL(p,0,reskey); p += 4;
1363 put_long_date(p,cdate); p += 8;
1364 put_long_date(p,adate); p += 8;
1365 put_long_date(p,mdate); p += 8;
1366 put_long_date(p,mdate); p += 8;
1367 SOFF_T(p,0,file_size); p += 8;
1368 SOFF_T(p,0,allocation_size); p += 8;
1369 SIVAL(p,0,nt_extmode); p += 4;
1370 q = p; p += 4; /* q is placeholder for name length */
1372 unsigned int ea_size = estimate_ea_size(conn, NULL, pathreal);
1373 SIVAL(p,0,ea_size); /* Extended attributes */
1376 /* Clear the short name buffer. This is
1377 * IMPORTANT as not doing so will trigger
1378 * a Win2k client bug. JRA.
1381 if (!was_8_3 && lp_manglednames(SNUM(conn))) {
1382 pstring mangled_name;
1383 pstrcpy(mangled_name, fname);
1384 mangle_map(mangled_name,True,True,SNUM(conn));
1385 mangled_name[12] = 0;
1386 len = srvstr_push(outbuf, p+2, mangled_name, 24, STR_UPPER|STR_UNICODE);
1393 SSVAL(p,0,0); p += 2; /* Reserved ? */
1394 SIVAL(p,0,sbuf.st_dev); p += 4;
1395 SIVAL(p,0,sbuf.st_ino); p += 4;
1396 len = srvstr_push(outbuf, p, fname, -1, STR_TERMINATE_ASCII);
1399 len = PTR_DIFF(p, pdata);
1400 len = (len + 3) & ~3;
1405 /* CIFS UNIX Extension. */
1407 case SMB_FIND_FILE_UNIX:
1408 DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_FILE_UNIX\n"));
1410 SIVAL(p,0,reskey); p+= 4; /* Used for continuing search. */
1412 /* Begin of SMB_QUERY_FILE_UNIX_BASIC */
1413 SOFF_T(p,0,get_file_size(sbuf)); /* File size 64 Bit */
1416 SOFF_T(p,0,get_allocation_size(conn,NULL,&sbuf)); /* Number of bytes used on disk - 64 Bit */
1419 put_long_date(p,sbuf.st_ctime); /* Inode change Time 64 Bit */
1420 put_long_date(p+8,sbuf.st_atime); /* Last access time 64 Bit */
1421 put_long_date(p+16,sbuf.st_mtime); /* Last modification time 64 Bit */
1424 SIVAL(p,0,sbuf.st_uid); /* user id for the owner */
1428 SIVAL(p,0,sbuf.st_gid); /* group id of owner */
1432 SIVAL(p,0,unix_filetype(sbuf.st_mode));
1435 SIVAL(p,0,unix_dev_major(sbuf.st_rdev)); /* Major device number if type is device */
1439 SIVAL(p,0,unix_dev_minor(sbuf.st_rdev)); /* Minor device number if type is device */
1443 SINO_T(p,0,(SMB_INO_T)sbuf.st_ino); /* inode number */
1446 SIVAL(p,0, unix_perms_to_wire(sbuf.st_mode)); /* Standard UNIX file permissions */
1450 SIVAL(p,0,sbuf.st_nlink); /* number of hard links */
1454 len = srvstr_push(outbuf, p, fname, -1, STR_TERMINATE);
1457 len = PTR_DIFF(p, pdata);
1458 len = (len + 3) & ~3;
1459 SIVAL(pdata,0,len); /* Offset from this structure to the beginning of the next one */
1461 /* End of SMB_QUERY_FILE_UNIX_BASIC */
1470 if (PTR_DIFF(p,pdata) > space_remaining) {
1471 /* Move the dirptr back to prev_dirpos */
1472 dptr_SeekDir(conn->dirptr, prev_dirpos);
1473 *out_of_space = True;
1474 DEBUG(9,("get_lanman2_dir_entry: out of space\n"));
1475 return False; /* Not finished - just out of space */
1478 /* Setup the last entry pointer, as an offset from base_data */
1479 *last_entry_off = PTR_DIFF(last_entry_ptr,base_data);
1480 /* Advance the data pointer to the next slot */
1486 /****************************************************************************
1487 Reply to a TRANS2_FINDFIRST.
1488 ****************************************************************************/
1490 static int call_trans2findfirst(connection_struct *conn, char *inbuf, char *outbuf, int bufsize,
1491 char **pparams, int total_params, char **ppdata, int total_data,
1492 unsigned int max_data_bytes)
1494 /* We must be careful here that we don't return more than the
1495 allowed number of data bytes. If this means returning fewer than
1496 maxentries then so be it. We assume that the redirector has
1497 enough room for the fixed number of parameter bytes it has
1499 char *params = *pparams;
1500 char *pdata = *ppdata;
1501 int dirtype = SVAL(params,0);
1502 int maxentries = SVAL(params,2);
1503 uint16 findfirst_flags = SVAL(params,4);
1504 BOOL close_after_first = (findfirst_flags & FLAG_TRANS2_FIND_CLOSE);
1505 BOOL close_if_end = (findfirst_flags & FLAG_TRANS2_FIND_CLOSE_IF_END);
1506 BOOL requires_resume_key = (findfirst_flags & FLAG_TRANS2_FIND_REQUIRE_RESUME);
1507 int info_level = SVAL(params,6);
1511 int last_entry_off=0;
1515 BOOL finished = False;
1516 BOOL dont_descend = False;
1517 BOOL out_of_space = False;
1518 int space_remaining;
1519 BOOL bad_path = False;
1520 SMB_STRUCT_STAT sbuf;
1521 TALLOC_CTX *ea_ctx = NULL;
1522 struct ea_list *ea_list = NULL;
1523 NTSTATUS ntstatus = NT_STATUS_OK;
1525 if (total_params < 12) {
1526 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
1529 *directory = *mask = 0;
1531 DEBUG(3,("call_trans2findfirst: dirtype = %d, maxentries = %d, close_after_first=%d, \
1532 close_if_end = %d requires_resume_key = %d level = 0x%x, max_data_bytes = %d\n",
1533 dirtype, maxentries, close_after_first, close_if_end, requires_resume_key,
1534 info_level, max_data_bytes));
1537 /* W2K3 seems to treat zero as 1. */
1541 switch (info_level) {
1542 case SMB_FIND_INFO_STANDARD:
1543 case SMB_FIND_EA_SIZE:
1544 case SMB_FIND_EA_LIST:
1545 case SMB_FIND_FILE_DIRECTORY_INFO:
1546 case SMB_FIND_FILE_FULL_DIRECTORY_INFO:
1547 case SMB_FIND_FILE_NAMES_INFO:
1548 case SMB_FIND_FILE_BOTH_DIRECTORY_INFO:
1549 case SMB_FIND_ID_FULL_DIRECTORY_INFO:
1550 case SMB_FIND_ID_BOTH_DIRECTORY_INFO:
1552 case SMB_FIND_FILE_UNIX:
1553 if (!lp_unix_extensions())
1554 return(ERROR_DOS(ERRDOS,ERRunknownlevel));
1557 return(ERROR_DOS(ERRDOS,ERRunknownlevel));
1560 srvstr_get_path(inbuf, directory, params+12, sizeof(directory), -1, STR_TERMINATE, &ntstatus, True);
1561 if (!NT_STATUS_IS_OK(ntstatus)) {
1562 return ERROR_NT(ntstatus);
1565 RESOLVE_DFSPATH(directory, conn, inbuf, outbuf);
1567 unix_convert(directory,conn,0,&bad_path,&sbuf);
1569 return ERROR_NT(NT_STATUS_OBJECT_PATH_NOT_FOUND);
1571 if(!check_name(directory,conn)) {
1572 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRbadpath);
1575 p = strrchr_m(directory,'/');
1577 /* Windows and OS/2 systems treat search on the root '\' as if it were '\*' */
1578 if((directory[0] == '.') && (directory[1] == '\0'))
1581 pstrcpy(mask,directory);
1582 pstrcpy(directory,"./");
1588 DEBUG(5,("dir=%s, mask = %s\n",directory, mask));
1590 if (info_level == SMB_FIND_EA_LIST) {
1593 if (total_data < 4) {
1594 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
1597 ea_size = IVAL(pdata,0);
1598 if (ea_size != total_data) {
1599 DEBUG(4,("call_trans2findfirst: Rejecting EA request with incorrect \
1600 total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pdata,0) ));
1601 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
1604 if (!lp_ea_support(SNUM(conn))) {
1605 return ERROR_DOS(ERRDOS,ERReasnotsupported);
1608 if ((ea_ctx = talloc_init("findnext_ea_list")) == NULL) {
1609 return ERROR_NT(NT_STATUS_NO_MEMORY);
1612 /* Pull out the list of names. */
1613 ea_list = read_ea_name_list(ea_ctx, pdata, ea_size);
1615 talloc_destroy(ea_ctx);
1616 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
1620 pdata = SMB_REALLOC(*ppdata, max_data_bytes + DIR_ENTRY_SAFETY_MARGIN);
1621 if( pdata == NULL ) {
1622 talloc_destroy(ea_ctx);
1623 return ERROR_NT(NT_STATUS_NO_MEMORY);
1627 memset((char *)pdata,'\0',max_data_bytes + DIR_ENTRY_SAFETY_MARGIN);
1629 /* Realloc the params space */
1630 params = SMB_REALLOC(*pparams, 10);
1631 if (params == NULL) {
1632 talloc_destroy(ea_ctx);
1633 return ERROR_NT(NT_STATUS_NO_MEMORY);
1637 dptr_num = dptr_create(conn,directory, False, True ,SVAL(inbuf,smb_pid));
1639 talloc_destroy(ea_ctx);
1640 return(UNIXERROR(ERRDOS,ERRbadfile));
1643 /* Save the wildcard match and attribs we are using on this directory -
1644 needed as lanman2 assumes these are being saved between calls */
1646 if (!dptr_set_wcard_and_attributes(dptr_num, mask, dirtype)) {
1647 dptr_close(&dptr_num);
1648 talloc_destroy(ea_ctx);
1649 return ERROR_NT(NT_STATUS_NO_MEMORY);
1652 DEBUG(4,("dptr_num is %d, wcard = %s, attr = %d\n",dptr_num, mask, dirtype));
1654 /* We don't need to check for VOL here as this is returned by
1655 a different TRANS2 call. */
1657 DEBUG(8,("dirpath=<%s> dontdescend=<%s>\n", conn->dirpath,lp_dontdescend(SNUM(conn))));
1658 if (in_list(conn->dirpath,lp_dontdescend(SNUM(conn)),conn->case_sensitive))
1659 dont_descend = True;
1662 space_remaining = max_data_bytes;
1663 out_of_space = False;
1665 for (i=0;(i<maxentries) && !finished && !out_of_space;i++) {
1666 BOOL got_exact_match = False;
1668 /* this is a heuristic to avoid seeking the dirptr except when
1669 absolutely necessary. It allows for a filename of about 40 chars */
1670 if (space_remaining < DIRLEN_GUESS && numentries > 0) {
1671 out_of_space = True;
1674 finished = !get_lanman2_dir_entry(conn,
1676 mask,dirtype,info_level,
1677 requires_resume_key,dont_descend,
1678 &p,pdata,space_remaining, &out_of_space, &got_exact_match,
1679 &last_entry_off, ea_list, ea_ctx);
1682 if (finished && out_of_space)
1685 if (!finished && !out_of_space)
1689 * As an optimisation if we know we aren't looking
1690 * for a wildcard name (ie. the name matches the wildcard exactly)
1691 * then we can finish on any (first) match.
1692 * This speeds up large directory searches. JRA.
1698 space_remaining = max_data_bytes - PTR_DIFF(p,pdata);
1701 talloc_destroy(ea_ctx);
1703 /* Check if we can close the dirptr */
1704 if(close_after_first || (finished && close_if_end)) {
1705 DEBUG(5,("call_trans2findfirst - (2) closing dptr_num %d\n", dptr_num));
1706 dptr_close(&dptr_num);
1710 * If there are no matching entries we must return ERRDOS/ERRbadfile -
1711 * from observation of NT. NB. This changes to ERRDOS,ERRnofiles if
1712 * the protocol level is less than NT1. Tested with smbclient. JRA.
1713 * This should fix the OS/2 client bug #2335.
1716 if(numentries == 0) {
1717 dptr_close(&dptr_num);
1718 if (Protocol < PROTOCOL_NT1) {
1719 return ERROR_DOS(ERRDOS,ERRnofiles);
1721 return ERROR_BOTH(NT_STATUS_NO_SUCH_FILE,ERRDOS,ERRbadfile);
1725 /* At this point pdata points to numentries directory entries. */
1727 /* Set up the return parameter block */
1728 SSVAL(params,0,dptr_num);
1729 SSVAL(params,2,numentries);
1730 SSVAL(params,4,finished);
1731 SSVAL(params,6,0); /* Never an EA error */
1732 SSVAL(params,8,last_entry_off);
1734 send_trans2_replies( outbuf, bufsize, params, 10, pdata, PTR_DIFF(p,pdata));
1736 if ((! *directory) && dptr_path(dptr_num))
1737 slprintf(directory,sizeof(directory)-1, "(%s)",dptr_path(dptr_num));
1739 DEBUG( 4, ( "%s mask=%s directory=%s dirtype=%d numentries=%d\n",
1740 smb_fn_name(CVAL(inbuf,smb_com)),
1741 mask, directory, dirtype, numentries ) );
1744 * Force a name mangle here to ensure that the
1745 * mask as an 8.3 name is top of the mangled cache.
1746 * The reasons for this are subtle. Don't remove
1747 * this code unless you know what you are doing
1748 * (see PR#13758). JRA.
1751 if(!mangle_is_8_3_wildcards( mask, False))
1752 mangle_map(mask, True, True, SNUM(conn));
1757 /****************************************************************************
1758 Reply to a TRANS2_FINDNEXT.
1759 ****************************************************************************/
1761 static int call_trans2findnext(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize,
1762 char **pparams, int total_params, char **ppdata, int total_data,
1763 unsigned int max_data_bytes)
1765 /* We must be careful here that we don't return more than the
1766 allowed number of data bytes. If this means returning fewer than
1767 maxentries then so be it. We assume that the redirector has
1768 enough room for the fixed number of parameter bytes it has
1770 char *params = *pparams;
1771 char *pdata = *ppdata;
1772 int dptr_num = SVAL(params,0);
1773 int maxentries = SVAL(params,2);
1774 uint16 info_level = SVAL(params,4);
1775 uint32 resume_key = IVAL(params,6);
1776 uint16 findnext_flags = SVAL(params,10);
1777 BOOL close_after_request = (findnext_flags & FLAG_TRANS2_FIND_CLOSE);
1778 BOOL close_if_end = (findnext_flags & FLAG_TRANS2_FIND_CLOSE_IF_END);
1779 BOOL requires_resume_key = (findnext_flags & FLAG_TRANS2_FIND_REQUIRE_RESUME);
1780 BOOL continue_bit = (findnext_flags & FLAG_TRANS2_FIND_CONTINUE);
1781 pstring resume_name;
1787 int i, last_entry_off=0;
1788 BOOL finished = False;
1789 BOOL dont_descend = False;
1790 BOOL out_of_space = False;
1791 int space_remaining;
1792 TALLOC_CTX *ea_ctx = NULL;
1793 struct ea_list *ea_list = NULL;
1794 NTSTATUS ntstatus = NT_STATUS_OK;
1796 if (total_params < 12) {
1797 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
1800 *mask = *directory = *resume_name = 0;
1802 srvstr_get_path(inbuf, resume_name, params+12, sizeof(resume_name), -1, STR_TERMINATE, &ntstatus, True);
1803 if (!NT_STATUS_IS_OK(ntstatus)) {
1804 /* Win9x or OS/2 can send a resume name of ".." or ".". This will cause the parser to
1805 complain (it thinks we're asking for the directory above the shared
1806 path or an invalid name). Catch this as the resume name is only compared, never used in
1807 a file access. JRA. */
1808 if (NT_STATUS_EQUAL(ntstatus,NT_STATUS_OBJECT_PATH_SYNTAX_BAD)) {
1809 pstrcpy(resume_name, "..");
1810 } else if (NT_STATUS_EQUAL(ntstatus,NT_STATUS_OBJECT_NAME_INVALID)) {
1811 pstrcpy(resume_name, ".");
1813 return ERROR_NT(ntstatus);
1817 DEBUG(3,("call_trans2findnext: dirhandle = %d, max_data_bytes = %d, maxentries = %d, \
1818 close_after_request=%d, close_if_end = %d requires_resume_key = %d \
1819 resume_key = %d resume name = %s continue=%d level = %d\n",
1820 dptr_num, max_data_bytes, maxentries, close_after_request, close_if_end,
1821 requires_resume_key, resume_key, resume_name, continue_bit, info_level));
1824 /* W2K3 seems to treat zero as 1. */
1828 switch (info_level) {
1829 case SMB_FIND_INFO_STANDARD:
1830 case SMB_FIND_EA_SIZE:
1831 case SMB_FIND_EA_LIST:
1832 case SMB_FIND_FILE_DIRECTORY_INFO:
1833 case SMB_FIND_FILE_FULL_DIRECTORY_INFO:
1834 case SMB_FIND_FILE_NAMES_INFO:
1835 case SMB_FIND_FILE_BOTH_DIRECTORY_INFO:
1837 case SMB_FIND_FILE_UNIX:
1838 if (!lp_unix_extensions())
1839 return(ERROR_DOS(ERRDOS,ERRunknownlevel));
1842 return ERROR_DOS(ERRDOS,ERRunknownlevel);
1845 if (info_level == SMB_FIND_EA_LIST) {
1848 if (total_data < 4) {
1849 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
1852 ea_size = IVAL(pdata,0);
1853 if (ea_size != total_data) {
1854 DEBUG(4,("call_trans2findnext: Rejecting EA request with incorrect \
1855 total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pdata,0) ));
1856 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
1859 if (!lp_ea_support(SNUM(conn))) {
1860 return ERROR_DOS(ERRDOS,ERReasnotsupported);
1863 if ((ea_ctx = talloc_init("findnext_ea_list")) == NULL) {
1864 return ERROR_NT(NT_STATUS_NO_MEMORY);
1867 /* Pull out the list of names. */
1868 ea_list = read_ea_name_list(ea_ctx, pdata, ea_size);
1870 talloc_destroy(ea_ctx);
1871 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
1875 pdata = SMB_REALLOC( *ppdata, max_data_bytes + DIR_ENTRY_SAFETY_MARGIN);
1877 talloc_destroy(ea_ctx);
1878 return ERROR_NT(NT_STATUS_NO_MEMORY);
1882 memset((char *)pdata,'\0',max_data_bytes + DIR_ENTRY_SAFETY_MARGIN);
1884 /* Realloc the params space */
1885 params = SMB_REALLOC(*pparams, 6*SIZEOFWORD);
1886 if( params == NULL ) {
1887 talloc_destroy(ea_ctx);
1888 return ERROR_NT(NT_STATUS_NO_MEMORY);
1893 /* Check that the dptr is valid */
1894 if(!(conn->dirptr = dptr_fetch_lanman2(dptr_num))) {
1895 talloc_destroy(ea_ctx);
1896 return ERROR_DOS(ERRDOS,ERRnofiles);
1899 string_set(&conn->dirpath,dptr_path(dptr_num));
1901 /* Get the wildcard mask from the dptr */
1902 if((p = dptr_wcard(dptr_num))== NULL) {
1903 DEBUG(2,("dptr_num %d has no wildcard\n", dptr_num));
1904 talloc_destroy(ea_ctx);
1905 return ERROR_DOS(ERRDOS,ERRnofiles);
1909 pstrcpy(directory,conn->dirpath);
1911 /* Get the attr mask from the dptr */
1912 dirtype = dptr_attr(dptr_num);
1914 DEBUG(3,("dptr_num is %d, mask = %s, attr = %x, dirptr=(0x%lX,%ld)\n",
1915 dptr_num, mask, dirtype,
1917 dptr_TellDir(conn->dirptr)));
1919 /* We don't need to check for VOL here as this is returned by
1920 a different TRANS2 call. */
1922 DEBUG(8,("dirpath=<%s> dontdescend=<%s>\n",conn->dirpath,lp_dontdescend(SNUM(conn))));
1923 if (in_list(conn->dirpath,lp_dontdescend(SNUM(conn)),conn->case_sensitive))
1924 dont_descend = True;
1927 space_remaining = max_data_bytes;
1928 out_of_space = False;
1931 * Seek to the correct position. We no longer use the resume key but
1932 * depend on the last file name instead.
1935 if(*resume_name && !continue_bit) {
1938 long current_pos = 0;
1940 * Remember, mangle_map is called by
1941 * get_lanman2_dir_entry(), so the resume name
1942 * could be mangled. Ensure we check the unmangled name.
1945 if (mangle_is_mangled(resume_name)) {
1946 mangle_check_cache(resume_name, sizeof(resume_name)-1);
1950 * Fix for NT redirector problem triggered by resume key indexes
1951 * changing between directory scans. We now return a resume key of 0
1952 * and instead look for the filename to continue from (also given
1953 * to us by NT/95/smbfs/smbclient). If no other scans have been done between the
1954 * findfirst/findnext (as is usual) then the directory pointer
1955 * should already be at the correct place.
1958 finished = !dptr_SearchDir(conn->dirptr, resume_name, ¤t_pos, &st);
1959 } /* end if resume_name && !continue_bit */
1961 for (i=0;(i<(int)maxentries) && !finished && !out_of_space ;i++) {
1962 BOOL got_exact_match = False;
1964 /* this is a heuristic to avoid seeking the dirptr except when
1965 absolutely necessary. It allows for a filename of about 40 chars */
1966 if (space_remaining < DIRLEN_GUESS && numentries > 0) {
1967 out_of_space = True;
1970 finished = !get_lanman2_dir_entry(conn,
1972 mask,dirtype,info_level,
1973 requires_resume_key,dont_descend,
1974 &p,pdata,space_remaining, &out_of_space, &got_exact_match,
1975 &last_entry_off, ea_list, ea_ctx);
1978 if (finished && out_of_space)
1981 if (!finished && !out_of_space)
1985 * As an optimisation if we know we aren't looking
1986 * for a wildcard name (ie. the name matches the wildcard exactly)
1987 * then we can finish on any (first) match.
1988 * This speeds up large directory searches. JRA.
1994 space_remaining = max_data_bytes - PTR_DIFF(p,pdata);
1997 talloc_destroy(ea_ctx);
1999 /* Check if we can close the dirptr */
2000 if(close_after_request || (finished && close_if_end)) {
2001 DEBUG(5,("call_trans2findnext: closing dptr_num = %d\n", dptr_num));
2002 dptr_close(&dptr_num); /* This frees up the saved mask */
2005 /* Set up the return parameter block */
2006 SSVAL(params,0,numentries);
2007 SSVAL(params,2,finished);
2008 SSVAL(params,4,0); /* Never an EA error */
2009 SSVAL(params,6,last_entry_off);
2011 send_trans2_replies( outbuf, bufsize, params, 8, pdata, PTR_DIFF(p,pdata));
2013 if ((! *directory) && dptr_path(dptr_num))
2014 slprintf(directory,sizeof(directory)-1, "(%s)",dptr_path(dptr_num));
2016 DEBUG( 3, ( "%s mask=%s directory=%s dirtype=%d numentries=%d\n",
2017 smb_fn_name(CVAL(inbuf,smb_com)),
2018 mask, directory, dirtype, numentries ) );
2023 /****************************************************************************
2024 Reply to a TRANS2_QFSINFO (query filesystem info).
2025 ****************************************************************************/
2027 static int call_trans2qfsinfo(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize,
2028 char **pparams, int total_params, char **ppdata, int total_data,
2029 unsigned int max_data_bytes)
2031 char *pdata = *ppdata;
2032 char *params = *pparams;
2033 uint16 info_level = SVAL(params,0);
2036 char *vname = volume_label(SNUM(conn));
2037 int snum = SNUM(conn);
2038 char *fstype = lp_fstype(SNUM(conn));
2041 DEBUG(3,("call_trans2qfsinfo: level = %d\n", info_level));
2043 if(SMB_VFS_STAT(conn,".",&st)!=0) {
2044 DEBUG(2,("call_trans2qfsinfo: stat of . failed (%s)\n", strerror(errno)));
2045 return ERROR_DOS(ERRSRV,ERRinvdevice);
2048 pdata = SMB_REALLOC(*ppdata, max_data_bytes + DIR_ENTRY_SAFETY_MARGIN);
2049 if ( pdata == NULL ) {
2050 return ERROR_NT(NT_STATUS_NO_MEMORY);
2054 memset((char *)pdata,'\0',max_data_bytes + DIR_ENTRY_SAFETY_MARGIN);
2056 switch (info_level) {
2057 case SMB_INFO_ALLOCATION:
2059 SMB_BIG_UINT dfree,dsize,bsize,block_size,sectors_per_unit,bytes_per_sector;
2061 if (SMB_VFS_DISK_FREE(conn,".",False,&bsize,&dfree,&dsize) == (SMB_BIG_UINT)-1) {
2062 return(UNIXERROR(ERRHRD,ERRgeneral));
2065 block_size = lp_block_size(snum);
2066 if (bsize < block_size) {
2067 SMB_BIG_UINT factor = block_size/bsize;
2072 if (bsize > block_size) {
2073 SMB_BIG_UINT factor = bsize/block_size;
2078 bytes_per_sector = 512;
2079 sectors_per_unit = bsize/bytes_per_sector;
2081 DEBUG(5,("call_trans2qfsinfo : SMB_INFO_ALLOCATION id=%x, bsize=%u, cSectorUnit=%u, \
2082 cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)st.st_dev, (unsigned int)bsize, (unsigned int)sectors_per_unit,
2083 (unsigned int)bytes_per_sector, (unsigned int)dsize, (unsigned int)dfree));
2085 SIVAL(pdata,l1_idFileSystem,st.st_dev);
2086 SIVAL(pdata,l1_cSectorUnit,sectors_per_unit);
2087 SIVAL(pdata,l1_cUnit,dsize);
2088 SIVAL(pdata,l1_cUnitAvail,dfree);
2089 SSVAL(pdata,l1_cbSector,bytes_per_sector);
2093 case SMB_INFO_VOLUME:
2094 /* Return volume name */
2096 * Add volume serial number - hash of a combination of
2097 * the called hostname and the service name.
2099 SIVAL(pdata,0,str_checksum(lp_servicename(snum)) ^ (str_checksum(get_local_machine_name())<<16) );
2100 len = srvstr_push(outbuf, pdata+l2_vol_szVolLabel, vname, -1, STR_NOALIGN);
2101 SCVAL(pdata,l2_vol_cch,len);
2102 data_len = l2_vol_szVolLabel + len;
2103 DEBUG(5,("call_trans2qfsinfo : time = %x, namelen = %d, name = %s\n",
2104 (unsigned)st.st_ctime, len, vname));
2107 case SMB_QUERY_FS_ATTRIBUTE_INFO:
2108 case SMB_FS_ATTRIBUTE_INFORMATION:
2111 #if defined(HAVE_SYS_QUOTAS)
2112 quota_flag = FILE_VOLUME_QUOTAS;
2115 SIVAL(pdata,0,FILE_CASE_PRESERVED_NAMES|FILE_CASE_SENSITIVE_SEARCH|
2116 (lp_nt_acl_support(SNUM(conn)) ? FILE_PERSISTENT_ACLS : 0)|
2117 quota_flag); /* FS ATTRIBUTES */
2119 SIVAL(pdata,4,255); /* Max filename component length */
2120 /* NOTE! the fstype must *not* be null terminated or win98 won't recognise it
2121 and will think we can't do long filenames */
2122 len = srvstr_push(outbuf, pdata+12, fstype, -1, STR_UNICODE);
2124 data_len = 12 + len;
2127 case SMB_QUERY_FS_LABEL_INFO:
2128 case SMB_FS_LABEL_INFORMATION:
2129 len = srvstr_push(outbuf, pdata+4, vname, -1, 0);
2134 case SMB_QUERY_FS_VOLUME_INFO:
2135 case SMB_FS_VOLUME_INFORMATION:
2138 * Add volume serial number - hash of a combination of
2139 * the called hostname and the service name.
2141 SIVAL(pdata,8,str_checksum(lp_servicename(snum)) ^
2142 (str_checksum(get_local_machine_name())<<16));
2144 len = srvstr_push(outbuf, pdata+18, vname, -1, STR_UNICODE);
2145 SIVAL(pdata,12,len);
2147 DEBUG(5,("call_trans2qfsinfo : SMB_QUERY_FS_VOLUME_INFO namelen = %d, vol=%s serv=%s\n",
2148 (int)strlen(vname),vname, lp_servicename(snum)));
2151 case SMB_QUERY_FS_SIZE_INFO:
2152 case SMB_FS_SIZE_INFORMATION:
2154 SMB_BIG_UINT dfree,dsize,bsize,block_size,sectors_per_unit,bytes_per_sector;
2156 if (SMB_VFS_DISK_FREE(conn,".",False,&bsize,&dfree,&dsize) == (SMB_BIG_UINT)-1) {
2157 return(UNIXERROR(ERRHRD,ERRgeneral));
2159 block_size = lp_block_size(snum);
2160 if (bsize < block_size) {
2161 SMB_BIG_UINT factor = block_size/bsize;
2166 if (bsize > block_size) {
2167 SMB_BIG_UINT factor = bsize/block_size;
2172 bytes_per_sector = 512;
2173 sectors_per_unit = bsize/bytes_per_sector;
2174 DEBUG(5,("call_trans2qfsinfo : SMB_QUERY_FS_SIZE_INFO bsize=%u, cSectorUnit=%u, \
2175 cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize, (unsigned int)sectors_per_unit,
2176 (unsigned int)bytes_per_sector, (unsigned int)dsize, (unsigned int)dfree));
2177 SBIG_UINT(pdata,0,dsize);
2178 SBIG_UINT(pdata,8,dfree);
2179 SIVAL(pdata,16,sectors_per_unit);
2180 SIVAL(pdata,20,bytes_per_sector);
2184 case SMB_FS_FULL_SIZE_INFORMATION:
2186 SMB_BIG_UINT dfree,dsize,bsize,block_size,sectors_per_unit,bytes_per_sector;
2188 if (SMB_VFS_DISK_FREE(conn,".",False,&bsize,&dfree,&dsize) == (SMB_BIG_UINT)-1) {
2189 return(UNIXERROR(ERRHRD,ERRgeneral));
2191 block_size = lp_block_size(snum);
2192 if (bsize < block_size) {
2193 SMB_BIG_UINT factor = block_size/bsize;
2198 if (bsize > block_size) {
2199 SMB_BIG_UINT factor = bsize/block_size;
2204 bytes_per_sector = 512;
2205 sectors_per_unit = bsize/bytes_per_sector;
2206 DEBUG(5,("call_trans2qfsinfo : SMB_QUERY_FS_FULL_SIZE_INFO bsize=%u, cSectorUnit=%u, \
2207 cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize, (unsigned int)sectors_per_unit,
2208 (unsigned int)bytes_per_sector, (unsigned int)dsize, (unsigned int)dfree));
2209 SBIG_UINT(pdata,0,dsize); /* Total Allocation units. */
2210 SBIG_UINT(pdata,8,dfree); /* Caller available allocation units. */
2211 SBIG_UINT(pdata,16,dfree); /* Actual available allocation units. */
2212 SIVAL(pdata,24,sectors_per_unit); /* Sectors per allocation unit. */
2213 SIVAL(pdata,28,bytes_per_sector); /* Bytes per sector. */
2217 case SMB_QUERY_FS_DEVICE_INFO:
2218 case SMB_FS_DEVICE_INFORMATION:
2220 SIVAL(pdata,0,0); /* dev type */
2221 SIVAL(pdata,4,0); /* characteristics */
2224 #ifdef HAVE_SYS_QUOTAS
2225 case SMB_FS_QUOTA_INFORMATION:
2227 * what we have to send --metze:
2229 * Unknown1: 24 NULL bytes
2230 * Soft Quota Treshold: 8 bytes seems like SMB_BIG_UINT or so
2231 * Hard Quota Limit: 8 bytes seems like SMB_BIG_UINT or so
2232 * Quota Flags: 2 byte :
2233 * Unknown3: 6 NULL bytes
2237 * details for Quota Flags:
2239 * 0x0020 Log Limit: log if the user exceeds his Hard Quota
2240 * 0x0010 Log Warn: log if the user exceeds his Soft Quota
2241 * 0x0002 Deny Disk: deny disk access when the user exceeds his Hard Quota
2242 * 0x0001 Enable Quotas: enable quota for this fs
2246 /* we need to fake up a fsp here,
2247 * because its not send in this call
2250 SMB_NTQUOTA_STRUCT quotas;
2253 ZERO_STRUCT(quotas);
2260 if (current_user.uid != 0) {
2261 DEBUG(0,("set_user_quota: access_denied service [%s] user [%s]\n",
2262 lp_servicename(SNUM(conn)),conn->user));
2263 return ERROR_DOS(ERRDOS,ERRnoaccess);
2266 if (vfs_get_ntquota(&fsp, SMB_USER_FS_QUOTA_TYPE, NULL, "as)!=0) {
2267 DEBUG(0,("vfs_get_ntquota() failed for service [%s]\n",lp_servicename(SNUM(conn))));
2268 return ERROR_DOS(ERRSRV,ERRerror);
2273 DEBUG(10,("SMB_FS_QUOTA_INFORMATION: for service [%s]\n",lp_servicename(SNUM(conn))));
2275 /* Unknown1 24 NULL bytes*/
2276 SBIG_UINT(pdata,0,(SMB_BIG_UINT)0);
2277 SBIG_UINT(pdata,8,(SMB_BIG_UINT)0);
2278 SBIG_UINT(pdata,16,(SMB_BIG_UINT)0);
2280 /* Default Soft Quota 8 bytes */
2281 SBIG_UINT(pdata,24,quotas.softlim);
2283 /* Default Hard Quota 8 bytes */
2284 SBIG_UINT(pdata,32,quotas.hardlim);
2286 /* Quota flag 2 bytes */
2287 SSVAL(pdata,40,quotas.qflags);
2289 /* Unknown3 6 NULL bytes */
2295 #endif /* HAVE_SYS_QUOTAS */
2296 case SMB_FS_OBJECTID_INFORMATION:
2301 * Query the version and capabilities of the CIFS UNIX extensions
2305 case SMB_QUERY_CIFS_UNIX_INFO:
2306 if (!lp_unix_extensions())
2307 return ERROR_DOS(ERRDOS,ERRunknownlevel);
2309 SSVAL(pdata,0,CIFS_UNIX_MAJOR_VERSION);
2310 SSVAL(pdata,2,CIFS_UNIX_MINOR_VERSION);
2311 SBIG_UINT(pdata,4,((SMB_BIG_UINT)CIFS_UNIX_POSIX_ACLS_CAP)); /* We have POSIX ACLs. */
2314 case SMB_MAC_QUERY_FS_INFO:
2316 * Thursby MAC extension... ONLY on NTFS filesystems
2317 * once we do streams then we don't need this
2319 if (strequal(lp_fstype(SNUM(conn)),"NTFS")) {
2321 SIVAL(pdata,84,0x100); /* Don't support mac... */
2326 return ERROR_DOS(ERRDOS,ERRunknownlevel);
2330 send_trans2_replies( outbuf, bufsize, params, 0, pdata, data_len);
2332 DEBUG( 4, ( "%s info_level = %d\n", smb_fn_name(CVAL(inbuf,smb_com)), info_level) );
2337 #ifdef HAVE_SYS_QUOTAS
2338 /****************************************************************************
2339 Reply to a TRANS2_SETFSINFO (set filesystem info).
2340 ****************************************************************************/
2342 static int call_trans2setfsinfo(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize,
2343 char **pparams, int total_params, char **ppdata, int total_data,
2344 unsigned int max_data_bytes)
2346 char *pdata = *ppdata;
2347 char *params = *pparams;
2348 files_struct *fsp = NULL;
2351 SMB_NTQUOTA_STRUCT quotas;
2353 ZERO_STRUCT(quotas);
2355 DEBUG(10,("call_trans2setfsinfo: SET_FS_QUOTA: for service [%s]\n",lp_servicename(SNUM(conn))));
2358 if ((current_user.uid != 0)||!CAN_WRITE(conn)) {
2359 DEBUG(0,("set_user_quota: access_denied service [%s] user [%s]\n",
2360 lp_servicename(SNUM(conn)),conn->user));
2361 return ERROR_DOS(ERRSRV,ERRaccess);
2365 if (total_params < 4) {
2366 DEBUG(0,("call_trans2setfsinfo: requires total_params(%d) >= 4 bytes!\n",
2368 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
2371 fsp = file_fsp(params,0);
2373 if (!CHECK_NTQUOTA_HANDLE_OK(fsp,conn)) {
2374 DEBUG(3,("TRANSACT_GET_USER_QUOTA: no valid QUOTA HANDLE\n"));
2375 return ERROR_NT(NT_STATUS_INVALID_HANDLE);
2378 info_level = SVAL(params,2);
2380 switch(info_level) {
2381 case SMB_FS_QUOTA_INFORMATION:
2382 /* note: normaly there're 48 bytes,
2383 * but we didn't use the last 6 bytes for now
2386 if (total_data < 42) {
2387 DEBUG(0,("call_trans2setfsinfo: SET_FS_QUOTA: requires total_data(%d) >= 42 bytes!\n",
2389 return ERROR_DOS(ERRDOS,ERRunknownlevel);
2392 /* unknown_1 24 NULL bytes in pdata*/
2394 /* the soft quotas 8 bytes (SMB_BIG_UINT)*/
2395 quotas.softlim = (SMB_BIG_UINT)IVAL(pdata,24);
2396 #ifdef LARGE_SMB_OFF_T
2397 quotas.softlim |= (((SMB_BIG_UINT)IVAL(pdata,28)) << 32);
2398 #else /* LARGE_SMB_OFF_T */
2399 if ((IVAL(pdata,28) != 0)&&
2400 ((quotas.softlim != 0xFFFFFFFF)||
2401 (IVAL(pdata,28)!=0xFFFFFFFF))) {
2402 /* more than 32 bits? */
2403 return ERROR_DOS(ERRDOS,ERRunknownlevel);
2405 #endif /* LARGE_SMB_OFF_T */
2407 /* the hard quotas 8 bytes (SMB_BIG_UINT)*/
2408 quotas.hardlim = (SMB_BIG_UINT)IVAL(pdata,32);
2409 #ifdef LARGE_SMB_OFF_T
2410 quotas.hardlim |= (((SMB_BIG_UINT)IVAL(pdata,36)) << 32);
2411 #else /* LARGE_SMB_OFF_T */
2412 if ((IVAL(pdata,36) != 0)&&
2413 ((quotas.hardlim != 0xFFFFFFFF)||
2414 (IVAL(pdata,36)!=0xFFFFFFFF))) {
2415 /* more than 32 bits? */
2416 return ERROR_DOS(ERRDOS,ERRunknownlevel);
2418 #endif /* LARGE_SMB_OFF_T */
2420 /* quota_flags 2 bytes **/
2421 quotas.qflags = SVAL(pdata,40);
2423 /* unknown_2 6 NULL bytes follow*/
2425 /* now set the quotas */
2426 if (vfs_set_ntquota(fsp, SMB_USER_FS_QUOTA_TYPE, NULL, "as)!=0) {
2427 DEBUG(0,("vfs_set_ntquota() failed for service [%s]\n",lp_servicename(SNUM(conn))));
2428 return ERROR_DOS(ERRSRV,ERRerror);
2433 DEBUG(3,("call_trans2setfsinfo: unknown level (0x%X) not implemented yet.\n",
2435 return ERROR_DOS(ERRDOS,ERRunknownlevel);
2440 * sending this reply works fine,
2441 * but I'm not sure it's the same
2442 * like windows do...
2445 outsize = set_message(outbuf,10,0,True);
2449 #endif /* HAVE_SYS_QUOTAS */
2451 /****************************************************************************
2452 Utility function to set bad path error.
2453 ****************************************************************************/
2455 int set_bad_path_error(int err, BOOL bad_path, char *outbuf, int def_class, uint32 def_code)
2457 DEBUG(10,("set_bad_path_error: err = %d bad_path = %d\n",
2458 err, (int)bad_path ));
2462 return ERROR_NT(NT_STATUS_OBJECT_PATH_NOT_FOUND);
2464 return ERROR_NT(NT_STATUS_OBJECT_NAME_NOT_FOUND);
2467 return UNIXERROR(def_class,def_code);
2470 #if defined(HAVE_POSIX_ACLS)
2471 /****************************************************************************
2472 Utility function to count the number of entries in a POSIX acl.
2473 ****************************************************************************/
2475 static unsigned int count_acl_entries(connection_struct *conn, SMB_ACL_T posix_acl)
2477 unsigned int ace_count = 0;
2478 int entry_id = SMB_ACL_FIRST_ENTRY;
2479 SMB_ACL_ENTRY_T entry;
2481 while ( posix_acl && (SMB_VFS_SYS_ACL_GET_ENTRY(conn, posix_acl, entry_id, &entry) == 1)) {
2483 if (entry_id == SMB_ACL_FIRST_ENTRY) {
2484 entry_id = SMB_ACL_NEXT_ENTRY;
2491 /****************************************************************************
2492 Utility function to marshall a POSIX acl into wire format.
2493 ****************************************************************************/
2495 static BOOL marshall_posix_acl(connection_struct *conn, char *pdata, SMB_STRUCT_STAT *pst, SMB_ACL_T posix_acl)
2497 int entry_id = SMB_ACL_FIRST_ENTRY;
2498 SMB_ACL_ENTRY_T entry;
2500 while ( posix_acl && (SMB_VFS_SYS_ACL_GET_ENTRY(conn, posix_acl, entry_id, &entry) == 1)) {
2501 SMB_ACL_TAG_T tagtype;
2502 SMB_ACL_PERMSET_T permset;
2503 unsigned char perms = 0;
2504 unsigned int own_grp;
2507 if (entry_id == SMB_ACL_FIRST_ENTRY) {
2508 entry_id = SMB_ACL_NEXT_ENTRY;
2511 if (SMB_VFS_SYS_ACL_GET_TAG_TYPE(conn, entry, &tagtype) == -1) {
2512 DEBUG(0,("marshall_posix_acl: SMB_VFS_SYS_ACL_GET_TAG_TYPE failed.\n"));
2516 if (SMB_VFS_SYS_ACL_GET_PERMSET(conn, entry, &permset) == -1) {
2517 DEBUG(0,("marshall_posix_acl: SMB_VFS_SYS_ACL_GET_PERMSET failed.\n"));
2521 perms |= (SMB_VFS_SYS_ACL_GET_PERM(conn, permset, SMB_ACL_READ) ? SMB_POSIX_ACL_READ : 0);
2522 perms |= (SMB_VFS_SYS_ACL_GET_PERM(conn, permset, SMB_ACL_WRITE) ? SMB_POSIX_ACL_WRITE : 0);
2523 perms |= (SMB_VFS_SYS_ACL_GET_PERM(conn, permset, SMB_ACL_EXECUTE) ? SMB_POSIX_ACL_EXECUTE : 0);
2525 SCVAL(pdata,1,perms);
2528 case SMB_ACL_USER_OBJ:
2529 SCVAL(pdata,0,SMB_POSIX_ACL_USER_OBJ);
2530 own_grp = (unsigned int)pst->st_uid;
2531 SIVAL(pdata,2,own_grp);
2536 uid_t *puid = (uid_t *)SMB_VFS_SYS_ACL_GET_QUALIFIER(conn, entry);
2538 DEBUG(0,("marshall_posix_acl: SMB_VFS_SYS_ACL_GET_QUALIFIER failed.\n"));
2540 own_grp = (unsigned int)*puid;
2541 SMB_VFS_SYS_ACL_FREE_QUALIFIER(conn, (void *)puid,tagtype);
2542 SCVAL(pdata,0,SMB_POSIX_ACL_USER);
2543 SIVAL(pdata,2,own_grp);
2547 case SMB_ACL_GROUP_OBJ:
2548 SCVAL(pdata,0,SMB_POSIX_ACL_GROUP_OBJ);
2549 own_grp = (unsigned int)pst->st_gid;
2550 SIVAL(pdata,2,own_grp);
2555 gid_t *pgid= (gid_t *)SMB_VFS_SYS_ACL_GET_QUALIFIER(conn, entry);
2557 DEBUG(0,("marshall_posix_acl: SMB_VFS_SYS_ACL_GET_QUALIFIER failed.\n"));
2559 own_grp = (unsigned int)*pgid;
2560 SMB_VFS_SYS_ACL_FREE_QUALIFIER(conn, (void *)pgid,tagtype);
2561 SCVAL(pdata,0,SMB_POSIX_ACL_GROUP);
2562 SIVAL(pdata,2,own_grp);
2567 SCVAL(pdata,0,SMB_POSIX_ACL_MASK);
2568 SIVAL(pdata,2,0xFFFFFFFF);
2569 SIVAL(pdata,6,0xFFFFFFFF);
2572 SCVAL(pdata,0,SMB_POSIX_ACL_OTHER);
2573 SIVAL(pdata,2,0xFFFFFFFF);
2574 SIVAL(pdata,6,0xFFFFFFFF);
2577 DEBUG(0,("marshall_posix_acl: unknown tagtype.\n"));
2580 pdata += SMB_POSIX_ACL_ENTRY_SIZE;
2587 /****************************************************************************
2588 Reply to a TRANS2_QFILEPATHINFO or TRANSACT2_QFILEINFO (query file info by
2589 file name or file id).
2590 ****************************************************************************/
2592 static int call_trans2qfilepathinfo(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize,
2593 char **pparams, int total_params, char **ppdata, int total_data,
2594 unsigned int max_data_bytes)
2596 char *params = *pparams;
2597 char *pdata = *ppdata;
2598 uint16 tran_call = SVAL(inbuf, smb_setup0);
2601 SMB_OFF_T file_size=0;
2602 SMB_BIG_UINT allocation_size=0;
2603 unsigned int data_size = 0;
2604 unsigned int param_size = 2;
2605 SMB_STRUCT_STAT sbuf;
2606 pstring fname, dos_fname;
2611 BOOL bad_path = False;
2612 BOOL delete_pending = False;
2615 files_struct *fsp = NULL;
2616 TALLOC_CTX *ea_ctx = NULL;
2617 struct ea_list *ea_list = NULL;
2618 uint32 desired_access = 0x12019F; /* Default - GENERIC_EXECUTE mapping from Windows */
2621 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
2625 if (tran_call == TRANSACT2_QFILEINFO) {
2626 if (total_params < 4) {
2627 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
2630 fsp = file_fsp(params,0);
2631 info_level = SVAL(params,2);
2633 DEBUG(3,("call_trans2qfilepathinfo: TRANSACT2_QFILEINFO: level = %d\n", info_level));
2635 if(fsp && (fsp->fake_file_handle)) {
2637 * This is actually for the QUOTA_FAKE_FILE --metze
2640 pstrcpy(fname, fsp->fsp_name);
2641 /* We know this name is ok, it's already passed the checks. */
2643 } else if(fsp && (fsp->is_directory || fsp->fd == -1)) {
2645 * This is actually a QFILEINFO on a directory
2646 * handle (returned from an NT SMB). NT5.0 seems
2647 * to do this call. JRA.
2649 /* We know this name is ok, it's already passed the checks. */
2650 pstrcpy(fname, fsp->fsp_name);
2652 if (INFO_LEVEL_IS_UNIX(info_level)) {
2653 /* Always do lstat for UNIX calls. */
2654 if (SMB_VFS_LSTAT(conn,fname,&sbuf)) {
2655 DEBUG(3,("call_trans2qfilepathinfo: SMB_VFS_LSTAT of %s failed (%s)\n",fname,strerror(errno)));
2656 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRbadpath);
2658 } else if (SMB_VFS_STAT(conn,fname,&sbuf)) {
2659 DEBUG(3,("call_trans2qfilepathinfo: SMB_VFS_STAT of %s failed (%s)\n",fname,strerror(errno)));
2660 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRbadpath);
2663 delete_pending = fsp->is_directory ? fsp->directory_delete_on_close : 0;
2666 * Original code - this is an open file.
2668 CHECK_FSP(fsp,conn);
2670 pstrcpy(fname, fsp->fsp_name);
2671 if (SMB_VFS_FSTAT(fsp,fsp->fd,&sbuf) != 0) {
2672 DEBUG(3,("fstat of fnum %d failed (%s)\n", fsp->fnum, strerror(errno)));
2673 return(UNIXERROR(ERRDOS,ERRbadfid));
2675 pos = fsp->position_information;
2676 delete_pending = fsp->delete_on_close;
2677 desired_access = fsp->desired_access;
2680 NTSTATUS status = NT_STATUS_OK;
2683 if (total_params < 6) {
2684 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
2687 info_level = SVAL(params,0);
2689 DEBUG(3,("call_trans2qfilepathinfo: TRANSACT2_QPATHINFO: level = %d\n", info_level));
2691 srvstr_get_path(inbuf, fname, ¶ms[6], sizeof(fname), -1, STR_TERMINATE, &status, False);
2692 if (!NT_STATUS_IS_OK(status)) {
2693 return ERROR_NT(status);
2696 RESOLVE_DFSPATH(fname, conn, inbuf, outbuf);
2698 unix_convert(fname,conn,0,&bad_path,&sbuf);
2700 return ERROR_NT(NT_STATUS_OBJECT_PATH_NOT_FOUND);
2702 if (!check_name(fname,conn)) {
2703 DEBUG(3,("call_trans2qfilepathinfo: fileinfo of %s failed (%s)\n",fname,strerror(errno)));
2704 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRbadpath);
2707 if (INFO_LEVEL_IS_UNIX(info_level)) {
2708 /* Always do lstat for UNIX calls. */
2709 if (SMB_VFS_LSTAT(conn,fname,&sbuf)) {
2710 DEBUG(3,("call_trans2qfilepathinfo: SMB_VFS_LSTAT of %s failed (%s)\n",fname,strerror(errno)));
2711 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRbadpath);
2713 } else if (!VALID_STAT(sbuf) && SMB_VFS_STAT(conn,fname,&sbuf) && (info_level != SMB_INFO_IS_NAME_VALID)) {
2714 DEBUG(3,("call_trans2qfilepathinfo: SMB_VFS_STAT of %s failed (%s)\n",fname,strerror(errno)));
2715 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRbadpath);
2719 if (INFO_LEVEL_IS_UNIX(info_level) && !lp_unix_extensions())
2720 return ERROR_DOS(ERRDOS,ERRunknownlevel);
2722 DEBUG(3,("call_trans2qfilepathinfo %s (fnum = %d) level=%d call=%d total_data=%d\n",
2723 fname,fsp ? fsp->fnum : -1, info_level,tran_call,total_data));
2725 p = strrchr_m(fname,'/');
2731 mode = dos_mode(conn,fname,&sbuf);
2733 mode = FILE_ATTRIBUTE_NORMAL;
2735 fullpathname = fname;
2736 file_size = get_file_size(sbuf);
2737 allocation_size = get_allocation_size(conn,fsp,&sbuf);
2739 /* This is necessary, as otherwise the desktop.ini file in
2740 * this folder is ignored */
2741 mode |= (lp_profile_acls(SNUM(conn)) ? aRONLY : 0);
2745 /* Pull any EA list from the data portion. */
2746 if (info_level == SMB_INFO_QUERY_EAS_FROM_LIST) {
2749 if (total_data < 4) {
2750 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
2752 ea_size = IVAL(pdata,0);
2754 if (total_data > 0 && ea_size != total_data) {
2755 DEBUG(4,("call_trans2qfilepathinfo: Rejecting EA request with incorrect \
2756 total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pdata,0) ));
2757 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
2760 if (!lp_ea_support(SNUM(conn))) {
2761 return ERROR_DOS(ERRDOS,ERReasnotsupported);
2764 if ((ea_ctx = talloc_init("ea_list")) == NULL) {
2765 return ERROR_NT(NT_STATUS_NO_MEMORY);
2768 /* Pull out the list of names. */
2769 ea_list = read_ea_name_list(ea_ctx, pdata, ea_size);
2771 talloc_destroy(ea_ctx);
2772 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
2776 params = SMB_REALLOC(*pparams,2);
2777 if (params == NULL) {
2778 talloc_destroy(ea_ctx);
2779 return ERROR_NT(NT_STATUS_NO_MEMORY);
2782 memset((char *)params,'\0',2);
2783 data_size = max_data_bytes + DIR_ENTRY_SAFETY_MARGIN;
2784 pdata = SMB_REALLOC(*ppdata, data_size);
2785 if ( pdata == NULL ) {
2786 talloc_destroy(ea_ctx);
2787 return ERROR_NT(NT_STATUS_NO_MEMORY);
2791 memset((char *)pdata,'\0',data_size);
2793 c_time = get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(conn)));
2796 if (fsp->pending_modtime) {
2797 /* the pending modtime overrides the current modtime */
2798 sbuf.st_mtime = fsp->pending_modtime;
2801 /* Do we have this path open ? */
2802 files_struct *fsp1 = file_find_di_first(sbuf.st_dev, sbuf.st_ino);
2803 if (fsp1 && fsp1->pending_modtime) {
2804 /* the pending modtime overrides the current modtime */
2805 sbuf.st_mtime = fsp1->pending_modtime;
2809 if (lp_dos_filetime_resolution(SNUM(conn))) {
2811 sbuf.st_atime &= ~1;
2812 sbuf.st_ctime &= ~1;
2813 sbuf.st_mtime &= ~1;
2816 /* NT expects the name to be in an exact form of the *full*
2817 filename. See the trans2 torture test */
2818 if (strequal(base_name,".")) {
2819 pstrcpy(dos_fname, "\\");
2821 pstr_sprintf(dos_fname, "\\%s", fname);
2822 string_replace(dos_fname, '/', '\\');
2825 switch (info_level) {
2826 case SMB_INFO_STANDARD:
2827 DEBUG(10,("call_trans2qfilepathinfo: SMB_INFO_STANDARD\n"));
2829 put_dos_date2(pdata,l1_fdateCreation,c_time);
2830 put_dos_date2(pdata,l1_fdateLastAccess,sbuf.st_atime);
2831 put_dos_date2(pdata,l1_fdateLastWrite,sbuf.st_mtime); /* write time */
2832 SIVAL(pdata,l1_cbFile,(uint32)file_size);
2833 SIVAL(pdata,l1_cbFileAlloc,(uint32)allocation_size);
2834 SSVAL(pdata,l1_attrFile,mode);
2837 case SMB_INFO_QUERY_EA_SIZE:
2839 unsigned int ea_size = estimate_ea_size(conn, fsp, fname);
2840 DEBUG(10,("call_trans2qfilepathinfo: SMB_INFO_QUERY_EA_SIZE\n"));
2842 put_dos_date2(pdata,l1_fdateCreation,c_time);
2843 put_dos_date2(pdata,l1_fdateLastAccess,sbuf.st_atime);
2844 put_dos_date2(pdata,l1_fdateLastWrite,sbuf.st_mtime); /* write time */
2845 SIVAL(pdata,l1_cbFile,(uint32)file_size);
2846 SIVAL(pdata,l1_cbFileAlloc,(uint32)allocation_size);
2847 SSVAL(pdata,l1_attrFile,mode);
2848 SIVAL(pdata,l1_attrFile+2,ea_size);
2852 case SMB_INFO_IS_NAME_VALID:
2853 DEBUG(10,("call_trans2qfilepathinfo: SMB_INFO_IS_NAME_VALID\n"));
2854 if (tran_call == TRANSACT2_QFILEINFO) {
2855 /* os/2 needs this ? really ?*/
2856 return ERROR_DOS(ERRDOS,ERRbadfunc);
2862 case SMB_INFO_QUERY_EAS_FROM_LIST:
2864 size_t total_ea_len = 0;
2865 struct ea_list *ea_file_list = NULL;
2867 DEBUG(10,("call_trans2qfilepathinfo: SMB_INFO_QUERY_EAS_FROM_LIST\n"));
2868 put_dos_date2(pdata,0,c_time);
2869 put_dos_date2(pdata,4,sbuf.st_atime);
2870 put_dos_date2(pdata,8,sbuf.st_mtime);
2871 SIVAL(pdata,12,(uint32)file_size);
2872 SIVAL(pdata,16,(uint32)allocation_size);
2873 SIVAL(pdata,20,mode);
2875 ea_file_list = get_ea_list_from_file(ea_ctx, conn, fsp, fname, &total_ea_len);
2877 ea_list = ea_list_union(ea_list, ea_file_list, &total_ea_len);
2879 if (!ea_list || (total_ea_len > data_size - 24)) {
2880 talloc_destroy(ea_ctx);
2885 data_size = fill_ea_buffer(ea_ctx, pdata + 24, data_size - 24, conn, ea_list);
2887 talloc_destroy(ea_ctx);
2891 case SMB_INFO_QUERY_ALL_EAS:
2893 /* We have data_size bytes to put EA's into. */
2894 size_t total_ea_len = 0;
2896 DEBUG(10,("call_trans2qfilepathinfo: SMB_INFO_QUERY_ALL_EAS\n"));
2898 ea_ctx = talloc_init("ea_ctx");
2900 return ERROR_NT(NT_STATUS_NO_MEMORY);
2903 ea_list = get_ea_list_from_file(ea_ctx, conn, fsp, fname, &total_ea_len);
2904 if (!ea_list || (total_ea_len > data_size)) {
2905 talloc_destroy(ea_ctx);
2910 data_size = fill_ea_buffer(ea_ctx, pdata, data_size, conn, ea_list);
2911 talloc_destroy(ea_ctx);
2915 case SMB_FILE_BASIC_INFORMATION:
2916 case SMB_QUERY_FILE_BASIC_INFO:
2918 if (info_level == SMB_QUERY_FILE_BASIC_INFO) {
2919 DEBUG(10,("call_trans2qfilepathinfo: SMB_QUERY_FILE_BASIC_INFO\n"));
2920 data_size = 36; /* w95 returns 40 bytes not 36 - why ?. */
2922 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_BASIC_INFORMATION\n"));
2926 put_long_date(pdata,c_time);
2927 put_long_date(pdata+8,sbuf.st_atime);
2928 put_long_date(pdata+16,sbuf.st_mtime); /* write time */
2929 put_long_date(pdata+24,sbuf.st_mtime); /* change time */
2930 SIVAL(pdata,32,mode);
2932 DEBUG(5,("SMB_QFBI - "));
2934 time_t create_time = c_time;
2935 DEBUG(5,("create: %s ", ctime(&create_time)));
2937 DEBUG(5,("access: %s ", ctime(&sbuf.st_atime)));
2938 DEBUG(5,("write: %s ", ctime(&sbuf.st_mtime)));
2939 DEBUG(5,("change: %s ", ctime(&sbuf.st_mtime)));
2940 DEBUG(5,("mode: %x\n", mode));
2944 case SMB_FILE_STANDARD_INFORMATION:
2945 case SMB_QUERY_FILE_STANDARD_INFO:
2947 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_STANDARD_INFORMATION\n"));
2949 SOFF_T(pdata,0,allocation_size);
2950 SOFF_T(pdata,8,file_size);
2951 if (delete_pending & sbuf.st_nlink)
2952 SIVAL(pdata,16,sbuf.st_nlink - 1);
2954 SIVAL(pdata,16,sbuf.st_nlink);
2956 SCVAL(pdata,21,(mode&aDIR)?1:0);
2959 case SMB_FILE_EA_INFORMATION:
2960 case SMB_QUERY_FILE_EA_INFO:
2962 unsigned int ea_size = estimate_ea_size(conn, fsp, fname);
2963 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_EA_INFORMATION\n"));
2965 SIVAL(pdata,0,ea_size);
2969 /* Get the 8.3 name - used if NT SMB was negotiated. */
2970 case SMB_QUERY_FILE_ALT_NAME_INFO:
2971 case SMB_FILE_ALTERNATE_NAME_INFORMATION:
2975 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_ALTERNATE_NAME_INFORMATION\n"));
2976 pstrcpy(short_name,base_name);
2977 /* Mangle if not already 8.3 */
2978 if(!mangle_is_8_3(short_name, True)) {
2979 mangle_map(short_name,True,True,SNUM(conn));
2981 len = srvstr_push(outbuf, pdata+4, short_name, -1, STR_UNICODE);
2982 data_size = 4 + len;
2987 case SMB_QUERY_FILE_NAME_INFO:
2989 this must be *exactly* right for ACLs on mapped drives to work
2991 len = srvstr_push(outbuf, pdata+4, dos_fname, -1, STR_UNICODE);
2992 DEBUG(10,("call_trans2qfilepathinfo: SMB_QUERY_FILE_NAME_INFO\n"));
2993 data_size = 4 + len;
2997 case SMB_FILE_ALLOCATION_INFORMATION:
2998 case SMB_QUERY_FILE_ALLOCATION_INFO:
2999 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_ALLOCATION_INFORMATION\n"));
3001 SOFF_T(pdata,0,allocation_size);
3004 case SMB_FILE_END_OF_FILE_INFORMATION:
3005 case SMB_QUERY_FILE_END_OF_FILEINFO:
3006 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_END_OF_FILE_INFORMATION\n"));
3008 SOFF_T(pdata,0,file_size);
3011 case SMB_QUERY_FILE_ALL_INFO:
3012 case SMB_FILE_ALL_INFORMATION:
3014 unsigned int ea_size = estimate_ea_size(conn, fsp, fname);
3015 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_ALL_INFORMATION\n"));
3016 put_long_date(pdata,c_time);
3017 put_long_date(pdata+8,sbuf.st_atime);
3018 put_long_date(pdata+16,sbuf.st_mtime); /* write time */
3019 put_long_date(pdata+24,sbuf.st_mtime); /* change time */
3020 SIVAL(pdata,32,mode);
3022 SOFF_T(pdata,0,allocation_size);
3023 SOFF_T(pdata,8,file_size);
3024 if (delete_pending && sbuf.st_nlink)
3025 SIVAL(pdata,16,sbuf.st_nlink - 1);
3027 SIVAL(pdata,16,sbuf.st_nlink);
3028 SCVAL(pdata,20,delete_pending);
3029 SCVAL(pdata,21,(mode&aDIR)?1:0);
3031 SIVAL(pdata,0,ea_size);
3032 pdata += 4; /* EA info */
3033 len = srvstr_push(outbuf, pdata+4, dos_fname, -1, STR_UNICODE);
3036 data_size = PTR_DIFF(pdata,(*ppdata));
3039 case SMB_FILE_INTERNAL_INFORMATION:
3040 /* This should be an index number - looks like
3043 I think this causes us to fail the IFSKIT
3044 BasicFileInformationTest. -tpot */
3046 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_INTERNAL_INFORMATION\n"));
3047 SIVAL(pdata,0,sbuf.st_dev);
3048 SIVAL(pdata,4,sbuf.st_ino);
3052 case SMB_FILE_ACCESS_INFORMATION:
3053 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_ACCESS_INFORMATION\n"));
3054 SIVAL(pdata,0,desired_access);
3058 case SMB_FILE_NAME_INFORMATION:
3059 /* Pathname with leading '\'. */
3062 byte_len = dos_PutUniCode(pdata+4,dos_fname,max_data_bytes,False);
3063 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_NAME_INFORMATION\n"));
3064 SIVAL(pdata,0,byte_len);
3065 data_size = 4 + byte_len;
3069 case SMB_FILE_DISPOSITION_INFORMATION:
3070 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_DISPOSITION_INFORMATION\n"));
3072 SCVAL(pdata,0,delete_pending);
3075 case SMB_FILE_POSITION_INFORMATION:
3076 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_POSITION_INFORMATION\n"));
3078 SOFF_T(pdata,0,pos);
3081 case SMB_FILE_MODE_INFORMATION:
3082 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_MODE_INFORMATION\n"));
3083 SIVAL(pdata,0,mode);
3087 case SMB_FILE_ALIGNMENT_INFORMATION:
3088 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_ALIGNMENT_INFORMATION\n"));
3089 SIVAL(pdata,0,0); /* No alignment needed. */
3095 * NT4 server just returns "invalid query" to this - if we try to answer
3096 * it then NTws gets a BSOD! (tridge).
3097 * W2K seems to want this. JRA.
3099 case SMB_QUERY_FILE_STREAM_INFO:
3101 case SMB_FILE_STREAM_INFORMATION:
3102 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_STREAM_INFORMATION\n"));
3106 size_t byte_len = dos_PutUniCode(pdata+24,"::$DATA", 0xE, False);
3107 SIVAL(pdata,0,0); /* ??? */
3108 SIVAL(pdata,4,byte_len); /* Byte length of unicode string ::$DATA */
3109 SOFF_T(pdata,8,file_size);
3110 SIVAL(pdata,16,allocation_size);
3111 SIVAL(pdata,20,0); /* ??? */
3112 data_size = 24 + byte_len;
3116 case SMB_QUERY_COMPRESSION_INFO:
3117 case SMB_FILE_COMPRESSION_INFORMATION:
3118 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_COMPRESSION_INFORMATION\n"));
3119 SOFF_T(pdata,0,file_size);
3120 SIVAL(pdata,8,0); /* ??? */
3121 SIVAL(pdata,12,0); /* ??? */
3125 case SMB_FILE_NETWORK_OPEN_INFORMATION:
3126 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_NETWORK_OPEN_INFORMATION\n"));
3127 put_long_date(pdata,c_time);
3128 put_long_date(pdata+8,sbuf.st_atime);
3129 put_long_date(pdata+16,sbuf.st_mtime); /* write time */
3130 put_long_date(pdata+24,sbuf.st_mtime); /* change time */
3131 SIVAL(pdata,32,allocation_size);
3132 SOFF_T(pdata,40,file_size);
3133 SIVAL(pdata,48,mode);
3134 SIVAL(pdata,52,0); /* ??? */
3138 case SMB_FILE_ATTRIBUTE_TAG_INFORMATION:
3139 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_ATTRIBUTE_TAG_INFORMATION\n"));
3140 SIVAL(pdata,0,mode);
3146 * CIFS UNIX Extensions.
3149 case SMB_QUERY_FILE_UNIX_BASIC:
3151 DEBUG(10,("call_trans2qfilepathinfo: SMB_QUERY_FILE_UNIX_BASIC\n"));
3152 DEBUG(4,("call_trans2qfilepathinfo: st_mode=%o\n",(int)sbuf.st_mode));
3154 SOFF_T(pdata,0,get_file_size(sbuf)); /* File size 64 Bit */
3157 SOFF_T(pdata,0,get_allocation_size(conn,fsp,&sbuf)); /* Number of bytes used on disk - 64 Bit */
3160 put_long_date(pdata,sbuf.st_ctime); /* Creation Time 64 Bit */
3161 put_long_date(pdata+8,sbuf.st_atime); /* Last access time 64 Bit */
3162 put_long_date(pdata+16,sbuf.st_mtime); /* Last modification time 64 Bit */
3165 SIVAL(pdata,0,sbuf.st_uid); /* user id for the owner */
3169 SIVAL(pdata,0,sbuf.st_gid); /* group id of owner */
3173 SIVAL(pdata,0,unix_filetype(sbuf.st_mode));
3176 SIVAL(pdata,0,unix_dev_major(sbuf.st_rdev)); /* Major device number if type is device */
3180 SIVAL(pdata,0,unix_dev_minor(sbuf.st_rdev)); /* Minor device number if type is device */
3184 SINO_T(pdata,0,(SMB_INO_T)sbuf.st_ino); /* inode number */
3187 SIVAL(pdata,0, unix_perms_to_wire(sbuf.st_mode)); /* Standard UNIX file permissions */
3191 SIVAL(pdata,0,sbuf.st_nlink); /* number of hard links */
3194 data_size = PTR_DIFF(pdata,(*ppdata));
3198 DEBUG(4,("call_trans2qfilepathinfo: SMB_QUERY_FILE_UNIX_BASIC"));
3200 for (i=0; i<100; i++)
3201 DEBUG(4,("%d=%x, ",i, (*ppdata)[i]));
3207 case SMB_QUERY_FILE_UNIX_LINK:
3211 DEBUG(10,("call_trans2qfilepathinfo: SMB_QUERY_FILE_UNIX_LINK\n"));
3213 if(!S_ISLNK(sbuf.st_mode))
3214 return(UNIXERROR(ERRSRV,ERRbadlink));
3216 return(UNIXERROR(ERRDOS,ERRbadlink));
3218 len = SMB_VFS_READLINK(conn,fullpathname, buffer, sizeof(pstring)-1); /* read link */
3220 return(UNIXERROR(ERRDOS,ERRnoaccess));
3222 len = srvstr_push(outbuf, pdata, buffer, -1, STR_TERMINATE);
3224 data_size = PTR_DIFF(pdata,(*ppdata));
3229 #if defined(HAVE_POSIX_ACLS)
3230 case SMB_QUERY_POSIX_ACL:
3232 SMB_ACL_T file_acl = NULL;
3233 SMB_ACL_T def_acl = NULL;
3234 uint16 num_file_acls = 0;
3235 uint16 num_def_acls = 0;
3237 if (fsp && !fsp->is_directory && (fsp->fd != -1)) {
3238 file_acl = SMB_VFS_SYS_ACL_GET_FD(fsp, fsp->fd);
3240 file_acl = SMB_VFS_SYS_ACL_GET_FILE(conn, fname, SMB_ACL_TYPE_ACCESS);
3243 if (file_acl == NULL && no_acl_syscall_error(errno)) {
3244 DEBUG(5,("call_trans2qfilepathinfo: ACLs not implemented on filesystem containing %s\n",
3246 return ERROR_NT(NT_STATUS_NOT_IMPLEMENTED);
3249 if (S_ISDIR(sbuf.st_mode)) {
3250 if (fsp && fsp->is_directory) {
3251 def_acl = SMB_VFS_SYS_ACL_GET_FILE(conn, fsp->fsp_name, SMB_ACL_TYPE_DEFAULT);
3253 def_acl = SMB_VFS_SYS_ACL_GET_FILE(conn, fname, SMB_ACL_TYPE_DEFAULT);
3255 def_acl = free_empty_sys_acl(conn, def_acl);
3258 num_file_acls = count_acl_entries(conn, file_acl);
3259 num_def_acls = count_acl_entries(conn, def_acl);
3261 if ( data_size < (num_file_acls + num_def_acls)*SMB_POSIX_ACL_ENTRY_SIZE + SMB_POSIX_ACL_HEADER_SIZE) {
3262 DEBUG(5,("call_trans2qfilepathinfo: data_size too small (%u) need %u\n",
3264 (unsigned int)((num_file_acls + num_def_acls)*SMB_POSIX_ACL_ENTRY_SIZE +
3265 SMB_POSIX_ACL_HEADER_SIZE) ));
3267 SMB_VFS_SYS_ACL_FREE_ACL(conn, file_acl);
3270 SMB_VFS_SYS_ACL_FREE_ACL(conn, def_acl);
3272 return ERROR_NT(NT_STATUS_BUFFER_TOO_SMALL);
3275 SSVAL(pdata,0,SMB_POSIX_ACL_VERSION);
3276 SSVAL(pdata,2,num_file_acls);
3277 SSVAL(pdata,4,num_def_acls);
3278 if (!marshall_posix_acl(conn, pdata + SMB_POSIX_ACL_HEADER_SIZE, &sbuf, file_acl)) {
3280 SMB_VFS_SYS_ACL_FREE_ACL(conn, file_acl);
3283 SMB_VFS_SYS_ACL_FREE_ACL(conn, def_acl);
3285 return ERROR_NT(NT_STATUS_INTERNAL_ERROR);
3287 if (!marshall_posix_acl(conn, pdata + SMB_POSIX_ACL_HEADER_SIZE + (num_file_acls*SMB_POSIX_ACL_ENTRY_SIZE), &sbuf, def_acl)) {
3289 SMB_VFS_SYS_ACL_FREE_ACL(conn, file_acl);
3292 SMB_VFS_SYS_ACL_FREE_ACL(conn, def_acl);
3294 return ERROR_NT(NT_STATUS_INTERNAL_ERROR);
3298 SMB_VFS_SYS_ACL_FREE_ACL(conn, file_acl);
3301 SMB_VFS_SYS_ACL_FREE_ACL(conn, def_acl);
3303 data_size = (num_file_acls + num_def_acls)*SMB_POSIX_ACL_ENTRY_SIZE + SMB_POSIX_ACL_HEADER_SIZE;
3309 return ERROR_DOS(ERRDOS,ERRunknownlevel);
3312 send_trans2_replies(outbuf, bufsize, params, param_size, *ppdata, data_size);
3317 /****************************************************************************
3318 Deal with the internal needs of setting the delete on close flag. Note that
3319 as the tdb locking is recursive, it is safe to call this from within
3320 open_file_shared. JRA.
3321 ****************************************************************************/
3323 NTSTATUS set_delete_on_close_internal(files_struct *fsp, BOOL delete_on_close, uint32 dosmode)
3325 if (delete_on_close) {
3327 * Only allow delete on close for writable files.
3330 if (!lp_delete_readonly(SNUM(fsp->conn))) {
3331 if (dosmode & aRONLY) {
3332 DEBUG(10,("set_delete_on_close_internal: file %s delete on close flag set but file attribute is readonly.\n",
3334 return NT_STATUS_CANNOT_DELETE;
3339 * Only allow delete on close for writable shares.
3342 if (!CAN_WRITE(fsp->conn)) {
3343 DEBUG(10,("set_delete_on_close_internal: file %s delete on close flag set but write access denied on share.\n",
3345 return NT_STATUS_ACCESS_DENIED;
3349 * Only allow delete on close for files/directories opened with delete intent.
3352 if (!(fsp->desired_access & DELETE_ACCESS)) {
3353 DEBUG(10,("set_delete_on_close_internal: file %s delete on close flag set but delete access denied.\n",
3355 return NT_STATUS_ACCESS_DENIED;
3359 if(fsp->is_directory) {
3360 fsp->directory_delete_on_close = delete_on_close;
3361 DEBUG(10, ("set_delete_on_close_internal: %s delete on close flag for fnum = %d, directory %s\n",
3362 delete_on_close ? "Added" : "Removed", fsp->fnum, fsp->fsp_name ));
3364 fsp->delete_on_close = delete_on_close;
3365 DEBUG(10, ("set_delete_on_close_internal: %s delete on close flag for fnum = %d, file %s\n",
3366 delete_on_close ? "Added" : "Removed", fsp->fnum, fsp->fsp_name ));
3369 return NT_STATUS_OK;
3372 /****************************************************************************
3373 Sets the delete on close flag over all share modes on this file.
3374 Modify the share mode entry for all files open
3375 on this device and inode to tell other smbds we have
3376 changed the delete on close flag. This will be noticed
3377 in the close code, the last closer will delete the file
3379 ****************************************************************************/
3381 NTSTATUS set_delete_on_close_over_all(files_struct *fsp, BOOL delete_on_close)
3383 DEBUG(10,("set_delete_on_close_over_all: %s delete on close flag for fnum = %d, file %s\n",
3384 delete_on_close ? "Adding" : "Removing", fsp->fnum, fsp->fsp_name ));
3386 if (fsp->is_directory || fsp->is_stat)
3387 return NT_STATUS_OK;
3389 if (lock_share_entry_fsp(fsp) == False)
3390 return NT_STATUS_ACCESS_DENIED;
3392 if (!modify_delete_flag(fsp->dev, fsp->inode, delete_on_close)) {
3393 DEBUG(0,("set_delete_on_close_over_all: failed to change delete on close flag for file %s\n",
3395 unlock_share_entry_fsp(fsp);
3396 return NT_STATUS_ACCESS_DENIED;
3399 unlock_share_entry_fsp(fsp);
3400 return NT_STATUS_OK;
3403 /****************************************************************************
3404 Set a hard link (called by UNIX extensions and by NT rename with HARD link
3406 ****************************************************************************/
3408 NTSTATUS hardlink_internals(connection_struct *conn, char *oldname, char *newname)
3410 BOOL bad_path_oldname = False;
3411 BOOL bad_path_newname = False;
3412 SMB_STRUCT_STAT sbuf1, sbuf2;
3413 pstring last_component_oldname;
3414 pstring last_component_newname;
3415 NTSTATUS status = NT_STATUS_OK;
3421 if (ms_has_wild(newname) || ms_has_wild(oldname)) {
3422 return NT_STATUS_OBJECT_PATH_SYNTAX_BAD;
3425 unix_convert(oldname,conn,last_component_oldname,&bad_path_oldname,&sbuf1);
3426 if (bad_path_oldname) {
3427 return NT_STATUS_OBJECT_PATH_NOT_FOUND;
3430 /* Quick check for "." and ".." */
3431 if (last_component_oldname[0] == '.') {
3432 if (!last_component_oldname[1] || (last_component_oldname[1] == '.' && !last_component_oldname[2])) {
3433 return NT_STATUS_OBJECT_NAME_INVALID;
3437 /* source must already exist. */
3438 if (!VALID_STAT(sbuf1)) {
3439 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3442 if (!check_name(oldname,conn)) {
3443 return NT_STATUS_ACCESS_DENIED;
3446 unix_convert(newname,conn,last_component_newname,&bad_path_newname,&sbuf2);
3447 if (bad_path_newname) {
3448 return NT_STATUS_OBJECT_PATH_NOT_FOUND;
3451 /* Quick check for "." and ".." */
3452 if (last_component_newname[0] == '.') {
3453 if (!last_component_newname[1] || (last_component_newname[1] == '.' && !last_component_newname[2])) {
3454 return NT_STATUS_OBJECT_NAME_INVALID;
3458 /* Disallow if newname already exists. */
3459 if (VALID_STAT(sbuf2)) {
3460 return NT_STATUS_OBJECT_NAME_COLLISION;
3463 if (!check_name(newname,conn)) {
3464 return NT_STATUS_ACCESS_DENIED;
3467 /* No links from a directory. */
3468 if (S_ISDIR(sbuf1.st_mode)) {
3469 return NT_STATUS_FILE_IS_A_DIRECTORY;
3472 /* Ensure this is within the share. */
3473 if (!reduce_name(conn, oldname) != 0)
3474 return NT_STATUS_ACCESS_DENIED;
3476 DEBUG(10,("hardlink_internals: doing hard link %s -> %s\n", newname, oldname ));
3478 if (SMB_VFS_LINK(conn,oldname,newname) != 0) {
3479 status = map_nt_error_from_unix(errno);
3480 DEBUG(3,("hardlink_internals: Error %s hard link %s -> %s\n",
3481 nt_errstr(status), newname, oldname));
3487 /****************************************************************************
3488 Reply to a TRANS2_SETFILEINFO (set file info by fileid).
3489 ****************************************************************************/
3491 static int call_trans2setfilepathinfo(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize,
3492 char **pparams, int total_params, char **ppdata, int total_data,
3493 unsigned int max_data_bytes)
3495 char *params = *pparams;
3496 char *pdata = *ppdata;
3497 uint16 tran_call = SVAL(inbuf, smb_setup0);
3502 SMB_STRUCT_STAT sbuf;
3505 BOOL bad_path = False;
3506 files_struct *fsp = NULL;
3507 uid_t set_owner = (uid_t)SMB_UID_NO_CHANGE;
3508 gid_t set_grp = (uid_t)SMB_GID_NO_CHANGE;
3509 mode_t unixmode = 0;
3510 NTSTATUS status = NT_STATUS_OK;
3513 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
3517 if (tran_call == TRANSACT2_SETFILEINFO) {
3518 if (total_params < 4) {
3519 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
3522 fsp = file_fsp(params,0);
3523 info_level = SVAL(params,2);
3525 if(fsp && (fsp->is_directory || fsp->fd == -1)) {
3527 * This is actually a SETFILEINFO on a directory
3528 * handle (returned from an NT SMB). NT5.0 seems
3529 * to do this call. JRA.
3531 pstrcpy(fname, fsp->fsp_name);
3532 if (SMB_VFS_STAT(conn,fname,&sbuf) != 0) {
3533 DEBUG(3,("call_trans2setfilepathinfo: fileinfo of %s failed (%s)\n",fname,strerror(errno)));
3534 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRbadpath);
3536 } else if (fsp && fsp->print_file) {
3538 * Doing a DELETE_ON_CLOSE should cancel a print job.
3540 if ((info_level == SMB_SET_FILE_DISPOSITION_INFO) && CVAL(pdata,0)) {
3541 fsp->share_mode = FILE_DELETE_ON_CLOSE;
3543 DEBUG(3,("call_trans2setfilepathinfo: Cancelling print job (%s)\n", fsp->fsp_name ));
3546 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
3549 return (UNIXERROR(ERRDOS,ERRbadpath));
3552 * Original code - this is an open file.
3554 CHECK_FSP(fsp,conn);
3556 pstrcpy(fname, fsp->fsp_name);
3559 if (SMB_VFS_FSTAT(fsp,fd,&sbuf) != 0) {
3560 DEBUG(3,("call_trans2setfilepathinfo: fstat of fnum %d failed (%s)\n",fsp->fnum, strerror(errno)));
3561 return(UNIXERROR(ERRDOS,ERRbadfid));
3566 if (total_params < 6) {
3567 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
3570 info_level = SVAL(params,0);
3571 srvstr_get_path(inbuf, fname, ¶ms[6], sizeof(fname), -1, STR_TERMINATE, &status, False);
3572 if (!NT_STATUS_IS_OK(status)) {
3573 return ERROR_NT(status);
3575 unix_convert(fname,conn,0,&bad_path,&sbuf);
3577 return ERROR_NT(NT_STATUS_OBJECT_PATH_NOT_FOUND);
3581 * For CIFS UNIX extensions the target name may not exist.
3584 if(!VALID_STAT(sbuf) && !INFO_LEVEL_IS_UNIX(info_level)) {
3585 DEBUG(3,("call_trans2setfilepathinfo: stat of %s failed (%s)\n", fname, strerror(errno)));
3586 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRbadpath);
3589 if(!check_name(fname, conn)) {
3590 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRbadpath);
3595 if (!CAN_WRITE(conn))
3596 return ERROR_DOS(ERRSRV,ERRaccess);
3598 if (INFO_LEVEL_IS_UNIX(info_level) && !lp_unix_extensions())
3599 return ERROR_DOS(ERRDOS,ERRunknownlevel);
3601 if (VALID_STAT(sbuf))
3602 unixmode = sbuf.st_mode;
3604 DEBUG(3,("call_trans2setfilepathinfo(%d) %s (fnum %d) info_level=%d totdata=%d\n",
3605 tran_call,fname, fsp ? fsp->fnum : -1, info_level,total_data));
3607 /* Realloc the parameter size */
3608 params = SMB_REALLOC(*pparams,2);
3609 if(params == NULL) {
3610 return ERROR_NT(NT_STATUS_NO_MEMORY);
3616 if (fsp && fsp->pending_modtime) {
3617 /* the pending modtime overrides the current modtime */
3618 sbuf.st_mtime = fsp->pending_modtime;
3621 size = get_file_size(sbuf);
3622 tvs.modtime = sbuf.st_mtime;
3623 tvs.actime = sbuf.st_atime;
3624 dosmode = dos_mode(conn,fname,&sbuf);
3625 unixmode = sbuf.st_mode;
3627 set_owner = VALID_STAT(sbuf) ? sbuf.st_uid : (uid_t)SMB_UID_NO_CHANGE;
3628 set_grp = VALID_STAT(sbuf) ? sbuf.st_gid : (gid_t)SMB_GID_NO_CHANGE;
3630 switch (info_level) {
3631 case SMB_INFO_STANDARD:
3633 if (total_data < 12) {
3634 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
3638 tvs.actime = make_unix_date2(pdata+l1_fdateLastAccess);
3640 tvs.modtime = make_unix_date2(pdata+l1_fdateLastWrite);
3644 case SMB_INFO_SET_EA:
3646 struct ea_list *ea_list = NULL;
3647 TALLOC_CTX *ctx = talloc_init("SMB_INFO_SET_EA");
3649 return ERROR_NT(NT_STATUS_NO_MEMORY);
3651 ea_list = read_ea_list(ctx, pdata, total_data);
3653 talloc_destroy(ctx);
3654 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
3656 status = set_ea(conn, fsp, fname, ea_list);
3657 talloc_destroy(ctx);
3659 if (NT_STATUS_V(status) != NT_STATUS_V(NT_STATUS_OK)) {
3660 return ERROR_NT(status);
3666 /* The following 2 info levels are only valid on query, not set. Remove them. JRA. */
3667 /* XXXX um, i don't think this is right.
3668 it's also not in the cifs6.txt spec.
3670 case SMB_INFO_QUERY_EAS_FROM_LIST:
3671 if (total_data < 28)
3672 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
3674 tvs.actime = make_unix_date2(pdata+8);
3675 tvs.modtime = make_unix_date2(pdata+12);
3676 size = IVAL(pdata,16);
3677 dosmode = IVAL(pdata,24);
3680 /* XXXX nor this. not in cifs6.txt, either. */
3681 case SMB_INFO_QUERY_ALL_EAS:
3682 if (total_data < 28)
3683 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
3685 tvs.actime = make_unix_date2(pdata+8);
3686 tvs.modtime = make_unix_date2(pdata+12);
3687 size = IVAL(pdata,16);
3688 dosmode = IVAL(pdata,24);
3692 case SMB_SET_FILE_BASIC_INFO:
3693 case SMB_FILE_BASIC_INFORMATION:
3695 /* Patch to do this correctly from Paul Eggert <eggert@twinsun.com>. */
3697 time_t changed_time;
3699 if (total_data < 36) {
3700 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
3703 /* Ignore create time at offset pdata. */
3706 tvs.actime = interpret_long_date(pdata+8);
3708 write_time = interpret_long_date(pdata+16);
3709 changed_time = interpret_long_date(pdata+24);
3711 tvs.modtime = MIN(write_time, changed_time);
3713 if (write_time > tvs.modtime && write_time != (time_t)-1) {
3714 tvs.modtime = write_time;
3716 /* Prefer a defined time to an undefined one. */
3717 if (null_mtime(tvs.modtime)) {
3718 tvs.modtime = null_mtime(write_time) ? changed_time : write_time;
3722 dosmode = IVAL(pdata,32);
3726 case SMB_FILE_ALLOCATION_INFORMATION:
3727 case SMB_SET_FILE_ALLOCATION_INFO:
3730 SMB_BIG_UINT allocation_size;
3732 if (total_data < 8) {
3733 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
3736 allocation_size = (SMB_BIG_UINT)IVAL(pdata,0);
3737 #ifdef LARGE_SMB_OFF_T
3738 allocation_size |= (((SMB_BIG_UINT)IVAL(pdata,4)) << 32);
3739 #else /* LARGE_SMB_OFF_T */
3740 if (IVAL(pdata,4) != 0) /* more than 32 bits? */
3741 return ERROR_DOS(ERRDOS,ERRunknownlevel);
3742 #endif /* LARGE_SMB_OFF_T */
3743 DEBUG(10,("call_trans2setfilepathinfo: Set file allocation info for file %s to %.0f\n",
3744 fname, (double)allocation_size ));
3746 if (allocation_size) {
3747 allocation_size = smb_roundup(conn, allocation_size);
3750 if(allocation_size != get_file_size(sbuf)) {
3751 SMB_STRUCT_STAT new_sbuf;
3753 DEBUG(10,("call_trans2setfilepathinfo: file %s : setting new allocation size to %.0f\n",
3754 fname, (double)allocation_size ));
3757 files_struct *new_fsp = NULL;
3758 int access_mode = 0;
3761 if(global_oplock_break) {
3762 /* Queue this file modify as we are the process of an oplock break. */
3764 DEBUG(2,("call_trans2setfilepathinfo: queueing message due to being "));
3765 DEBUGADD(2,( "in oplock break state.\n"));
3767 push_oplock_pending_smb_message(inbuf, length);
3771 new_fsp = open_file_shared1(conn, fname, &sbuf,FILE_WRITE_DATA,
3772 SET_OPEN_MODE(DOS_OPEN_RDWR),
3773 (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN),
3774 FILE_ATTRIBUTE_NORMAL,
3775 INTERNAL_OPEN_ONLY, &access_mode, &action);
3777 if (new_fsp == NULL)
3778 return(UNIXERROR(ERRDOS,ERRbadpath));
3779 ret = vfs_allocate_file_space(new_fsp, allocation_size);
3780 if (SMB_VFS_FSTAT(new_fsp,new_fsp->fd,&new_sbuf) != 0) {
3781 DEBUG(3,("call_trans2setfilepathinfo: fstat of fnum %d failed (%s)\n",
3782 new_fsp->fnum, strerror(errno)));
3785 close_file(new_fsp,True);
3787 ret = vfs_allocate_file_space(fsp, allocation_size);
3788 if (SMB_VFS_FSTAT(fsp,fd,&new_sbuf) != 0) {
3789 DEBUG(3,("call_trans2setfilepathinfo: fstat of fnum %d failed (%s)\n",
3790 fsp->fnum, strerror(errno)));
3795 return ERROR_NT(NT_STATUS_DISK_FULL);
3797 /* Allocate can truncate size... */
3798 size = get_file_size(new_sbuf);
3804 case SMB_FILE_END_OF_FILE_INFORMATION:
3805 case SMB_SET_FILE_END_OF_FILE_INFO:
3807 if (total_data < 8) {
3808 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
3811 size = IVAL(pdata,0);
3812 #ifdef LARGE_SMB_OFF_T
3813 size |= (((SMB_OFF_T)IVAL(pdata,4)) << 32);
3814 #else /* LARGE_SMB_OFF_T */
3815 if (IVAL(pdata,4) != 0) /* more than 32 bits? */
3816 return ERROR_DOS(ERRDOS,ERRunknownlevel);
3817 #endif /* LARGE_SMB_OFF_T */
3818 DEBUG(10,("call_trans2setfilepathinfo: Set end of file info for file %s to %.0f\n", fname, (double)size ));
3822 case SMB_FILE_DISPOSITION_INFORMATION:
3823 case SMB_SET_FILE_DISPOSITION_INFO: /* Set delete on close for open file. */
3825 BOOL delete_on_close;
3827 if (total_data < 1) {
3828 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
3831 delete_on_close = (CVAL(pdata,0) ? True : False);
3833 /* Just ignore this set on a path. */
3834 if (tran_call != TRANSACT2_SETFILEINFO)
3838 return(UNIXERROR(ERRDOS,ERRbadfid));
3840 status = set_delete_on_close_internal(fsp, delete_on_close, dosmode);
3842 if (NT_STATUS_V(status) != NT_STATUS_V(NT_STATUS_OK))
3843 return ERROR_NT(status);
3845 /* The set is across all open files on this dev/inode pair. */
3846 status =set_delete_on_close_over_all(fsp, delete_on_close);
3847 if (NT_STATUS_V(status) != NT_STATUS_V(NT_STATUS_OK))
3848 return ERROR_NT(status);
3853 case SMB_FILE_POSITION_INFORMATION:
3855 SMB_BIG_UINT position_information;
3857 if (total_data < 8) {
3858 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
3861 position_information = (SMB_BIG_UINT)IVAL(pdata,0);
3862 #ifdef LARGE_SMB_OFF_T
3863 position_information |= (((SMB_BIG_UINT)IVAL(pdata,4)) << 32);
3864 #else /* LARGE_SMB_OFF_T */
3865 if (IVAL(pdata,4) != 0) /* more than 32 bits? */
3866 return ERROR_DOS(ERRDOS,ERRunknownlevel);
3867 #endif /* LARGE_SMB_OFF_T */
3868 DEBUG(10,("call_trans2setfilepathinfo: Set file position information for file %s to %.0f\n",
3869 fname, (double)position_information ));
3871 fsp->position_information = position_information;
3875 /* From tridge Samba4 :
3876 * MODE_INFORMATION in setfileinfo (I have no
3877 * idea what "mode information" on a file is - it takes a value of 0,
3878 * 2, 4 or 6. What could it be?).
3881 case SMB_FILE_MODE_INFORMATION:
3885 if (total_data < 4) {
3886 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
3888 mode = IVAL(pdata,0);
3889 if (mode != 0 && mode != 2 && mode != 4 && mode != 6) {
3890 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
3896 * CIFS UNIX extensions.
3899 case SMB_SET_FILE_UNIX_BASIC:
3901 uint32 raw_unixmode;
3903 if (total_data < 100) {
3904 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
3907 if(IVAL(pdata, 0) != SMB_SIZE_NO_CHANGE_LO &&
3908 IVAL(pdata, 4) != SMB_SIZE_NO_CHANGE_HI) {
3909 size=IVAL(pdata,0); /* first 8 Bytes are size */
3910 #ifdef LARGE_SMB_OFF_T
3911 size |= (((SMB_OFF_T)IVAL(pdata,4)) << 32);
3912 #else /* LARGE_SMB_OFF_T */
3913 if (IVAL(pdata,4) != 0) /* more than 32 bits? */
3914 return ERROR_DOS(ERRDOS,ERRunknownlevel);
3915 #endif /* LARGE_SMB_OFF_T */
3917 pdata+=24; /* ctime & st_blocks are not changed */
3918 tvs.actime = interpret_long_date(pdata); /* access_time */
3919 tvs.modtime = interpret_long_date(pdata+8); /* modification_time */
3921 set_owner = (uid_t)IVAL(pdata,0);
3923 set_grp = (gid_t)IVAL(pdata,0);
3925 raw_unixmode = IVAL(pdata,28);
3926 unixmode = unix_perms_from_wire(conn, &sbuf, raw_unixmode);
3927 dosmode = 0; /* Ensure dos mode change doesn't override this. */
3929 DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_BASIC: name = %s \
3930 size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n",
3931 fname, (double)size, (unsigned int)set_owner, (unsigned int)set_grp, (int)raw_unixmode));
3933 if (!VALID_STAT(sbuf)) {
3936 * The only valid use of this is to create character and block
3937 * devices, and named pipes. This is deprecated (IMHO) and
3938 * a new info level should be used for mknod. JRA.
3941 uint32 file_type = IVAL(pdata,0);
3942 #if defined(HAVE_MAKEDEV)
3943 uint32 dev_major = IVAL(pdata,4);
3944 uint32 dev_minor = IVAL(pdata,12);
3947 uid_t myuid = geteuid();
3948 gid_t mygid = getegid();
3949 SMB_DEV_T dev = (SMB_DEV_T)0;
3951 if (tran_call == TRANSACT2_SETFILEINFO)
3952 return(ERROR_DOS(ERRDOS,ERRnoaccess));
3954 if (raw_unixmode == SMB_MODE_NO_CHANGE) {
3955 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
3958 #if defined(HAVE_MAKEDEV)
3959 dev = makedev(dev_major, dev_minor);
3962 /* We can only create as the owner/group we are. */
3964 if ((set_owner != myuid) && (set_owner != (uid_t)SMB_UID_NO_CHANGE))
3965 return(ERROR_DOS(ERRDOS,ERRnoaccess));
3966 if ((set_grp != mygid) && (set_grp != (gid_t)SMB_GID_NO_CHANGE))
3967 return(ERROR_DOS(ERRDOS,ERRnoaccess));
3969 switch (file_type) {
3970 #if defined(S_IFIFO)
3971 case UNIX_TYPE_FIFO:
3972 unixmode |= S_IFIFO;
3975 #if defined(S_IFSOCK)
3976 case UNIX_TYPE_SOCKET:
3977 unixmode |= S_IFSOCK;
3980 #if defined(S_IFCHR)
3981 case UNIX_TYPE_CHARDEV:
3982 unixmode |= S_IFCHR;
3985 #if defined(S_IFBLK)
3986 case UNIX_TYPE_BLKDEV:
3987 unixmode |= S_IFBLK;
3991 return(ERROR_DOS(ERRDOS,ERRnoaccess));
3994 DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_BASIC doing mknod dev %.0f mode \
3995 0%o for file %s\n", (double)dev, unixmode, fname ));
3997 /* Ok - do the mknod. */
3998 if (SMB_VFS_MKNOD(conn,fname, unixmode, dev) != 0)
3999 return(UNIXERROR(ERRDOS,ERRnoaccess));
4001 inherit_access_acl(conn, fname, unixmode);
4004 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
4009 * Deal with the UNIX specific mode set.
4012 if (raw_unixmode != SMB_MODE_NO_CHANGE) {
4013 DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_BASIC setting mode 0%o for file %s\n",
4014 (unsigned int)unixmode, fname ));
4015 if (SMB_VFS_CHMOD(conn,fname,unixmode) != 0)
4016 return(UNIXERROR(ERRDOS,ERRnoaccess));
4020 * Deal with the UNIX specific uid set.
4023 if ((set_owner != (uid_t)SMB_UID_NO_CHANGE) && (sbuf.st_uid != set_owner)) {
4024 DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_BASIC changing owner %u for file %s\n",
4025 (unsigned int)set_owner, fname ));
4026 if (SMB_VFS_CHOWN(conn,fname,set_owner, (gid_t)-1) != 0)
4027 return(UNIXERROR(ERRDOS,ERRnoaccess));
4031 * Deal with the UNIX specific gid set.
4034 if ((set_grp != (uid_t)SMB_GID_NO_CHANGE) && (sbuf.st_gid != set_grp)) {
4035 DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_BASIC changing group %u for file %s\n",
4036 (unsigned int)set_owner, fname ));
4037 if (SMB_VFS_CHOWN(conn,fname,(uid_t)-1, set_grp) != 0)
4038 return(UNIXERROR(ERRDOS,ERRnoaccess));
4043 case SMB_SET_FILE_UNIX_LINK:
4045 pstring link_target;
4046 char *newname = fname;
4048 /* Set a symbolic link. */
4049 /* Don't allow this if follow links is false. */
4051 if (!lp_symlinks(SNUM(conn)))
4052 return(ERROR_DOS(ERRDOS,ERRnoaccess));
4054 srvstr_pull(inbuf, link_target, pdata, sizeof(link_target), -1, STR_TERMINATE);
4056 /* !widelinks forces the target path to be within the share. */
4057 /* This means we can interpret the target as a pathname. */
4058 if (!lp_widelinks(SNUM(conn))) {
4060 char *last_dirp = NULL;
4062 unix_format(link_target);
4063 if (*link_target == '/') {
4064 /* No absolute paths allowed. */
4065 return(UNIXERROR(ERRDOS,ERRnoaccess));
4067 pstrcpy(rel_name, newname);
4068 last_dirp = strrchr_m(rel_name, '/');
4070 last_dirp[1] = '\0';
4072 pstrcpy(rel_name, "./");
4074 pstrcat(rel_name, link_target);
4076 if (!check_name(rel_name, conn)) {
4077 return(UNIXERROR(ERRDOS,ERRnoaccess));
4081 DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_LINK doing symlink %s -> %s\n",
4082 fname, link_target ));
4084 if (SMB_VFS_SYMLINK(conn,link_target,newname) != 0)
4085 return(UNIXERROR(ERRDOS,ERRnoaccess));
4087 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
4091 case SMB_SET_FILE_UNIX_HLINK:
4094 char *newname = fname;
4096 /* Set a hard link. */
4097 srvstr_get_path(inbuf, oldname, pdata, sizeof(oldname), -1, STR_TERMINATE, &status, False);
4098 if (!NT_STATUS_IS_OK(status)) {
4099 return ERROR_NT(status);
4102 DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_LINK doing hard link %s -> %s\n",
4105 status = hardlink_internals(conn, oldname, newname);
4106 if (!NT_STATUS_IS_OK(status)) {
4107 return ERROR_NT(status);
4111 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
4115 case SMB_FILE_RENAME_INFORMATION:
4124 if (total_data < 12) {
4125 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
4128 overwrite = (CVAL(pdata,0) ? True : False);
4129 root_fid = IVAL(pdata,4);
4130 len = IVAL(pdata,8);
4131 srvstr_get_path(inbuf, newname, &pdata[12], sizeof(newname), len, 0, &status, False);
4132 if (!NT_STATUS_IS_OK(status)) {
4133 return ERROR_NT(status);
4136 /* Check the new name has no '/' characters. */
4137 if (strchr_m(newname, '/'))
4138 return ERROR_NT(NT_STATUS_NOT_SUPPORTED);
4140 RESOLVE_DFSPATH(newname, conn, inbuf, outbuf);
4142 /* Create the base directory. */
4143 pstrcpy(base_name, fname);
4144 p = strrchr_m(base_name, '/');
4147 /* Append the new name. */
4148 pstrcat(base_name, "/");
4149 pstrcat(base_name, newname);
4152 DEBUG(10,("call_trans2setfilepathinfo: SMB_FILE_RENAME_INFORMATION (fnum %d) %s -> %s\n",
4153 fsp->fnum, fsp->fsp_name, base_name ));
4154 status = rename_internals_fsp(conn, fsp, base_name, 0, overwrite);
4156 DEBUG(10,("call_trans2setfilepathinfo: SMB_FILE_RENAME_INFORMATION %s -> %s\n",
4158 status = rename_internals(conn, fname, base_name, 0, overwrite);
4160 if (!NT_STATUS_IS_OK(status)) {
4161 return ERROR_NT(status);
4163 process_pending_change_notify_queue((time_t)0);
4165 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
4169 #if defined(HAVE_POSIX_ACLS)
4170 case SMB_SET_POSIX_ACL:
4172 uint16 posix_acl_version;
4173 uint16 num_file_acls;
4174 uint16 num_def_acls;
4175 BOOL valid_file_acls = True;
4176 BOOL valid_def_acls = True;
4178 if (total_data < SMB_POSIX_ACL_HEADER_SIZE) {
4179 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
4181 posix_acl_version = SVAL(pdata,0);
4182 num_file_acls = SVAL(pdata,2);
4183 num_def_acls = SVAL(pdata,4);
4185 if (num_file_acls == SMB_POSIX_IGNORE_ACE_ENTRIES) {
4186 valid_file_acls = False;
4190 if (num_def_acls == SMB_POSIX_IGNORE_ACE_ENTRIES) {
4191 valid_def_acls = False;
4195 if (posix_acl_version != SMB_POSIX_ACL_VERSION) {
4196 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
4199 if (total_data < SMB_POSIX_ACL_HEADER_SIZE +
4200 (num_file_acls+num_def_acls)*SMB_POSIX_ACL_ENTRY_SIZE) {
4201 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
4204 if (valid_file_acls && !set_unix_posix_acl(conn, fsp, fname, num_file_acls,
4205 pdata + SMB_POSIX_ACL_HEADER_SIZE)) {
4206 return(UNIXERROR(ERRDOS,ERRnoaccess));
4209 if (valid_def_acls && !set_unix_posix_default_acl(conn, fname, &sbuf, num_def_acls,
4210 pdata + SMB_POSIX_ACL_HEADER_SIZE +
4211 (num_file_acls*SMB_POSIX_ACL_ENTRY_SIZE))) {
4212 return(UNIXERROR(ERRDOS,ERRnoaccess));
4216 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
4222 return ERROR_DOS(ERRDOS,ERRunknownlevel);
4225 /* get some defaults (no modifications) if any info is zero or -1. */
4226 if (null_mtime(tvs.actime)) {
4227 tvs.actime = sbuf.st_atime;
4230 if (null_mtime(tvs.modtime)) {
4231 tvs.modtime = sbuf.st_mtime;
4234 DEBUG(6,("actime: %s " , ctime(&tvs.actime)));
4235 DEBUG(6,("modtime: %s ", ctime(&tvs.modtime)));
4236 DEBUG(6,("size: %.0f ", (double)size));
4239 if (S_ISDIR(sbuf.st_mode))
4245 DEBUG(6,("dosmode: %x\n" , dosmode));
4247 if(!((info_level == SMB_SET_FILE_END_OF_FILE_INFO) ||
4248 (info_level == SMB_SET_FILE_ALLOCATION_INFO) ||
4249 (info_level == SMB_FILE_ALLOCATION_INFORMATION) ||
4250 (info_level == SMB_FILE_END_OF_FILE_INFORMATION))) {
4253 * Only do this test if we are not explicitly
4254 * changing the size of a file.
4257 size = get_file_size(sbuf);
4261 * Try and set the times, size and mode of this file -
4262 * if they are different from the current values
4265 /* check the mode isn't different, before changing it */
4266 if ((dosmode != 0) && (dosmode != dos_mode(conn, fname, &sbuf))) {
4268 DEBUG(10,("call_trans2setfilepathinfo: file %s : setting dos mode %x\n", fname, dosmode ));
4270 if(file_set_dosmode(conn, fname, dosmode, &sbuf, False)) {
4271 DEBUG(2,("file_set_dosmode of %s failed (%s)\n", fname, strerror(errno)));
4272 return(UNIXERROR(ERRDOS,ERRnoaccess));
4277 if (size != get_file_size(sbuf)) {
4281 DEBUG(10,("call_trans2setfilepathinfo: file %s : setting new size to %.0f\n",
4282 fname, (double)size ));
4285 files_struct *new_fsp = NULL;
4286 int access_mode = 0;
4289 if(global_oplock_break) {
4290 /* Queue this file modify as we are the process of an oplock break. */
4292 DEBUG(2,("call_trans2setfilepathinfo: queueing message due to being "));
4293 DEBUGADD(2,( "in oplock break state.\n"));
4295 push_oplock_pending_smb_message(inbuf, length);
4299 new_fsp = open_file_shared(conn, fname, &sbuf,
4300 SET_OPEN_MODE(DOS_OPEN_RDWR),
4301 (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN),
4302 FILE_ATTRIBUTE_NORMAL,
4303 INTERNAL_OPEN_ONLY, &access_mode, &action);
4305 if (new_fsp == NULL)
4306 return(UNIXERROR(ERRDOS,ERRbadpath));
4307 ret = vfs_set_filelen(new_fsp, size);
4308 close_file(new_fsp,True);
4310 ret = vfs_set_filelen(fsp, size);
4314 return (UNIXERROR(ERRHRD,ERRdiskfull));
4318 * Finally the times.
4320 if (sbuf.st_mtime != tvs.modtime || sbuf.st_atime != tvs.actime) {
4323 * This was a setfileinfo on an open file.
4324 * NT does this a lot. We also need to
4325 * set the time here, as it can be read by
4326 * FindFirst/FindNext and with the patch for bug #2045
4327 * in smbd/fileio.c it ensures that this timestamp is
4328 * kept sticky even after a write. We save the request
4329 * away and will set it on file close and after a write. JRA.
4332 if (tvs.modtime != (time_t)0 && tvs.modtime != (time_t)-1) {
4333 DEBUG(10,("call_trans2setfilepathinfo: setting pending modtime to %s\n", ctime(&tvs.modtime) ));
4334 fsp_set_pending_modtime(fsp, tvs.modtime);
4338 DEBUG(10,("call_trans2setfilepathinfo: setting utimes to modified values.\n"));
4340 if(file_utime(conn, fname, &tvs)!=0) {
4341 return(UNIXERROR(ERRDOS,ERRnoaccess));
4346 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
4351 /****************************************************************************
4352 Reply to a TRANS2_MKDIR (make directory with extended attributes).
4353 ****************************************************************************/
4355 static int call_trans2mkdir(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize,
4356 char **pparams, int total_params, char **ppdata, int total_data,
4357 unsigned int max_data_bytes)
4359 char *params = *pparams;
4362 SMB_STRUCT_STAT sbuf;
4363 BOOL bad_path = False;
4364 NTSTATUS status = NT_STATUS_OK;
4366 if (!CAN_WRITE(conn))
4367 return ERROR_DOS(ERRSRV,ERRaccess);
4369 if (total_params < 4) {
4370 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
4373 srvstr_get_path(inbuf, directory, ¶ms[4], sizeof(directory), -1, STR_TERMINATE, &status, False);
4374 if (!NT_STATUS_IS_OK(status)) {
4375 return ERROR_NT(status);
4378 DEBUG(3,("call_trans2mkdir : name = %s\n", directory));
4380 unix_convert(directory,conn,0,&bad_path,&sbuf);
4382 return ERROR_NT(NT_STATUS_OBJECT_PATH_NOT_FOUND);
4384 if (check_name(directory,conn))
4385 ret = vfs_MkDir(conn,directory,unix_mode(conn,aDIR,directory,True));
4388 DEBUG(5,("call_trans2mkdir error (%s)\n", strerror(errno)));
4389 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRnoaccess);
4392 /* Realloc the parameter and data sizes */
4393 params = SMB_REALLOC(*pparams,2);
4394 if(params == NULL) {
4395 return ERROR_NT(NT_STATUS_NO_MEMORY);
4401 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
4406 /****************************************************************************
4407 Reply to a TRANS2_FINDNOTIFYFIRST (start monitoring a directory for changes).
4408 We don't actually do this - we just send a null response.
4409 ****************************************************************************/
4411 static int call_trans2findnotifyfirst(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize,
4412 char **pparams, int total_params, char **ppdata, int total_data,
4413 unsigned int max_data_bytes)
4415 static uint16 fnf_handle = 257;
4416 char *params = *pparams;
4419 if (total_params < 6) {
4420 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
4423 info_level = SVAL(params,4);
4424 DEBUG(3,("call_trans2findnotifyfirst - info_level %d\n", info_level));
4426 switch (info_level) {
4431 return ERROR_DOS(ERRDOS,ERRunknownlevel);
4434 /* Realloc the parameter and data sizes */
4435 params = SMB_REALLOC(*pparams,6);
4436 if(params == NULL) {
4437 return ERROR_NT(NT_STATUS_NO_MEMORY);
4441 SSVAL(params,0,fnf_handle);
4442 SSVAL(params,2,0); /* No changes */
4443 SSVAL(params,4,0); /* No EA errors */
4450 send_trans2_replies(outbuf, bufsize, params, 6, *ppdata, 0);
4455 /****************************************************************************
4456 Reply to a TRANS2_FINDNOTIFYNEXT (continue monitoring a directory for
4457 changes). Currently this does nothing.
4458 ****************************************************************************/
4460 static int call_trans2findnotifynext(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize,
4461 char **pparams, int total_params, char **ppdata, int total_data,
4462 unsigned int max_data_bytes)
4464 char *params = *pparams;
4466 DEBUG(3,("call_trans2findnotifynext\n"));
4468 /* Realloc the parameter and data sizes */
4469 params = SMB_REALLOC(*pparams,4);
4470 if(params == NULL) {
4471 return ERROR_NT(NT_STATUS_NO_MEMORY);
4475 SSVAL(params,0,0); /* No changes */
4476 SSVAL(params,2,0); /* No EA errors */
4478 send_trans2_replies(outbuf, bufsize, params, 4, *ppdata, 0);
4483 /****************************************************************************
4484 Reply to a TRANS2_GET_DFS_REFERRAL - Shirish Kalele <kalele@veritas.com>.
4485 ****************************************************************************/
4487 static int call_trans2getdfsreferral(connection_struct *conn, char* inbuf, char* outbuf, int length, int bufsize,
4488 char **pparams, int total_params, char **ppdata, int total_data,
4489 unsigned int max_data_bytes)
4491 char *params = *pparams;
4494 int max_referral_level;
4496 DEBUG(10,("call_trans2getdfsreferral\n"));
4498 if (total_params < 2) {
4499 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
4502 max_referral_level = SVAL(params,0);
4504 if(!lp_host_msdfs())
4505 return ERROR_DOS(ERRDOS,ERRbadfunc);
4507 srvstr_pull(inbuf, pathname, ¶ms[2], sizeof(pathname), -1, STR_TERMINATE);
4508 if((reply_size = setup_dfs_referral(conn, pathname,max_referral_level,ppdata)) < 0)
4509 return UNIXERROR(ERRDOS,ERRbadfile);
4511 SSVAL(outbuf,smb_flg2,SVAL(outbuf,smb_flg2) | FLAGS2_DFS_PATHNAMES);
4512 send_trans2_replies(outbuf,bufsize,0,0,*ppdata,reply_size);
4517 #define LMCAT_SPL 0x53
4518 #define LMFUNC_GETJOBID 0x60
4520 /****************************************************************************
4521 Reply to a TRANS2_IOCTL - used for OS/2 printing.
4522 ****************************************************************************/
4524 static int call_trans2ioctl(connection_struct *conn, char* inbuf, char* outbuf, int length, int bufsize,
4525 char **pparams, int total_params, char **ppdata, int total_data,
4526 unsigned int max_data_bytes)
4528 char *pdata = *ppdata;
4529 files_struct *fsp = file_fsp(inbuf,smb_vwv15);
4531 /* check for an invalid fid before proceeding */
4534 return(ERROR_DOS(ERRDOS,ERRbadfid));
4536 if ((SVAL(inbuf,(smb_setup+4)) == LMCAT_SPL) &&
4537 (SVAL(inbuf,(smb_setup+6)) == LMFUNC_GETJOBID)) {
4538 pdata = SMB_REALLOC(*ppdata, 32);
4540 return ERROR_NT(NT_STATUS_NO_MEMORY);
4544 /* NOTE - THIS IS ASCII ONLY AT THE MOMENT - NOT SURE IF OS/2
4545 CAN ACCEPT THIS IN UNICODE. JRA. */
4547 SSVAL(pdata,0,fsp->rap_print_jobid); /* Job number */
4548 srvstr_push( outbuf, pdata + 2, global_myname(), 15, STR_ASCII|STR_TERMINATE); /* Our NetBIOS name */
4549 srvstr_push( outbuf, pdata+18, lp_servicename(SNUM(conn)), 13, STR_ASCII|STR_TERMINATE); /* Service name */
4550 send_trans2_replies(outbuf,bufsize,*pparams,0,*ppdata,32);
4553 DEBUG(2,("Unknown TRANS2_IOCTL\n"));
4554 return ERROR_DOS(ERRSRV,ERRerror);
4558 /****************************************************************************
4559 Reply to a SMBfindclose (stop trans2 directory search).
4560 ****************************************************************************/
4562 int reply_findclose(connection_struct *conn,
4563 char *inbuf,char *outbuf,int length,int bufsize)
4566 int dptr_num=SVALS(inbuf,smb_vwv0);
4567 START_PROFILE(SMBfindclose);
4569 DEBUG(3,("reply_findclose, dptr_num = %d\n", dptr_num));
4571 dptr_close(&dptr_num);
4573 outsize = set_message(outbuf,0,0,True);
4575 DEBUG(3,("SMBfindclose dptr_num = %d\n", dptr_num));
4577 END_PROFILE(SMBfindclose);
4581 /****************************************************************************
4582 Reply to a SMBfindnclose (stop FINDNOTIFYFIRST directory search).
4583 ****************************************************************************/
4585 int reply_findnclose(connection_struct *conn,
4586 char *inbuf,char *outbuf,int length,int bufsize)
4590 START_PROFILE(SMBfindnclose);
4592 dptr_num = SVAL(inbuf,smb_vwv0);
4594 DEBUG(3,("reply_findnclose, dptr_num = %d\n", dptr_num));
4596 /* We never give out valid handles for a
4597 findnotifyfirst - so any dptr_num is ok here.
4600 outsize = set_message(outbuf,0,0,True);
4602 DEBUG(3,("SMB_findnclose dptr_num = %d\n", dptr_num));
4604 END_PROFILE(SMBfindnclose);
4608 /****************************************************************************
4609 Reply to a SMBtranss2 - just ignore it!
4610 ****************************************************************************/
4612 int reply_transs2(connection_struct *conn,
4613 char *inbuf,char *outbuf,int length,int bufsize)
4615 START_PROFILE(SMBtranss2);
4616 DEBUG(4,("Ignoring transs2 of length %d\n",length));
4617 END_PROFILE(SMBtranss2);
4621 /****************************************************************************
4622 Reply to a SMBtrans2.
4623 ****************************************************************************/
4625 int reply_trans2(connection_struct *conn,
4626 char *inbuf,char *outbuf,int length,int bufsize)
4629 unsigned int total_params = SVAL(inbuf, smb_tpscnt);
4630 unsigned int total_data =SVAL(inbuf, smb_tdscnt);
4631 unsigned int max_data_bytes = SVAL(inbuf, smb_mdrcnt);
4633 unsigned int max_param_reply = SVAL(inbuf, smb_mprcnt);
4634 unsigned int max_setup_fields = SVAL(inbuf, smb_msrcnt);
4635 BOOL close_tid = BITSETW(inbuf+smb_flags,0);
4636 BOOL no_final_response = BITSETW(inbuf+smb_flags,1);
4637 int32 timeout = IVALS(inbuf,smb_timeout);
4639 unsigned int suwcnt = SVAL(inbuf, smb_suwcnt);
4640 unsigned int tran_call = SVAL(inbuf, smb_setup0);
4641 char *params = NULL, *data = NULL;
4642 unsigned int num_params, num_params_sofar, num_data, num_data_sofar;
4643 START_PROFILE(SMBtrans2);
4645 if(global_oplock_break && (tran_call == TRANSACT2_OPEN)) {
4646 /* Queue this open message as we are the process of an
4649 DEBUG(2,("reply_trans2: queueing message trans2open due to being "));
4650 DEBUGADD(2,( "in oplock break state.\n"));
4652 push_oplock_pending_smb_message(inbuf, length);
4653 END_PROFILE(SMBtrans2);
4657 if (IS_IPC(conn) && (tran_call != TRANSACT2_OPEN)
4658 && (tran_call != TRANSACT2_GET_DFS_REFERRAL)) {
4659 END_PROFILE(SMBtrans2);
4660 return ERROR_DOS(ERRSRV,ERRaccess);
4663 outsize = set_message(outbuf,0,0,True);
4665 /* All trans2 messages we handle have smb_sucnt == 1 - ensure this
4666 is so as a sanity check */
4669 * Need to have rc=0 for ioctl to get job id for OS/2.
4670 * Network printing will fail if function is not successful.
4671 * Similar function in reply.c will be used if protocol
4672 * is LANMAN1.0 instead of LM1.2X002.
4673 * Until DosPrintSetJobInfo with PRJINFO3 is supported,
4674 * outbuf doesn't have to be set(only job id is used).
4676 if ( (suwcnt == 4) && (tran_call == TRANSACT2_IOCTL) &&
4677 (SVAL(inbuf,(smb_setup+4)) == LMCAT_SPL) &&
4678 (SVAL(inbuf,(smb_setup+6)) == LMFUNC_GETJOBID)) {
4679 DEBUG(2,("Got Trans2 DevIOctl jobid\n"));
4681 DEBUG(2,("Invalid smb_sucnt in trans2 call(%u)\n",suwcnt));
4682 DEBUG(2,("Transaction is %d\n",tran_call));
4683 END_PROFILE(SMBtrans2);
4684 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
4688 /* Allocate the space for the maximum needed parameters and data */
4689 if (total_params > 0)
4690 params = (char *)SMB_MALLOC(total_params);
4692 data = (char *)SMB_MALLOC(total_data);
4694 if ((total_params && !params) || (total_data && !data)) {
4695 DEBUG(2,("Out of memory in reply_trans2\n"));
4698 END_PROFILE(SMBtrans2);
4699 return ERROR_NT(NT_STATUS_NO_MEMORY);
4702 /* Copy the param and data bytes sent with this request into
4703 the params buffer */
4704 num_params = num_params_sofar = SVAL(inbuf,smb_pscnt);
4705 num_data = num_data_sofar = SVAL(inbuf, smb_dscnt);
4707 if (num_params > total_params || num_data > total_data)
4708 exit_server("invalid params in reply_trans2");
4711 unsigned int psoff = SVAL(inbuf, smb_psoff);
4712 if ((psoff + num_params < psoff) || (psoff + num_params < num_params))
4714 if ((smb_base(inbuf) + psoff + num_params > inbuf + length) ||
4715 (smb_base(inbuf) + psoff + num_params < smb_base(inbuf)))
4717 memcpy( params, smb_base(inbuf) + psoff, num_params);
4720 unsigned int dsoff = SVAL(inbuf, smb_dsoff);
4721 if ((dsoff + num_data < dsoff) || (dsoff + num_data < num_data))
4723 if ((smb_base(inbuf) + dsoff + num_data > inbuf + length) ||
4724 (smb_base(inbuf) + dsoff + num_data < smb_base(inbuf)))
4726 memcpy( data, smb_base(inbuf) + dsoff, num_data);
4729 srv_signing_trans_start(SVAL(inbuf,smb_mid));
4731 if(num_data_sofar < total_data || num_params_sofar < total_params) {
4732 /* We need to send an interim response then receive the rest
4733 of the parameter/data bytes */
4734 outsize = set_message(outbuf,0,0,True);
4735 srv_signing_trans_stop();
4736 if (!send_smb(smbd_server_fd(),outbuf))
4737 exit_server("reply_trans2: send_smb failed.");
4739 while (num_data_sofar < total_data ||
4740 num_params_sofar < total_params) {
4742 unsigned int param_disp;
4743 unsigned int param_off;
4744 unsigned int data_disp;
4745 unsigned int data_off;
4747 ret = receive_next_smb(inbuf,bufsize,SMB_SECONDARY_WAIT);
4750 * The sequence number for the trans reply is always
4751 * based on the last secondary received.
4754 srv_signing_trans_start(SVAL(inbuf,smb_mid));
4757 (CVAL(inbuf, smb_com) != SMBtranss2)) || !ret) {
4758 outsize = set_message(outbuf,0,0,True);
4760 DEBUG(0,("reply_trans2: Invalid secondary trans2 packet\n"));
4762 DEBUG(0,("reply_trans2: %s in getting secondary trans2 response.\n",
4763 (smb_read_error == READ_ERROR) ? "error" : "timeout" ));
4767 /* Revise total_params and total_data in case
4768 they have changed downwards */
4769 if (SVAL(inbuf, smb_tpscnt) < total_params)
4770 total_params = SVAL(inbuf, smb_tpscnt);
4771 if (SVAL(inbuf, smb_tdscnt) < total_data)
4772 total_data = SVAL(inbuf, smb_tdscnt);
4774 num_params = SVAL(inbuf,smb_spscnt);
4775 param_off = SVAL(inbuf, smb_spsoff);
4776 param_disp = SVAL(inbuf, smb_spsdisp);
4777 num_params_sofar += num_params;
4779 num_data = SVAL(inbuf, smb_sdscnt);
4780 data_off = SVAL(inbuf, smb_sdsoff);
4781 data_disp = SVAL(inbuf, smb_sdsdisp);
4782 num_data_sofar += num_data;
4784 if (num_params_sofar > total_params || num_data_sofar > total_data)
4788 if (param_disp + num_params > total_params)
4790 if ((param_disp + num_params < param_disp) ||
4791 (param_disp + num_params < num_params))
4793 if (param_disp > total_params)
4795 if ((smb_base(inbuf) + param_off + num_params >= inbuf + bufsize) ||
4796 (smb_base(inbuf) + param_off + num_params < smb_base(inbuf)))
4798 if (params + param_disp < params)
4801 memcpy( ¶ms[param_disp], smb_base(inbuf) + param_off, num_params);
4804 if (data_disp + num_data > total_data)
4806 if ((data_disp + num_data < data_disp) ||
4807 (data_disp + num_data < num_data))
4809 if (data_disp > total_data)
4811 if ((smb_base(inbuf) + data_off + num_data >= inbuf + bufsize) ||
4812 (smb_base(inbuf) + data_off + num_data < smb_base(inbuf)))
4814 if (data + data_disp < data)
4817 memcpy( &data[data_disp], smb_base(inbuf) + data_off, num_data);
4822 if (Protocol >= PROTOCOL_NT1) {
4823 SSVAL(outbuf,smb_flg2,SVAL(outbuf,smb_flg2) | 0x40); /* IS_LONG_NAME */
4826 /* Now we must call the relevant TRANS2 function */
4828 case TRANSACT2_OPEN:
4829 START_PROFILE_NESTED(Trans2_open);
4830 outsize = call_trans2open(conn, inbuf, outbuf, bufsize,
4831 ¶ms, total_params, &data, total_data, max_data_bytes);
4832 END_PROFILE_NESTED(Trans2_open);
4835 case TRANSACT2_FINDFIRST:
4836 START_PROFILE_NESTED(Trans2_findfirst);
4837 outsize = call_trans2findfirst(conn, inbuf, outbuf, bufsize,
4838 ¶ms, total_params, &data, total_data, max_data_bytes);
4839 END_PROFILE_NESTED(Trans2_findfirst);
4842 case TRANSACT2_FINDNEXT:
4843 START_PROFILE_NESTED(Trans2_findnext);
4844 outsize = call_trans2findnext(conn, inbuf, outbuf, length, bufsize,
4845 ¶ms, total_params, &data, total_data, max_data_bytes);
4846 END_PROFILE_NESTED(Trans2_findnext);
4849 case TRANSACT2_QFSINFO:
4850 START_PROFILE_NESTED(Trans2_qfsinfo);
4851 outsize = call_trans2qfsinfo(conn, inbuf, outbuf, length, bufsize,
4852 ¶ms, total_params, &data, total_data, max_data_bytes);
4853 END_PROFILE_NESTED(Trans2_qfsinfo);
4856 #ifdef HAVE_SYS_QUOTAS
4857 case TRANSACT2_SETFSINFO:
4858 START_PROFILE_NESTED(Trans2_setfsinfo);
4859 outsize = call_trans2setfsinfo(conn, inbuf, outbuf, length, bufsize,
4860 ¶ms, total_params, &data, total_data, max_data_bytes);
4861 END_PROFILE_NESTED(Trans2_setfsinfo);
4864 case TRANSACT2_QPATHINFO:
4865 case TRANSACT2_QFILEINFO:
4866 START_PROFILE_NESTED(Trans2_qpathinfo);
4867 outsize = call_trans2qfilepathinfo(conn, inbuf, outbuf, length, bufsize,
4868 ¶ms, total_params, &data, total_data, max_data_bytes);
4869 END_PROFILE_NESTED(Trans2_qpathinfo);
4871 case TRANSACT2_SETPATHINFO:
4872 case TRANSACT2_SETFILEINFO:
4873 START_PROFILE_NESTED(Trans2_setpathinfo);
4874 outsize = call_trans2setfilepathinfo(conn, inbuf, outbuf, length, bufsize,
4875 ¶ms, total_params, &data, total_data, max_data_bytes);
4876 END_PROFILE_NESTED(Trans2_setpathinfo);
4879 case TRANSACT2_FINDNOTIFYFIRST:
4880 START_PROFILE_NESTED(Trans2_findnotifyfirst);
4881 outsize = call_trans2findnotifyfirst(conn, inbuf, outbuf, length, bufsize,
4882 ¶ms, total_params, &data, total_data, max_data_bytes);
4883 END_PROFILE_NESTED(Trans2_findnotifyfirst);
4886 case TRANSACT2_FINDNOTIFYNEXT:
4887 START_PROFILE_NESTED(Trans2_findnotifynext);
4888 outsize = call_trans2findnotifynext(conn, inbuf, outbuf, length, bufsize,
4889 ¶ms, total_params, &data, total_data, max_data_bytes);
4890 END_PROFILE_NESTED(Trans2_findnotifynext);
4892 case TRANSACT2_MKDIR:
4893 START_PROFILE_NESTED(Trans2_mkdir);
4894 outsize = call_trans2mkdir(conn, inbuf, outbuf, length, bufsize,
4895 ¶ms, total_params, &data, total_data, max_data_bytes);
4896 END_PROFILE_NESTED(Trans2_mkdir);
4899 case TRANSACT2_GET_DFS_REFERRAL:
4900 START_PROFILE_NESTED(Trans2_get_dfs_referral);
4901 outsize = call_trans2getdfsreferral(conn,inbuf,outbuf,length, bufsize,
4902 ¶ms, total_params, &data, total_data, max_data_bytes);
4903 END_PROFILE_NESTED(Trans2_get_dfs_referral);
4905 case TRANSACT2_IOCTL:
4906 START_PROFILE_NESTED(Trans2_ioctl);
4907 outsize = call_trans2ioctl(conn,inbuf,outbuf,length, bufsize,
4908 ¶ms, total_params, &data, total_data, max_data_bytes);
4909 END_PROFILE_NESTED(Trans2_ioctl);
4912 /* Error in request */
4913 DEBUG(2,("Unknown request %d in trans2 call\n", tran_call));
4916 END_PROFILE(SMBtrans2);
4917 srv_signing_trans_stop();
4918 return ERROR_DOS(ERRSRV,ERRerror);
4921 /* As we do not know how many data packets will need to be
4922 returned here the various call_trans2xxxx calls
4923 must send their own. Thus a call_trans2xxx routine only
4924 returns a value other than -1 when it wants to send
4928 srv_signing_trans_stop();
4932 END_PROFILE(SMBtrans2);
4933 return outsize; /* If a correct response was needed the
4934 call_trans2xxx calls have already sent
4935 it. If outsize != -1 then it is returning */
4939 srv_signing_trans_stop();
4942 END_PROFILE(SMBtrans2);
4943 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);