2 Unix SMB/CIFS implementation.
3 SMB transaction2 handling
4 Copyright (C) Jeremy Allison 1994-2003
5 Copyright (C) Stefan (metze) Metzmacher 2003
7 Extensively modified by Andrew Tridgell, 1995
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
27 extern enum protocol_types Protocol;
28 extern int smb_read_error;
29 extern int global_oplock_break;
30 extern uint32 global_client_caps;
31 extern struct current_user current_user;
33 #define get_file_size(sbuf) ((sbuf).st_size)
34 #define DIR_ENTRY_SAFETY_MARGIN 4096
36 /********************************************************************
37 Roundup a value to the nearest allocation roundup size boundary.
38 Only do this for Windows clients.
39 ********************************************************************/
41 SMB_BIG_UINT smb_roundup(connection_struct *conn, SMB_BIG_UINT val)
43 SMB_BIG_UINT rval = lp_allocation_roundup_size(SNUM(conn));
45 /* Only roundup for Windows clients. */
46 enum remote_arch_types ra_type = get_remote_arch();
47 if (rval && (ra_type != RA_SAMBA) && (ra_type != RA_CIFSFS)) {
48 val = SMB_ROUNDUP(val,rval);
53 /********************************************************************
54 Given a stat buffer return the allocated size on disk, taking into
56 ********************************************************************/
58 SMB_BIG_UINT get_allocation_size(connection_struct *conn, files_struct *fsp, SMB_STRUCT_STAT *sbuf)
62 if(S_ISDIR(sbuf->st_mode)) {
66 #if defined(HAVE_STAT_ST_BLOCKS) && defined(STAT_ST_BLOCKSIZE)
67 ret = (SMB_BIG_UINT)STAT_ST_BLOCKSIZE * (SMB_BIG_UINT)sbuf->st_blocks;
69 ret = (SMB_BIG_UINT)get_file_size(*sbuf);
72 if (fsp && fsp->initial_allocation_size)
73 ret = MAX(ret,fsp->initial_allocation_size);
75 return smb_roundup(conn, ret);
78 /****************************************************************************
79 Utility functions for dealing with extended attributes.
80 ****************************************************************************/
82 static const char *prohibited_ea_names[] = {
83 SAMBA_POSIX_INHERITANCE_EA_NAME,
84 SAMBA_XATTR_DOS_ATTRIB,
88 /****************************************************************************
89 Refuse to allow clients to overwrite our private xattrs.
90 ****************************************************************************/
92 static BOOL samba_private_attr_name(const char *unix_ea_name)
96 for (i = 0; prohibited_ea_names[i]; i++) {
97 if (strequal( prohibited_ea_names[i], unix_ea_name))
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);
240 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 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 one EA list entry from the buffer.
424 ****************************************************************************/
426 struct ea_list *read_ea_list_entry(TALLOC_CTX *ctx, const char *pdata, size_t data_size, size_t *pbytes_used)
428 struct ea_list *eal = TALLOC_ZERO_P(ctx, struct ea_list);
430 unsigned int namelen;
440 eal->ea.flags = CVAL(pdata,0);
441 namelen = CVAL(pdata,1);
442 val_len = SVAL(pdata,2);
444 if (4 + namelen + 1 + val_len > data_size) {
448 /* Ensure the name is null terminated. */
449 if (pdata[namelen + 4] != '\0') {
452 pull_ascii_talloc(ctx, &eal->ea.name, pdata + 4);
457 eal->ea.value = data_blob(NULL, (size_t)val_len + 1);
458 if (!eal->ea.value.data) {
462 memcpy(eal->ea.value.data, pdata + 4 + namelen + 1, val_len);
464 /* Ensure we're null terminated just in case we print the value. */
465 eal->ea.value.data[val_len] = '\0';
466 /* But don't count the null. */
467 eal->ea.value.length--;
470 *pbytes_used = 4 + namelen + 1 + val_len;
473 DEBUG(10,("read_ea_list_entry: read ea name %s\n", eal->ea.name));
474 dump_data(10, eal->ea.value.data, eal->ea.value.length);
479 /****************************************************************************
480 Read a list of EA names and data from an incoming data buffer. Create an ea_list with them.
481 ****************************************************************************/
483 static struct ea_list *read_ea_list(TALLOC_CTX *ctx, const char *pdata, size_t data_size)
485 struct ea_list *ea_list_head = NULL;
487 size_t bytes_used = 0;
489 while (offset < data_size) {
491 struct ea_list *eal = read_ea_list_entry(ctx, pdata + offset, data_size - offset, &bytes_used);
497 DLIST_ADD_END(ea_list_head, eal, tmp);
498 offset += bytes_used;
504 /****************************************************************************
505 Count the total EA size needed.
506 ****************************************************************************/
508 static size_t ea_list_size(struct ea_list *ealist)
511 struct ea_list *listp;
514 for (listp = ealist; listp; listp = listp->next) {
515 push_ascii_fstring(dos_ea_name, listp->ea.name);
516 ret += 4 + strlen(dos_ea_name) + 1 + listp->ea.value.length;
518 /* Add on 4 for total length. */
526 /****************************************************************************
527 Return a union of EA's from a file list and a list of names.
528 The TALLOC context for the two lists *MUST* be identical as we steal
529 memory from one list to add to another. JRA.
530 ****************************************************************************/
532 static struct ea_list *ea_list_union(struct ea_list *name_list, struct ea_list *file_list, size_t *total_ea_len)
534 struct ea_list *nlistp, *flistp;
536 for (nlistp = name_list; nlistp; nlistp = nlistp->next) {
537 for (flistp = file_list; flistp; flistp = flistp->next) {
538 if (strequal(nlistp->ea.name, flistp->ea.name)) {
544 /* Copy the data from this entry. */
545 nlistp->ea.flags = flistp->ea.flags;
546 nlistp->ea.value = flistp->ea.value;
549 nlistp->ea.flags = 0;
550 ZERO_STRUCT(nlistp->ea.value);
554 *total_ea_len = ea_list_size(name_list);
558 /****************************************************************************
559 Send the required number of replies back.
560 We assume all fields other than the data fields are
561 set correctly for the type of call.
562 HACK ! Always assumes smb_setup field is zero.
563 ****************************************************************************/
565 static int send_trans2_replies(char *outbuf,
572 /* As we are using a protocol > LANMAN1 then the max_send
573 variable must have been set in the sessetupX call.
574 This takes precedence over the max_xmit field in the
575 global struct. These different max_xmit variables should
576 be merged as this is now too confusing */
578 int data_to_send = datasize;
579 int params_to_send = paramsize;
583 int params_sent_thistime, data_sent_thistime, total_sent_thistime;
584 int alignment_offset = 1; /* JRA. This used to be 3. Set to 1 to make netmon parse ok. */
585 int data_alignment_offset = 0;
587 /* Initially set the wcnt area to be 10 - this is true for all trans2 replies */
589 set_message(outbuf,10,0,True);
591 /* If there genuinely are no parameters or data to send just send the empty packet */
593 if(params_to_send == 0 && data_to_send == 0) {
595 if (!send_smb(smbd_server_fd(),outbuf))
596 exit_server("send_trans2_replies: send_smb failed.");
600 /* When sending params and data ensure that both are nicely aligned */
601 /* Only do this alignment when there is also data to send - else
602 can cause NT redirector problems. */
604 if (((params_to_send % 4) != 0) && (data_to_send != 0))
605 data_alignment_offset = 4 - (params_to_send % 4);
607 /* Space is bufsize minus Netbios over TCP header minus SMB header */
608 /* The alignment_offset is to align the param bytes on an even byte
609 boundary. NT 4.0 Beta needs this to work correctly. */
611 useable_space = bufsize - ((smb_buf(outbuf)+ alignment_offset+data_alignment_offset) - outbuf);
613 /* useable_space can never be more than max_send minus the alignment offset. */
615 useable_space = MIN(useable_space, max_send - (alignment_offset+data_alignment_offset));
617 while (params_to_send || data_to_send) {
618 /* Calculate whether we will totally or partially fill this packet */
620 total_sent_thistime = params_to_send + data_to_send + alignment_offset + data_alignment_offset;
622 /* We can never send more than useable_space */
624 * Note that 'useable_space' does not include the alignment offsets,
625 * but we must include the alignment offsets in the calculation of
626 * the length of the data we send over the wire, as the alignment offsets
627 * are sent here. Fix from Marc_Jacobsen@hp.com.
630 total_sent_thistime = MIN(total_sent_thistime, useable_space+ alignment_offset + data_alignment_offset);
632 set_message(outbuf, 10, total_sent_thistime, True);
634 /* Set total params and data to be sent */
635 SSVAL(outbuf,smb_tprcnt,paramsize);
636 SSVAL(outbuf,smb_tdrcnt,datasize);
638 /* Calculate how many parameters and data we can fit into
639 * this packet. Parameters get precedence
642 params_sent_thistime = MIN(params_to_send,useable_space);
643 data_sent_thistime = useable_space - params_sent_thistime;
644 data_sent_thistime = MIN(data_sent_thistime,data_to_send);
646 SSVAL(outbuf,smb_prcnt, params_sent_thistime);
648 /* smb_proff is the offset from the start of the SMB header to the
649 parameter bytes, however the first 4 bytes of outbuf are
650 the Netbios over TCP header. Thus use smb_base() to subtract
651 them from the calculation */
653 SSVAL(outbuf,smb_proff,((smb_buf(outbuf)+alignment_offset) - smb_base(outbuf)));
655 if(params_sent_thistime == 0)
656 SSVAL(outbuf,smb_prdisp,0);
658 /* Absolute displacement of param bytes sent in this packet */
659 SSVAL(outbuf,smb_prdisp,pp - params);
661 SSVAL(outbuf,smb_drcnt, data_sent_thistime);
662 if(data_sent_thistime == 0) {
663 SSVAL(outbuf,smb_droff,0);
664 SSVAL(outbuf,smb_drdisp, 0);
666 /* The offset of the data bytes is the offset of the
667 parameter bytes plus the number of parameters being sent this time */
668 SSVAL(outbuf,smb_droff,((smb_buf(outbuf)+alignment_offset) -
669 smb_base(outbuf)) + params_sent_thistime + data_alignment_offset);
670 SSVAL(outbuf,smb_drdisp, pd - pdata);
673 /* Copy the param bytes into the packet */
675 if(params_sent_thistime)
676 memcpy((smb_buf(outbuf)+alignment_offset),pp,params_sent_thistime);
678 /* Copy in the data bytes */
679 if(data_sent_thistime)
680 memcpy(smb_buf(outbuf)+alignment_offset+params_sent_thistime+
681 data_alignment_offset,pd,data_sent_thistime);
683 DEBUG(9,("t2_rep: params_sent_thistime = %d, data_sent_thistime = %d, useable_space = %d\n",
684 params_sent_thistime, data_sent_thistime, useable_space));
685 DEBUG(9,("t2_rep: params_to_send = %d, data_to_send = %d, paramsize = %d, datasize = %d\n",
686 params_to_send, data_to_send, paramsize, datasize));
688 /* Send the packet */
690 if (!send_smb(smbd_server_fd(),outbuf))
691 exit_server("send_trans2_replies: send_smb failed.");
693 pp += params_sent_thistime;
694 pd += data_sent_thistime;
696 params_to_send -= params_sent_thistime;
697 data_to_send -= data_sent_thistime;
700 if(params_to_send < 0 || data_to_send < 0) {
701 DEBUG(0,("send_trans2_replies failed sanity check pts = %d, dts = %d\n!!!",
702 params_to_send, data_to_send));
710 /****************************************************************************
711 Reply to a TRANSACT2_OPEN.
712 ****************************************************************************/
714 static int call_trans2open(connection_struct *conn, char *inbuf, char *outbuf, int bufsize,
715 char **pparams, int total_params, char **ppdata, int total_data,
716 unsigned int max_data_bytes)
718 char *params = *pparams;
719 char *pdata = *ppdata;
724 BOOL return_additional_info;
733 int fmode=0,mtime=0,rmode;
735 SMB_STRUCT_STAT sbuf;
737 BOOL bad_path = False;
739 TALLOC_CTX *ctx = NULL;
740 struct ea_list *ea_list = NULL;
745 * Ensure we have enough parameters to perform the operation.
748 if (total_params < 29) {
749 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
752 flags = SVAL(params, 0);
753 open_mode = SVAL(params, 2);
754 open_attr = SVAL(params,6);
755 oplock_request = (flags & REQUEST_OPLOCK) ? EXCLUSIVE_OPLOCK : 0;
756 if (oplock_request) {
757 oplock_request |= (flags & REQUEST_BATCH_OPLOCK) ? BATCH_OPLOCK : 0;
761 return_additional_info = BITSETW(params,0);
762 open_sattr = SVAL(params, 4);
763 open_time = make_unix_date3(params+8);
765 open_ofun = SVAL(params,12);
766 open_size = IVAL(params,14);
770 return(ERROR_DOS(ERRSRV,ERRaccess));
772 srvstr_get_path(inbuf, fname, pname, sizeof(fname), -1, STR_TERMINATE, &status, False);
773 if (!NT_STATUS_IS_OK(status)) {
774 return ERROR_NT(status);
777 DEBUG(3,("call_trans2open %s mode=%d attr=%d ofun=%d size=%d\n",
778 fname,open_mode, open_attr, open_ofun, open_size));
780 /* XXXX we need to handle passed times, sattr and flags */
782 unix_convert(fname,conn,0,&bad_path,&sbuf);
784 return ERROR_NT(NT_STATUS_OBJECT_PATH_NOT_FOUND);
787 if (!check_name(fname,conn)) {
788 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRnoaccess);
791 /* Strange open mode mapping. */
792 if (open_ofun == 0) {
793 if (GET_OPEN_MODE(open_mode) == DOS_OPEN_EXEC) {
794 open_ofun = FILE_EXISTS_FAIL | FILE_CREATE_IF_NOT_EXIST;
798 /* Any data in this call is an EA list. */
799 if (total_data && !lp_ea_support(SNUM(conn))) {
800 return ERROR_NT(NT_STATUS_EAS_NOT_SUPPORTED);
804 if (total_data < 10) {
805 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
808 if (IVAL(pdata,0) > total_data) {
809 DEBUG(10,("call_trans2open: bad total data size (%u) > %u\n",
810 IVAL(pdata,0), (unsigned int)total_data));
811 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
814 ctx = talloc_init("TRANS2_OPEN_SET_EA");
816 return ERROR_NT(NT_STATUS_NO_MEMORY);
818 ea_list = read_ea_list(ctx, pdata + 4, total_data - 4);
821 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
825 fsp = open_file_shared(conn,fname,&sbuf,open_mode,open_ofun,(uint32)open_attr,
826 oplock_request, &rmode,&smb_action);
830 if (open_was_deferred(SVAL(inbuf,smb_mid))) {
831 /* We have re-scheduled this call. */
834 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRnoaccess);
837 size = get_file_size(sbuf);
838 fmode = dos_mode(conn,fname,&sbuf);
839 mtime = sbuf.st_mtime;
843 close_file(fsp,False);
844 return(ERROR_DOS(ERRDOS,ERRnoaccess));
847 if (total_data && smb_action == FILE_WAS_CREATED) {
848 status = set_ea(conn, fsp, fname, ea_list);
850 if (!NT_STATUS_IS_OK(status)) {
851 close_file(fsp,False);
852 return ERROR_NT(status);
856 /* Realloc the size of parameters and data we will return */
857 params = SMB_REALLOC(*pparams, 30);
858 if( params == NULL ) {
859 return ERROR_NT(NT_STATUS_NO_MEMORY);
863 SSVAL(params,0,fsp->fnum);
864 SSVAL(params,2,fmode);
865 put_dos_date2(params,4, mtime);
866 SIVAL(params,8, (uint32)size);
867 SSVAL(params,12,rmode);
868 SSVAL(params,16,0); /* Padding. */
870 if (oplock_request && lp_fake_oplocks(SNUM(conn))) {
871 smb_action |= EXTENDED_OPLOCK_GRANTED;
874 SSVAL(params,18,smb_action);
877 * WARNING - this may need to be changed if SMB_INO_T <> 4 bytes.
879 SIVAL(params,20,inode);
880 SSVAL(params,24,0); /* Padding. */
882 uint32 ea_size = estimate_ea_size(conn, fsp, fname);
883 SIVAL(params, 26, ea_size);
885 SIVAL(params, 26, 0);
888 /* Send the required number of replies */
889 send_trans2_replies(outbuf, bufsize, params, 30, *ppdata, 0);
894 /*********************************************************
895 Routine to check if a given string matches exactly.
896 as a special case a mask of "." does NOT match. That
897 is required for correct wildcard semantics
898 Case can be significant or not.
899 **********************************************************/
901 static BOOL exact_match(char *str,char *mask, BOOL case_sig)
903 if (mask[0] == '.' && mask[1] == 0)
906 return strcmp(str,mask)==0;
907 if (StrCaseCmp(str,mask) != 0) {
910 if (ms_has_wild(str)) {
916 /****************************************************************************
917 Return the filetype for UNIX extensions.
918 ****************************************************************************/
920 static uint32 unix_filetype(mode_t mode)
923 return UNIX_TYPE_FILE;
924 else if(S_ISDIR(mode))
925 return UNIX_TYPE_DIR;
927 else if(S_ISLNK(mode))
928 return UNIX_TYPE_SYMLINK;
931 else if(S_ISCHR(mode))
932 return UNIX_TYPE_CHARDEV;
935 else if(S_ISBLK(mode))
936 return UNIX_TYPE_BLKDEV;
939 else if(S_ISFIFO(mode))
940 return UNIX_TYPE_FIFO;
943 else if(S_ISSOCK(mode))
944 return UNIX_TYPE_SOCKET;
947 DEBUG(0,("unix_filetype: unknown filetype %u", (unsigned)mode));
948 return UNIX_TYPE_UNKNOWN;
951 /****************************************************************************
952 Map wire perms onto standard UNIX permissions. Obey share restrictions.
953 ****************************************************************************/
955 static mode_t unix_perms_from_wire( connection_struct *conn, SMB_STRUCT_STAT *pst, uint32 perms)
959 if (perms == SMB_MODE_NO_CHANGE)
962 ret |= ((perms & UNIX_X_OTH ) ? S_IXOTH : 0);
963 ret |= ((perms & UNIX_W_OTH ) ? S_IWOTH : 0);
964 ret |= ((perms & UNIX_R_OTH ) ? S_IROTH : 0);
965 ret |= ((perms & UNIX_X_GRP ) ? S_IXGRP : 0);
966 ret |= ((perms & UNIX_W_GRP ) ? S_IWGRP : 0);
967 ret |= ((perms & UNIX_R_GRP ) ? S_IRGRP : 0);
968 ret |= ((perms & UNIX_X_USR ) ? S_IXUSR : 0);
969 ret |= ((perms & UNIX_W_USR ) ? S_IWUSR : 0);
970 ret |= ((perms & UNIX_R_USR ) ? S_IRUSR : 0);
972 ret |= ((perms & UNIX_STICKY ) ? S_ISVTX : 0);
975 ret |= ((perms & UNIX_SET_GID ) ? S_ISGID : 0);
978 ret |= ((perms & UNIX_SET_UID ) ? S_ISUID : 0);
981 if (VALID_STAT(*pst) && S_ISDIR(pst->st_mode)) {
982 ret &= lp_dir_mask(SNUM(conn));
983 /* Add in force bits */
984 ret |= lp_force_dir_mode(SNUM(conn));
986 /* Apply mode mask */
987 ret &= lp_create_mask(SNUM(conn));
988 /* Add in force bits */
989 ret |= lp_force_create_mode(SNUM(conn));
995 /****************************************************************************
996 Get a level dependent lanman2 dir entry.
997 ****************************************************************************/
999 static BOOL get_lanman2_dir_entry(connection_struct *conn,
1000 void *inbuf, void *outbuf,
1001 char *path_mask,uint32 dirtype,int info_level,
1002 int requires_resume_key,
1003 BOOL dont_descend,char **ppdata,
1004 char *base_data, int space_remaining,
1005 BOOL *out_of_space, BOOL *got_exact_match,
1006 int *last_entry_off, struct ea_list *name_list, TALLOC_CTX *ea_ctx)
1010 SMB_STRUCT_STAT sbuf;
1014 char *p, *q, *pdata = *ppdata;
1018 SMB_OFF_T file_size = 0;
1019 SMB_BIG_UINT allocation_size = 0;
1021 time_t mdate=0, adate=0, cdate=0;
1023 char *last_entry_ptr;
1025 uint32 nt_extmode; /* Used for NT connections instead of mode */
1026 BOOL needslash = ( conn->dirpath[strlen(conn->dirpath) -1] != '/');
1027 BOOL check_mangled_names = lp_manglednames(SNUM(conn));
1030 *out_of_space = False;
1031 *got_exact_match = False;
1036 p = strrchr_m(path_mask,'/');
1039 pstrcpy(mask,"*.*");
1043 pstrcpy(mask, path_mask);
1048 /* Needed if we run out of space */
1049 long curr_dirpos = prev_dirpos = dptr_TellDir(conn->dirptr);
1050 dname = dptr_ReadDirName(conn->dirptr,&curr_dirpos,&sbuf);
1053 * Due to bugs in NT client redirectors we are not using
1054 * resume keys any more - set them to zero.
1055 * Check out the related comments in findfirst/findnext.
1061 DEBUG(8,("get_lanman2_dir_entry:readdir on dirptr 0x%lx now at offset %ld\n",
1062 (long)conn->dirptr,curr_dirpos));
1067 pstrcpy(fname,dname);
1069 if(!(got_match = *got_exact_match = exact_match(fname, mask, conn->case_sensitive)))
1070 got_match = mask_match(fname, mask, conn->case_sensitive);
1072 if(!got_match && check_mangled_names && !mangle_is_8_3(fname, False, SNUM(conn))) {
1075 * It turns out that NT matches wildcards against
1076 * both long *and* short names. This may explain some
1077 * of the wildcard wierdness from old DOS clients
1078 * that some people have been seeing.... JRA.
1082 pstrcpy( newname, fname);
1083 mangle_map( newname, True, False, SNUM(conn));
1084 if(!(got_match = *got_exact_match = exact_match(newname, mask, conn->case_sensitive)))
1085 got_match = mask_match(newname, mask, conn->case_sensitive);
1089 BOOL isdots = (strequal(fname,"..") || strequal(fname,"."));
1090 if (dont_descend && !isdots)
1093 pstrcpy(pathreal,conn->dirpath);
1095 pstrcat(pathreal,"/");
1096 pstrcat(pathreal,dname);
1098 if (INFO_LEVEL_IS_UNIX(info_level)) {
1099 if (SMB_VFS_LSTAT(conn,pathreal,&sbuf) != 0) {
1100 DEBUG(5,("get_lanman2_dir_entry:Couldn't lstat [%s] (%s)\n",
1101 pathreal,strerror(errno)));
1104 } else if (!VALID_STAT(sbuf) && SMB_VFS_STAT(conn,pathreal,&sbuf) != 0) {
1106 /* Needed to show the msdfs symlinks as
1109 if(lp_host_msdfs() &&
1110 lp_msdfs_root(SNUM(conn)) &&
1111 is_msdfs_link(conn, pathreal, NULL, NULL,
1114 DEBUG(5,("get_lanman2_dir_entry: Masquerading msdfs link %s as a directory\n", pathreal));
1115 sbuf.st_mode = (sbuf.st_mode & 0xFFF) | S_IFDIR;
1119 DEBUG(5,("get_lanman2_dir_entry:Couldn't stat [%s] (%s)\n",
1120 pathreal,strerror(errno)));
1125 mode = dos_mode(conn,pathreal,&sbuf);
1127 if (!dir_check_ftype(conn,mode,dirtype)) {
1128 DEBUG(5,("[%s] attribs didn't match %x\n",fname,dirtype));
1132 file_size = get_file_size(sbuf);
1133 allocation_size = get_allocation_size(conn,NULL,&sbuf);
1134 mdate = sbuf.st_mtime;
1135 adate = sbuf.st_atime;
1136 cdate = get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(conn)));
1138 if (lp_dos_filetime_resolution(SNUM(conn))) {
1145 /* This is necessary, as otherwise the
1146 * desktop.ini file in this folder is
1148 mode |= (lp_profile_acls(SNUM(conn)) ? aRONLY : 0);
1152 DEBUG(5,("get_lanman2_dir_entry found %s fname=%s\n",pathreal,fname));
1158 mangle_map(fname,False,True,SNUM(conn));
1163 nt_extmode = mode ? mode : FILE_ATTRIBUTE_NORMAL;
1165 switch (info_level) {
1166 case SMB_FIND_INFO_STANDARD:
1167 DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_INFO_STANDARD\n"));
1168 if(requires_resume_key) {
1172 put_dos_date2(p,0,cdate);
1173 put_dos_date2(p,4,adate);
1174 put_dos_date2(p,8,mdate);
1175 SIVAL(p,12,(uint32)file_size);
1176 SIVAL(p,16,(uint32)allocation_size);
1180 p += align_string(outbuf, p, 0);
1181 len = srvstr_push(outbuf, p, fname, -1, STR_TERMINATE);
1182 if (SVAL(outbuf, smb_flg2) & FLAGS2_UNICODE_STRINGS) {
1184 SCVAL(nameptr, -1, len - 2);
1186 SCVAL(nameptr, -1, 0);
1190 SCVAL(nameptr, -1, len - 1);
1192 SCVAL(nameptr, -1, 0);
1198 case SMB_FIND_EA_SIZE:
1199 DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_EA_SIZE\n"));
1200 if(requires_resume_key) {
1204 put_dos_date2(p,0,cdate);
1205 put_dos_date2(p,4,adate);
1206 put_dos_date2(p,8,mdate);
1207 SIVAL(p,12,(uint32)file_size);
1208 SIVAL(p,16,(uint32)allocation_size);
1211 unsigned int ea_size = estimate_ea_size(conn, NULL, pathreal);
1212 SIVAL(p,22,ea_size); /* Extended attributes */
1216 len = srvstr_push(outbuf, p, fname, -1, STR_TERMINATE | STR_NOALIGN);
1217 if (SVAL(outbuf, smb_flg2) & FLAGS2_UNICODE_STRINGS) {
1230 SCVAL(nameptr,0,len);
1232 SCVAL(p,0,0); p += 1; /* Extra zero byte ? - why.. */
1235 case SMB_FIND_EA_LIST:
1237 struct ea_list *file_list = NULL;
1240 DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_EA_LIST\n"));
1244 if(requires_resume_key) {
1248 put_dos_date2(p,0,cdate);
1249 put_dos_date2(p,4,adate);
1250 put_dos_date2(p,8,mdate);
1251 SIVAL(p,12,(uint32)file_size);
1252 SIVAL(p,16,(uint32)allocation_size);
1254 p += 22; /* p now points to the EA area. */
1256 file_list = get_ea_list_from_file(ea_ctx, conn, NULL, pathreal, &ea_len);
1257 name_list = ea_list_union(name_list, file_list, &ea_len);
1259 /* We need to determine if this entry will fit in the space available. */
1260 /* Max string size is 255 bytes. */
1261 if (PTR_DIFF(p + 255 + ea_len,pdata) > space_remaining) {
1262 /* Move the dirptr back to prev_dirpos */
1263 dptr_SeekDir(conn->dirptr, prev_dirpos);
1264 *out_of_space = True;
1265 DEBUG(9,("get_lanman2_dir_entry: out of space\n"));
1266 return False; /* Not finished - just out of space */
1269 /* Push the ea_data followed by the name. */
1270 p += fill_ea_buffer(ea_ctx, p, space_remaining, conn, name_list);
1272 len = srvstr_push(outbuf, p + 1, fname, -1, STR_TERMINATE | STR_NOALIGN);
1273 if (SVAL(outbuf, smb_flg2) & FLAGS2_UNICODE_STRINGS) {
1286 SCVAL(nameptr,0,len);
1288 SCVAL(p,0,0); p += 1; /* Extra zero byte ? - why.. */
1292 case SMB_FIND_FILE_BOTH_DIRECTORY_INFO:
1293 DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_FILE_BOTH_DIRECTORY_INFO\n"));
1294 was_8_3 = mangle_is_8_3(fname, True, SNUM(conn));
1296 SIVAL(p,0,reskey); p += 4;
1297 put_long_date(p,cdate); p += 8;
1298 put_long_date(p,adate); p += 8;
1299 put_long_date(p,mdate); p += 8;
1300 put_long_date(p,mdate); p += 8;
1301 SOFF_T(p,0,file_size); p += 8;
1302 SOFF_T(p,0,allocation_size); p += 8;
1303 SIVAL(p,0,nt_extmode); p += 4;
1304 q = p; p += 4; /* q is placeholder for name length. */
1306 unsigned int ea_size = estimate_ea_size(conn, NULL, pathreal);
1307 SIVAL(p,0,ea_size); /* Extended attributes */
1310 /* Clear the short name buffer. This is
1311 * IMPORTANT as not doing so will trigger
1312 * a Win2k client bug. JRA.
1314 if (!was_8_3 && check_mangled_names) {
1315 pstring mangled_name;
1316 pstrcpy(mangled_name, fname);
1317 mangle_map(mangled_name,True,True,SNUM(conn));
1318 mangled_name[12] = 0;
1319 len = srvstr_push(outbuf, p+2, mangled_name, 24, STR_UPPER|STR_UNICODE);
1321 memset(p + 2 + len,'\0',24 - len);
1328 len = srvstr_push(outbuf, p, fname, -1, STR_TERMINATE_ASCII);
1331 SIVAL(p,0,0); /* Ensure any padding is null. */
1332 len = PTR_DIFF(p, pdata);
1333 len = (len + 3) & ~3;
1338 case SMB_FIND_FILE_DIRECTORY_INFO:
1339 DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_FILE_DIRECTORY_INFO\n"));
1341 SIVAL(p,0,reskey); p += 4;
1342 put_long_date(p,cdate); p += 8;
1343 put_long_date(p,adate); p += 8;
1344 put_long_date(p,mdate); p += 8;
1345 put_long_date(p,mdate); p += 8;
1346 SOFF_T(p,0,file_size); p += 8;
1347 SOFF_T(p,0,allocation_size); p += 8;
1348 SIVAL(p,0,nt_extmode); p += 4;
1349 len = srvstr_push(outbuf, p + 4, fname, -1, STR_TERMINATE_ASCII);
1352 SIVAL(p,0,0); /* Ensure any padding is null. */
1353 len = PTR_DIFF(p, pdata);
1354 len = (len + 3) & ~3;
1359 case SMB_FIND_FILE_FULL_DIRECTORY_INFO:
1360 DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_FILE_FULL_DIRECTORY_INFO\n"));
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 len = srvstr_push(outbuf, p, fname, -1, STR_TERMINATE_ASCII);
1380 SIVAL(p,0,0); /* Ensure any padding is null. */
1381 len = PTR_DIFF(p, pdata);
1382 len = (len + 3) & ~3;
1387 case SMB_FIND_FILE_NAMES_INFO:
1388 DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_FILE_NAMES_INFO\n"));
1390 SIVAL(p,0,reskey); p += 4;
1392 /* this must *not* be null terminated or w2k gets in a loop trying to set an
1393 acl on a dir (tridge) */
1394 len = srvstr_push(outbuf, p, fname, -1, STR_TERMINATE_ASCII);
1397 SIVAL(p,0,0); /* Ensure any padding is null. */
1398 len = PTR_DIFF(p, pdata);
1399 len = (len + 3) & ~3;
1404 case SMB_FIND_ID_FULL_DIRECTORY_INFO:
1405 DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_ID_FULL_DIRECTORY_INFO\n"));
1407 SIVAL(p,0,reskey); p += 4;
1408 put_long_date(p,cdate); p += 8;
1409 put_long_date(p,adate); p += 8;
1410 put_long_date(p,mdate); p += 8;
1411 put_long_date(p,mdate); p += 8;
1412 SOFF_T(p,0,file_size); p += 8;
1413 SOFF_T(p,0,allocation_size); p += 8;
1414 SIVAL(p,0,nt_extmode); p += 4;
1415 q = p; p += 4; /* q is placeholder for name length. */
1417 unsigned int ea_size = estimate_ea_size(conn, NULL, pathreal);
1418 SIVAL(p,0,ea_size); /* Extended attributes */
1421 SIVAL(p,0,0); p += 4; /* Unknown - reserved ? */
1422 SIVAL(p,0,sbuf.st_dev); p += 4;
1423 SIVAL(p,0,sbuf.st_ino); p += 4;
1424 len = srvstr_push(outbuf, p, fname, -1, STR_TERMINATE_ASCII);
1427 SIVAL(p,0,0); /* Ensure any padding is null. */
1428 len = PTR_DIFF(p, pdata);
1429 len = (len + 3) & ~3;
1434 case SMB_FIND_ID_BOTH_DIRECTORY_INFO:
1435 DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_ID_BOTH_DIRECTORY_INFO\n"));
1436 was_8_3 = mangle_is_8_3(fname, True, SNUM(conn));
1438 SIVAL(p,0,reskey); p += 4;
1439 put_long_date(p,cdate); p += 8;
1440 put_long_date(p,adate); p += 8;
1441 put_long_date(p,mdate); p += 8;
1442 put_long_date(p,mdate); p += 8;
1443 SOFF_T(p,0,file_size); p += 8;
1444 SOFF_T(p,0,allocation_size); p += 8;
1445 SIVAL(p,0,nt_extmode); p += 4;
1446 q = p; p += 4; /* q is placeholder for name length */
1448 unsigned int ea_size = estimate_ea_size(conn, NULL, pathreal);
1449 SIVAL(p,0,ea_size); /* Extended attributes */
1452 /* Clear the short name buffer. This is
1453 * IMPORTANT as not doing so will trigger
1454 * a Win2k client bug. JRA.
1456 if (!was_8_3 && check_mangled_names) {
1457 pstring mangled_name;
1458 pstrcpy(mangled_name, fname);
1459 mangle_map(mangled_name,True,True,SNUM(conn));
1460 mangled_name[12] = 0;
1461 len = srvstr_push(outbuf, p+2, mangled_name, 24, STR_UPPER|STR_UNICODE);
1464 memset(p + 2 + len,'\0',24 - len);
1471 SSVAL(p,0,0); p += 2; /* Reserved ? */
1472 SIVAL(p,0,sbuf.st_dev); p += 4;
1473 SIVAL(p,0,sbuf.st_ino); p += 4;
1474 len = srvstr_push(outbuf, p, fname, -1, STR_TERMINATE_ASCII);
1477 SIVAL(p,0,0); /* Ensure any padding is null. */
1478 len = PTR_DIFF(p, pdata);
1479 len = (len + 3) & ~3;
1484 /* CIFS UNIX Extension. */
1486 case SMB_FIND_FILE_UNIX:
1487 DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_FILE_UNIX\n"));
1489 SIVAL(p,0,reskey); p+= 4; /* Used for continuing search. */
1491 /* Begin of SMB_QUERY_FILE_UNIX_BASIC */
1492 SOFF_T(p,0,get_file_size(sbuf)); /* File size 64 Bit */
1495 SOFF_T(p,0,get_allocation_size(conn,NULL,&sbuf)); /* Number of bytes used on disk - 64 Bit */
1498 put_long_date(p,sbuf.st_ctime); /* Inode change Time 64 Bit */
1499 put_long_date(p+8,sbuf.st_atime); /* Last access time 64 Bit */
1500 put_long_date(p+16,sbuf.st_mtime); /* Last modification time 64 Bit */
1503 SIVAL(p,0,sbuf.st_uid); /* user id for the owner */
1507 SIVAL(p,0,sbuf.st_gid); /* group id of owner */
1511 SIVAL(p,0,unix_filetype(sbuf.st_mode));
1514 SIVAL(p,0,unix_dev_major(sbuf.st_rdev)); /* Major device number if type is device */
1518 SIVAL(p,0,unix_dev_minor(sbuf.st_rdev)); /* Minor device number if type is device */
1522 SINO_T(p,0,(SMB_INO_T)sbuf.st_ino); /* inode number */
1525 SIVAL(p,0, unix_perms_to_wire(sbuf.st_mode)); /* Standard UNIX file permissions */
1529 SIVAL(p,0,sbuf.st_nlink); /* number of hard links */
1533 len = srvstr_push(outbuf, p, fname, -1, STR_TERMINATE);
1535 SIVAL(p,0,0); /* Ensure any padding is null. */
1537 len = PTR_DIFF(p, pdata);
1538 len = (len + 3) & ~3;
1539 SIVAL(pdata,0,len); /* Offset from this structure to the beginning of the next one */
1541 /* End of SMB_QUERY_FILE_UNIX_BASIC */
1550 if (PTR_DIFF(p,pdata) > space_remaining) {
1551 /* Move the dirptr back to prev_dirpos */
1552 dptr_SeekDir(conn->dirptr, prev_dirpos);
1553 *out_of_space = True;
1554 DEBUG(9,("get_lanman2_dir_entry: out of space\n"));
1555 return False; /* Not finished - just out of space */
1558 /* Setup the last entry pointer, as an offset from base_data */
1559 *last_entry_off = PTR_DIFF(last_entry_ptr,base_data);
1560 /* Advance the data pointer to the next slot */
1566 /****************************************************************************
1567 Reply to a TRANS2_FINDFIRST.
1568 ****************************************************************************/
1570 static int call_trans2findfirst(connection_struct *conn, char *inbuf, char *outbuf, int bufsize,
1571 char **pparams, int total_params, char **ppdata, int total_data,
1572 unsigned int max_data_bytes)
1574 /* We must be careful here that we don't return more than the
1575 allowed number of data bytes. If this means returning fewer than
1576 maxentries then so be it. We assume that the redirector has
1577 enough room for the fixed number of parameter bytes it has
1579 char *params = *pparams;
1580 char *pdata = *ppdata;
1581 uint32 dirtype = SVAL(params,0);
1582 int maxentries = SVAL(params,2);
1583 uint16 findfirst_flags = SVAL(params,4);
1584 BOOL close_after_first = (findfirst_flags & FLAG_TRANS2_FIND_CLOSE);
1585 BOOL close_if_end = (findfirst_flags & FLAG_TRANS2_FIND_CLOSE_IF_END);
1586 BOOL requires_resume_key = (findfirst_flags & FLAG_TRANS2_FIND_REQUIRE_RESUME);
1587 int info_level = SVAL(params,6);
1591 int last_entry_off=0;
1595 BOOL finished = False;
1596 BOOL dont_descend = False;
1597 BOOL out_of_space = False;
1598 int space_remaining;
1599 BOOL bad_path = False;
1600 SMB_STRUCT_STAT sbuf;
1601 TALLOC_CTX *ea_ctx = NULL;
1602 struct ea_list *ea_list = NULL;
1603 NTSTATUS ntstatus = NT_STATUS_OK;
1605 if (total_params < 12) {
1606 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
1609 *directory = *mask = 0;
1611 DEBUG(3,("call_trans2findfirst: dirtype = %x, maxentries = %d, close_after_first=%d, \
1612 close_if_end = %d requires_resume_key = %d level = 0x%x, max_data_bytes = %d\n",
1613 (unsigned int)dirtype, maxentries, close_after_first, close_if_end, requires_resume_key,
1614 info_level, max_data_bytes));
1617 /* W2K3 seems to treat zero as 1. */
1621 switch (info_level) {
1622 case SMB_FIND_INFO_STANDARD:
1623 case SMB_FIND_EA_SIZE:
1624 case SMB_FIND_EA_LIST:
1625 case SMB_FIND_FILE_DIRECTORY_INFO:
1626 case SMB_FIND_FILE_FULL_DIRECTORY_INFO:
1627 case SMB_FIND_FILE_NAMES_INFO:
1628 case SMB_FIND_FILE_BOTH_DIRECTORY_INFO:
1629 case SMB_FIND_ID_FULL_DIRECTORY_INFO:
1630 case SMB_FIND_ID_BOTH_DIRECTORY_INFO:
1632 case SMB_FIND_FILE_UNIX:
1633 if (!lp_unix_extensions())
1634 return(ERROR_DOS(ERRDOS,ERRunknownlevel));
1637 return(ERROR_DOS(ERRDOS,ERRunknownlevel));
1640 srvstr_get_path(inbuf, directory, params+12, sizeof(directory), -1, STR_TERMINATE, &ntstatus, True);
1641 if (!NT_STATUS_IS_OK(ntstatus)) {
1642 return ERROR_NT(ntstatus);
1645 RESOLVE_DFSPATH_WCARD(directory, conn, inbuf, outbuf);
1647 unix_convert(directory,conn,0,&bad_path,&sbuf);
1649 return ERROR_NT(NT_STATUS_OBJECT_PATH_NOT_FOUND);
1651 if(!check_name(directory,conn)) {
1652 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRbadpath);
1655 p = strrchr_m(directory,'/');
1657 /* Windows and OS/2 systems treat search on the root '\' as if it were '\*' */
1658 if((directory[0] == '.') && (directory[1] == '\0'))
1661 pstrcpy(mask,directory);
1662 pstrcpy(directory,"./");
1668 DEBUG(5,("dir=%s, mask = %s\n",directory, mask));
1670 if (info_level == SMB_FIND_EA_LIST) {
1673 if (total_data < 4) {
1674 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
1677 ea_size = IVAL(pdata,0);
1678 if (ea_size != total_data) {
1679 DEBUG(4,("call_trans2findfirst: Rejecting EA request with incorrect \
1680 total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pdata,0) ));
1681 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
1684 if (!lp_ea_support(SNUM(conn))) {
1685 return ERROR_DOS(ERRDOS,ERReasnotsupported);
1688 if ((ea_ctx = talloc_init("findnext_ea_list")) == NULL) {
1689 return ERROR_NT(NT_STATUS_NO_MEMORY);
1692 /* Pull out the list of names. */
1693 ea_list = read_ea_name_list(ea_ctx, pdata + 4, ea_size - 4);
1695 talloc_destroy(ea_ctx);
1696 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
1700 pdata = SMB_REALLOC(*ppdata, max_data_bytes + DIR_ENTRY_SAFETY_MARGIN);
1701 if( pdata == NULL ) {
1702 talloc_destroy(ea_ctx);
1703 return ERROR_NT(NT_STATUS_NO_MEMORY);
1708 /* Realloc the params space */
1709 params = SMB_REALLOC(*pparams, 10);
1710 if (params == NULL) {
1711 talloc_destroy(ea_ctx);
1712 return ERROR_NT(NT_STATUS_NO_MEMORY);
1716 /* Save the wildcard match and attribs we are using on this directory -
1717 needed as lanman2 assumes these are being saved between calls */
1719 dptr_num = dptr_create(conn,directory, False, True ,SVAL(inbuf,smb_pid), mask, dirtype);
1721 talloc_destroy(ea_ctx);
1722 return(UNIXERROR(ERRDOS,ERRbadfile));
1725 DEBUG(4,("dptr_num is %d, wcard = %s, attr = %d\n",dptr_num, mask, dirtype));
1727 /* We don't need to check for VOL here as this is returned by
1728 a different TRANS2 call. */
1730 DEBUG(8,("dirpath=<%s> dontdescend=<%s>\n", conn->dirpath,lp_dontdescend(SNUM(conn))));
1731 if (in_list(conn->dirpath,lp_dontdescend(SNUM(conn)),conn->case_sensitive))
1732 dont_descend = True;
1735 space_remaining = max_data_bytes;
1736 out_of_space = False;
1738 for (i=0;(i<maxentries) && !finished && !out_of_space;i++) {
1739 BOOL got_exact_match = False;
1741 /* this is a heuristic to avoid seeking the dirptr except when
1742 absolutely necessary. It allows for a filename of about 40 chars */
1743 if (space_remaining < DIRLEN_GUESS && numentries > 0) {
1744 out_of_space = True;
1747 finished = !get_lanman2_dir_entry(conn,
1749 mask,dirtype,info_level,
1750 requires_resume_key,dont_descend,
1751 &p,pdata,space_remaining, &out_of_space, &got_exact_match,
1752 &last_entry_off, ea_list, ea_ctx);
1755 if (finished && out_of_space)
1758 if (!finished && !out_of_space)
1762 * As an optimisation if we know we aren't looking
1763 * for a wildcard name (ie. the name matches the wildcard exactly)
1764 * then we can finish on any (first) match.
1765 * This speeds up large directory searches. JRA.
1771 space_remaining = max_data_bytes - PTR_DIFF(p,pdata);
1774 talloc_destroy(ea_ctx);
1776 /* Check if we can close the dirptr */
1777 if(close_after_first || (finished && close_if_end)) {
1778 DEBUG(5,("call_trans2findfirst - (2) closing dptr_num %d\n", dptr_num));
1779 dptr_close(&dptr_num);
1783 * If there are no matching entries we must return ERRDOS/ERRbadfile -
1784 * from observation of NT. NB. This changes to ERRDOS,ERRnofiles if
1785 * the protocol level is less than NT1. Tested with smbclient. JRA.
1786 * This should fix the OS/2 client bug #2335.
1789 if(numentries == 0) {
1790 dptr_close(&dptr_num);
1791 if (Protocol < PROTOCOL_NT1) {
1792 return ERROR_DOS(ERRDOS,ERRnofiles);
1794 return ERROR_BOTH(NT_STATUS_NO_SUCH_FILE,ERRDOS,ERRbadfile);
1798 /* At this point pdata points to numentries directory entries. */
1800 /* Set up the return parameter block */
1801 SSVAL(params,0,dptr_num);
1802 SSVAL(params,2,numentries);
1803 SSVAL(params,4,finished);
1804 SSVAL(params,6,0); /* Never an EA error */
1805 SSVAL(params,8,last_entry_off);
1807 send_trans2_replies( outbuf, bufsize, params, 10, pdata, PTR_DIFF(p,pdata));
1809 if ((! *directory) && dptr_path(dptr_num))
1810 slprintf(directory,sizeof(directory)-1, "(%s)",dptr_path(dptr_num));
1812 DEBUG( 4, ( "%s mask=%s directory=%s dirtype=%d numentries=%d\n",
1813 smb_fn_name(CVAL(inbuf,smb_com)),
1814 mask, directory, dirtype, numentries ) );
1817 * Force a name mangle here to ensure that the
1818 * mask as an 8.3 name is top of the mangled cache.
1819 * The reasons for this are subtle. Don't remove
1820 * this code unless you know what you are doing
1821 * (see PR#13758). JRA.
1824 if(!mangle_is_8_3_wildcards( mask, False, SNUM(conn)))
1825 mangle_map(mask, True, True, SNUM(conn));
1830 /****************************************************************************
1831 Reply to a TRANS2_FINDNEXT.
1832 ****************************************************************************/
1834 static int call_trans2findnext(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize,
1835 char **pparams, int total_params, char **ppdata, int total_data,
1836 unsigned int max_data_bytes)
1838 /* We must be careful here that we don't return more than the
1839 allowed number of data bytes. If this means returning fewer than
1840 maxentries then so be it. We assume that the redirector has
1841 enough room for the fixed number of parameter bytes it has
1843 char *params = *pparams;
1844 char *pdata = *ppdata;
1845 int dptr_num = SVAL(params,0);
1846 int maxentries = SVAL(params,2);
1847 uint16 info_level = SVAL(params,4);
1848 uint32 resume_key = IVAL(params,6);
1849 uint16 findnext_flags = SVAL(params,10);
1850 BOOL close_after_request = (findnext_flags & FLAG_TRANS2_FIND_CLOSE);
1851 BOOL close_if_end = (findnext_flags & FLAG_TRANS2_FIND_CLOSE_IF_END);
1852 BOOL requires_resume_key = (findnext_flags & FLAG_TRANS2_FIND_REQUIRE_RESUME);
1853 BOOL continue_bit = (findnext_flags & FLAG_TRANS2_FIND_CONTINUE);
1854 pstring resume_name;
1860 int i, last_entry_off=0;
1861 BOOL finished = False;
1862 BOOL dont_descend = False;
1863 BOOL out_of_space = False;
1864 int space_remaining;
1865 TALLOC_CTX *ea_ctx = NULL;
1866 struct ea_list *ea_list = NULL;
1867 NTSTATUS ntstatus = NT_STATUS_OK;
1869 if (total_params < 12) {
1870 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
1873 *mask = *directory = *resume_name = 0;
1875 srvstr_get_path(inbuf, resume_name, params+12, sizeof(resume_name), -1, STR_TERMINATE, &ntstatus, True);
1876 if (!NT_STATUS_IS_OK(ntstatus)) {
1877 /* Win9x or OS/2 can send a resume name of ".." or ".". This will cause the parser to
1878 complain (it thinks we're asking for the directory above the shared
1879 path or an invalid name). Catch this as the resume name is only compared, never used in
1880 a file access. JRA. */
1881 if (NT_STATUS_EQUAL(ntstatus,NT_STATUS_OBJECT_PATH_SYNTAX_BAD)) {
1882 pstrcpy(resume_name, "..");
1883 } else if (NT_STATUS_EQUAL(ntstatus,NT_STATUS_OBJECT_NAME_INVALID)) {
1884 pstrcpy(resume_name, ".");
1886 return ERROR_NT(ntstatus);
1890 DEBUG(3,("call_trans2findnext: dirhandle = %d, max_data_bytes = %d, maxentries = %d, \
1891 close_after_request=%d, close_if_end = %d requires_resume_key = %d \
1892 resume_key = %d resume name = %s continue=%d level = %d\n",
1893 dptr_num, max_data_bytes, maxentries, close_after_request, close_if_end,
1894 requires_resume_key, resume_key, resume_name, continue_bit, info_level));
1897 /* W2K3 seems to treat zero as 1. */
1901 switch (info_level) {
1902 case SMB_FIND_INFO_STANDARD:
1903 case SMB_FIND_EA_SIZE:
1904 case SMB_FIND_EA_LIST:
1905 case SMB_FIND_FILE_DIRECTORY_INFO:
1906 case SMB_FIND_FILE_FULL_DIRECTORY_INFO:
1907 case SMB_FIND_FILE_NAMES_INFO:
1908 case SMB_FIND_FILE_BOTH_DIRECTORY_INFO:
1910 case SMB_FIND_FILE_UNIX:
1911 if (!lp_unix_extensions())
1912 return(ERROR_DOS(ERRDOS,ERRunknownlevel));
1915 return ERROR_DOS(ERRDOS,ERRunknownlevel);
1918 if (info_level == SMB_FIND_EA_LIST) {
1921 if (total_data < 4) {
1922 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
1925 ea_size = IVAL(pdata,0);
1926 if (ea_size != total_data) {
1927 DEBUG(4,("call_trans2findnext: Rejecting EA request with incorrect \
1928 total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pdata,0) ));
1929 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
1932 if (!lp_ea_support(SNUM(conn))) {
1933 return ERROR_DOS(ERRDOS,ERReasnotsupported);
1936 if ((ea_ctx = talloc_init("findnext_ea_list")) == NULL) {
1937 return ERROR_NT(NT_STATUS_NO_MEMORY);
1940 /* Pull out the list of names. */
1941 ea_list = read_ea_name_list(ea_ctx, pdata + 4, ea_size - 4);
1943 talloc_destroy(ea_ctx);
1944 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
1948 pdata = SMB_REALLOC( *ppdata, max_data_bytes + DIR_ENTRY_SAFETY_MARGIN);
1950 talloc_destroy(ea_ctx);
1951 return ERROR_NT(NT_STATUS_NO_MEMORY);
1956 /* Realloc the params space */
1957 params = SMB_REALLOC(*pparams, 6*SIZEOFWORD);
1958 if( params == NULL ) {
1959 talloc_destroy(ea_ctx);
1960 return ERROR_NT(NT_STATUS_NO_MEMORY);
1965 /* Check that the dptr is valid */
1966 if(!(conn->dirptr = dptr_fetch_lanman2(dptr_num))) {
1967 talloc_destroy(ea_ctx);
1968 return ERROR_DOS(ERRDOS,ERRnofiles);
1971 string_set(&conn->dirpath,dptr_path(dptr_num));
1973 /* Get the wildcard mask from the dptr */
1974 if((p = dptr_wcard(dptr_num))== NULL) {
1975 DEBUG(2,("dptr_num %d has no wildcard\n", dptr_num));
1976 talloc_destroy(ea_ctx);
1977 return ERROR_DOS(ERRDOS,ERRnofiles);
1981 pstrcpy(directory,conn->dirpath);
1983 /* Get the attr mask from the dptr */
1984 dirtype = dptr_attr(dptr_num);
1986 DEBUG(3,("dptr_num is %d, mask = %s, attr = %x, dirptr=(0x%lX,%ld)\n",
1987 dptr_num, mask, dirtype,
1989 dptr_TellDir(conn->dirptr)));
1991 /* We don't need to check for VOL here as this is returned by
1992 a different TRANS2 call. */
1994 DEBUG(8,("dirpath=<%s> dontdescend=<%s>\n",conn->dirpath,lp_dontdescend(SNUM(conn))));
1995 if (in_list(conn->dirpath,lp_dontdescend(SNUM(conn)),conn->case_sensitive))
1996 dont_descend = True;
1999 space_remaining = max_data_bytes;
2000 out_of_space = False;
2003 * Seek to the correct position. We no longer use the resume key but
2004 * depend on the last file name instead.
2007 if(*resume_name && !continue_bit) {
2010 long current_pos = 0;
2012 * Remember, mangle_map is called by
2013 * get_lanman2_dir_entry(), so the resume name
2014 * could be mangled. Ensure we check the unmangled name.
2017 if (mangle_is_mangled(resume_name, SNUM(conn))) {
2018 mangle_check_cache(resume_name, sizeof(resume_name)-1, SNUM(conn));
2022 * Fix for NT redirector problem triggered by resume key indexes
2023 * changing between directory scans. We now return a resume key of 0
2024 * and instead look for the filename to continue from (also given
2025 * to us by NT/95/smbfs/smbclient). If no other scans have been done between the
2026 * findfirst/findnext (as is usual) then the directory pointer
2027 * should already be at the correct place.
2030 finished = !dptr_SearchDir(conn->dirptr, resume_name, ¤t_pos, &st);
2031 } /* end if resume_name && !continue_bit */
2033 for (i=0;(i<(int)maxentries) && !finished && !out_of_space ;i++) {
2034 BOOL got_exact_match = False;
2036 /* this is a heuristic to avoid seeking the dirptr except when
2037 absolutely necessary. It allows for a filename of about 40 chars */
2038 if (space_remaining < DIRLEN_GUESS && numentries > 0) {
2039 out_of_space = True;
2042 finished = !get_lanman2_dir_entry(conn,
2044 mask,dirtype,info_level,
2045 requires_resume_key,dont_descend,
2046 &p,pdata,space_remaining, &out_of_space, &got_exact_match,
2047 &last_entry_off, ea_list, ea_ctx);
2050 if (finished && out_of_space)
2053 if (!finished && !out_of_space)
2057 * As an optimisation if we know we aren't looking
2058 * for a wildcard name (ie. the name matches the wildcard exactly)
2059 * then we can finish on any (first) match.
2060 * This speeds up large directory searches. JRA.
2066 space_remaining = max_data_bytes - PTR_DIFF(p,pdata);
2069 talloc_destroy(ea_ctx);
2071 /* Check if we can close the dirptr */
2072 if(close_after_request || (finished && close_if_end)) {
2073 DEBUG(5,("call_trans2findnext: closing dptr_num = %d\n", dptr_num));
2074 dptr_close(&dptr_num); /* This frees up the saved mask */
2077 /* Set up the return parameter block */
2078 SSVAL(params,0,numentries);
2079 SSVAL(params,2,finished);
2080 SSVAL(params,4,0); /* Never an EA error */
2081 SSVAL(params,6,last_entry_off);
2083 send_trans2_replies( outbuf, bufsize, params, 8, pdata, PTR_DIFF(p,pdata));
2085 if ((! *directory) && dptr_path(dptr_num))
2086 slprintf(directory,sizeof(directory)-1, "(%s)",dptr_path(dptr_num));
2088 DEBUG( 3, ( "%s mask=%s directory=%s dirtype=%d numentries=%d\n",
2089 smb_fn_name(CVAL(inbuf,smb_com)),
2090 mask, directory, dirtype, numentries ) );
2095 /****************************************************************************
2096 Reply to a TRANS2_QFSINFO (query filesystem info).
2097 ****************************************************************************/
2099 static int call_trans2qfsinfo(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize,
2100 char **pparams, int total_params, char **ppdata, int total_data,
2101 unsigned int max_data_bytes)
2103 char *pdata = *ppdata;
2104 char *params = *pparams;
2105 uint16 info_level = SVAL(params,0);
2108 char *vname = volume_label(SNUM(conn));
2109 int snum = SNUM(conn);
2110 char *fstype = lp_fstype(SNUM(conn));
2113 DEBUG(3,("call_trans2qfsinfo: level = %d\n", info_level));
2115 if(SMB_VFS_STAT(conn,".",&st)!=0) {
2116 DEBUG(2,("call_trans2qfsinfo: stat of . failed (%s)\n", strerror(errno)));
2117 return ERROR_DOS(ERRSRV,ERRinvdevice);
2120 pdata = SMB_REALLOC(*ppdata, max_data_bytes + DIR_ENTRY_SAFETY_MARGIN);
2121 if ( pdata == NULL ) {
2122 return ERROR_NT(NT_STATUS_NO_MEMORY);
2126 memset((char *)pdata,'\0',max_data_bytes + DIR_ENTRY_SAFETY_MARGIN);
2128 switch (info_level) {
2129 case SMB_INFO_ALLOCATION:
2131 SMB_BIG_UINT dfree,dsize,bsize,block_size,sectors_per_unit,bytes_per_sector;
2133 if (SMB_VFS_DISK_FREE(conn,".",False,&bsize,&dfree,&dsize) == (SMB_BIG_UINT)-1) {
2134 return(UNIXERROR(ERRHRD,ERRgeneral));
2137 block_size = lp_block_size(snum);
2138 if (bsize < block_size) {
2139 SMB_BIG_UINT factor = block_size/bsize;
2144 if (bsize > block_size) {
2145 SMB_BIG_UINT factor = bsize/block_size;
2150 bytes_per_sector = 512;
2151 sectors_per_unit = bsize/bytes_per_sector;
2153 DEBUG(5,("call_trans2qfsinfo : SMB_INFO_ALLOCATION id=%x, bsize=%u, cSectorUnit=%u, \
2154 cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)st.st_dev, (unsigned int)bsize, (unsigned int)sectors_per_unit,
2155 (unsigned int)bytes_per_sector, (unsigned int)dsize, (unsigned int)dfree));
2157 SIVAL(pdata,l1_idFileSystem,st.st_dev);
2158 SIVAL(pdata,l1_cSectorUnit,sectors_per_unit);
2159 SIVAL(pdata,l1_cUnit,dsize);
2160 SIVAL(pdata,l1_cUnitAvail,dfree);
2161 SSVAL(pdata,l1_cbSector,bytes_per_sector);
2165 case SMB_INFO_VOLUME:
2166 /* Return volume name */
2168 * Add volume serial number - hash of a combination of
2169 * the called hostname and the service name.
2171 SIVAL(pdata,0,str_checksum(lp_servicename(snum)) ^ (str_checksum(get_local_machine_name())<<16) );
2173 * Win2k3 and previous mess this up by sending a name length
2174 * one byte short. I believe only older clients (OS/2 Win9x) use
2175 * this call so try fixing this by adding a terminating null to
2176 * the pushed string. The change here was adding the STR_TERMINATE. JRA.
2178 len = srvstr_push(outbuf, pdata+l2_vol_szVolLabel, vname, -1, STR_NOALIGN|STR_TERMINATE);
2179 SCVAL(pdata,l2_vol_cch,len);
2180 data_len = l2_vol_szVolLabel + len;
2181 DEBUG(5,("call_trans2qfsinfo : time = %x, namelen = %d, name = %s\n",
2182 (unsigned)st.st_ctime, len, vname));
2185 case SMB_QUERY_FS_ATTRIBUTE_INFO:
2186 case SMB_FS_ATTRIBUTE_INFORMATION:
2189 #if defined(HAVE_SYS_QUOTAS)
2190 quota_flag = FILE_VOLUME_QUOTAS;
2193 SIVAL(pdata,0,FILE_CASE_PRESERVED_NAMES|FILE_CASE_SENSITIVE_SEARCH|
2194 (lp_nt_acl_support(SNUM(conn)) ? FILE_PERSISTENT_ACLS : 0)|
2195 quota_flag); /* FS ATTRIBUTES */
2197 SIVAL(pdata,4,255); /* Max filename component length */
2198 /* NOTE! the fstype must *not* be null terminated or win98 won't recognise it
2199 and will think we can't do long filenames */
2200 len = srvstr_push(outbuf, pdata+12, fstype, -1, STR_UNICODE);
2202 data_len = 12 + len;
2205 case SMB_QUERY_FS_LABEL_INFO:
2206 case SMB_FS_LABEL_INFORMATION:
2207 len = srvstr_push(outbuf, pdata+4, vname, -1, 0);
2212 case SMB_QUERY_FS_VOLUME_INFO:
2213 case SMB_FS_VOLUME_INFORMATION:
2216 * Add volume serial number - hash of a combination of
2217 * the called hostname and the service name.
2219 SIVAL(pdata,8,str_checksum(lp_servicename(snum)) ^
2220 (str_checksum(get_local_machine_name())<<16));
2222 len = srvstr_push(outbuf, pdata+18, vname, -1, STR_UNICODE);
2223 SIVAL(pdata,12,len);
2225 DEBUG(5,("call_trans2qfsinfo : SMB_QUERY_FS_VOLUME_INFO namelen = %d, vol=%s serv=%s\n",
2226 (int)strlen(vname),vname, lp_servicename(snum)));
2229 case SMB_QUERY_FS_SIZE_INFO:
2230 case SMB_FS_SIZE_INFORMATION:
2232 SMB_BIG_UINT dfree,dsize,bsize,block_size,sectors_per_unit,bytes_per_sector;
2234 if (SMB_VFS_DISK_FREE(conn,".",False,&bsize,&dfree,&dsize) == (SMB_BIG_UINT)-1) {
2235 return(UNIXERROR(ERRHRD,ERRgeneral));
2237 block_size = lp_block_size(snum);
2238 if (bsize < block_size) {
2239 SMB_BIG_UINT factor = block_size/bsize;
2244 if (bsize > block_size) {
2245 SMB_BIG_UINT factor = bsize/block_size;
2250 bytes_per_sector = 512;
2251 sectors_per_unit = bsize/bytes_per_sector;
2252 DEBUG(5,("call_trans2qfsinfo : SMB_QUERY_FS_SIZE_INFO bsize=%u, cSectorUnit=%u, \
2253 cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize, (unsigned int)sectors_per_unit,
2254 (unsigned int)bytes_per_sector, (unsigned int)dsize, (unsigned int)dfree));
2255 SBIG_UINT(pdata,0,dsize);
2256 SBIG_UINT(pdata,8,dfree);
2257 SIVAL(pdata,16,sectors_per_unit);
2258 SIVAL(pdata,20,bytes_per_sector);
2262 case SMB_FS_FULL_SIZE_INFORMATION:
2264 SMB_BIG_UINT dfree,dsize,bsize,block_size,sectors_per_unit,bytes_per_sector;
2266 if (SMB_VFS_DISK_FREE(conn,".",False,&bsize,&dfree,&dsize) == (SMB_BIG_UINT)-1) {
2267 return(UNIXERROR(ERRHRD,ERRgeneral));
2269 block_size = lp_block_size(snum);
2270 if (bsize < block_size) {
2271 SMB_BIG_UINT factor = block_size/bsize;
2276 if (bsize > block_size) {
2277 SMB_BIG_UINT factor = bsize/block_size;
2282 bytes_per_sector = 512;
2283 sectors_per_unit = bsize/bytes_per_sector;
2284 DEBUG(5,("call_trans2qfsinfo : SMB_QUERY_FS_FULL_SIZE_INFO bsize=%u, cSectorUnit=%u, \
2285 cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize, (unsigned int)sectors_per_unit,
2286 (unsigned int)bytes_per_sector, (unsigned int)dsize, (unsigned int)dfree));
2287 SBIG_UINT(pdata,0,dsize); /* Total Allocation units. */
2288 SBIG_UINT(pdata,8,dfree); /* Caller available allocation units. */
2289 SBIG_UINT(pdata,16,dfree); /* Actual available allocation units. */
2290 SIVAL(pdata,24,sectors_per_unit); /* Sectors per allocation unit. */
2291 SIVAL(pdata,28,bytes_per_sector); /* Bytes per sector. */
2295 case SMB_QUERY_FS_DEVICE_INFO:
2296 case SMB_FS_DEVICE_INFORMATION:
2298 SIVAL(pdata,0,0); /* dev type */
2299 SIVAL(pdata,4,0); /* characteristics */
2302 #ifdef HAVE_SYS_QUOTAS
2303 case SMB_FS_QUOTA_INFORMATION:
2305 * what we have to send --metze:
2307 * Unknown1: 24 NULL bytes
2308 * Soft Quota Treshold: 8 bytes seems like SMB_BIG_UINT or so
2309 * Hard Quota Limit: 8 bytes seems like SMB_BIG_UINT or so
2310 * Quota Flags: 2 byte :
2311 * Unknown3: 6 NULL bytes
2315 * details for Quota Flags:
2317 * 0x0020 Log Limit: log if the user exceeds his Hard Quota
2318 * 0x0010 Log Warn: log if the user exceeds his Soft Quota
2319 * 0x0002 Deny Disk: deny disk access when the user exceeds his Hard Quota
2320 * 0x0001 Enable Quotas: enable quota for this fs
2324 /* we need to fake up a fsp here,
2325 * because its not send in this call
2328 SMB_NTQUOTA_STRUCT quotas;
2331 ZERO_STRUCT(quotas);
2338 if (current_user.uid != 0) {
2339 DEBUG(0,("set_user_quota: access_denied service [%s] user [%s]\n",
2340 lp_servicename(SNUM(conn)),conn->user));
2341 return ERROR_DOS(ERRDOS,ERRnoaccess);
2344 if (vfs_get_ntquota(&fsp, SMB_USER_FS_QUOTA_TYPE, NULL, "as)!=0) {
2345 DEBUG(0,("vfs_get_ntquota() failed for service [%s]\n",lp_servicename(SNUM(conn))));
2346 return ERROR_DOS(ERRSRV,ERRerror);
2351 DEBUG(10,("SMB_FS_QUOTA_INFORMATION: for service [%s]\n",lp_servicename(SNUM(conn))));
2353 /* Unknown1 24 NULL bytes*/
2354 SBIG_UINT(pdata,0,(SMB_BIG_UINT)0);
2355 SBIG_UINT(pdata,8,(SMB_BIG_UINT)0);
2356 SBIG_UINT(pdata,16,(SMB_BIG_UINT)0);
2358 /* Default Soft Quota 8 bytes */
2359 SBIG_UINT(pdata,24,quotas.softlim);
2361 /* Default Hard Quota 8 bytes */
2362 SBIG_UINT(pdata,32,quotas.hardlim);
2364 /* Quota flag 2 bytes */
2365 SSVAL(pdata,40,quotas.qflags);
2367 /* Unknown3 6 NULL bytes */
2373 #endif /* HAVE_SYS_QUOTAS */
2374 case SMB_FS_OBJECTID_INFORMATION:
2379 * Query the version and capabilities of the CIFS UNIX extensions
2383 case SMB_QUERY_CIFS_UNIX_INFO:
2384 if (!lp_unix_extensions())
2385 return ERROR_DOS(ERRDOS,ERRunknownlevel);
2387 SSVAL(pdata,0,CIFS_UNIX_MAJOR_VERSION);
2388 SSVAL(pdata,2,CIFS_UNIX_MINOR_VERSION);
2389 SBIG_UINT(pdata,4,((SMB_BIG_UINT)(CIFS_UNIX_POSIX_ACLS_CAP|
2390 CIFS_UNIX_POSIX_PATHNAMES_CAP))); /* We have POSIX ACLs and pathname capability. */
2393 case SMB_MAC_QUERY_FS_INFO:
2395 * Thursby MAC extension... ONLY on NTFS filesystems
2396 * once we do streams then we don't need this
2398 if (strequal(lp_fstype(SNUM(conn)),"NTFS")) {
2400 SIVAL(pdata,84,0x100); /* Don't support mac... */
2405 return ERROR_DOS(ERRDOS,ERRunknownlevel);
2409 send_trans2_replies( outbuf, bufsize, params, 0, pdata, data_len);
2411 DEBUG( 4, ( "%s info_level = %d\n", smb_fn_name(CVAL(inbuf,smb_com)), info_level) );
2416 /****************************************************************************
2417 Reply to a TRANS2_SETFSINFO (set filesystem info).
2418 ****************************************************************************/
2420 static int call_trans2setfsinfo(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize,
2421 char **pparams, int total_params, char **ppdata, int total_data,
2422 unsigned int max_data_bytes)
2424 char *pdata = *ppdata;
2425 char *params = *pparams;
2429 DEBUG(10,("call_trans2setfsinfo: for service [%s]\n",lp_servicename(SNUM(conn))));
2432 if (total_params < 4) {
2433 DEBUG(0,("call_trans2setfsinfo: requires total_params(%d) >= 4 bytes!\n",
2435 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
2438 info_level = SVAL(params,2);
2440 switch(info_level) {
2441 case SMB_SET_CIFS_UNIX_INFO:
2443 uint16 client_unix_major;
2444 uint16 client_unix_minor;
2445 uint32 client_unix_cap_low;
2446 uint32 client_unix_cap_high;
2448 if (!lp_unix_extensions()) {
2449 return ERROR_DOS(ERRDOS,ERRunknownlevel);
2452 /* There should be 12 bytes of capabilities set. */
2453 if (total_data < 8) {
2454 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
2456 client_unix_major = SVAL(pdata,0);
2457 client_unix_minor = SVAL(pdata,2);
2458 client_unix_cap_low = IVAL(pdata,4);
2459 client_unix_cap_high = IVAL(pdata,8);
2460 /* Just print these values for now. */
2461 DEBUG(10,("call_trans2setfsinfo: set unix info. major = %u, minor = %u \
2462 cap_low = 0x%x, cap_high = 0x%x\n",
2463 (unsigned int)client_unix_major,
2464 (unsigned int)client_unix_minor,
2465 (unsigned int)client_unix_cap_low,
2466 (unsigned int)client_unix_cap_high ));
2468 /* Here is where we must switch to posix pathname processing... */
2469 lp_set_posix_pathnames();
2470 mangle_change_to_posix();
2473 case SMB_FS_QUOTA_INFORMATION:
2475 files_struct *fsp = NULL;
2476 SMB_NTQUOTA_STRUCT quotas;
2478 ZERO_STRUCT(quotas);
2481 if ((current_user.uid != 0)||!CAN_WRITE(conn)) {
2482 DEBUG(0,("set_user_quota: access_denied service [%s] user [%s]\n",
2483 lp_servicename(SNUM(conn)),conn->user));
2484 return ERROR_DOS(ERRSRV,ERRaccess);
2487 /* note: normaly there're 48 bytes,
2488 * but we didn't use the last 6 bytes for now
2491 fsp = file_fsp(params,0);
2492 if (!CHECK_NTQUOTA_HANDLE_OK(fsp,conn)) {
2493 DEBUG(3,("TRANSACT_GET_USER_QUOTA: no valid QUOTA HANDLE\n"));
2494 return ERROR_NT(NT_STATUS_INVALID_HANDLE);
2497 if (total_data < 42) {
2498 DEBUG(0,("call_trans2setfsinfo: SET_FS_QUOTA: requires total_data(%d) >= 42 bytes!\n",
2500 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
2503 /* unknown_1 24 NULL bytes in pdata*/
2505 /* the soft quotas 8 bytes (SMB_BIG_UINT)*/
2506 quotas.softlim = (SMB_BIG_UINT)IVAL(pdata,24);
2507 #ifdef LARGE_SMB_OFF_T
2508 quotas.softlim |= (((SMB_BIG_UINT)IVAL(pdata,28)) << 32);
2509 #else /* LARGE_SMB_OFF_T */
2510 if ((IVAL(pdata,28) != 0)&&
2511 ((quotas.softlim != 0xFFFFFFFF)||
2512 (IVAL(pdata,28)!=0xFFFFFFFF))) {
2513 /* more than 32 bits? */
2514 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
2516 #endif /* LARGE_SMB_OFF_T */
2518 /* the hard quotas 8 bytes (SMB_BIG_UINT)*/
2519 quotas.hardlim = (SMB_BIG_UINT)IVAL(pdata,32);
2520 #ifdef LARGE_SMB_OFF_T
2521 quotas.hardlim |= (((SMB_BIG_UINT)IVAL(pdata,36)) << 32);
2522 #else /* LARGE_SMB_OFF_T */
2523 if ((IVAL(pdata,36) != 0)&&
2524 ((quotas.hardlim != 0xFFFFFFFF)||
2525 (IVAL(pdata,36)!=0xFFFFFFFF))) {
2526 /* more than 32 bits? */
2527 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
2529 #endif /* LARGE_SMB_OFF_T */
2531 /* quota_flags 2 bytes **/
2532 quotas.qflags = SVAL(pdata,40);
2534 /* unknown_2 6 NULL bytes follow*/
2536 /* now set the quotas */
2537 if (vfs_set_ntquota(fsp, SMB_USER_FS_QUOTA_TYPE, NULL, "as)!=0) {
2538 DEBUG(0,("vfs_set_ntquota() failed for service [%s]\n",lp_servicename(SNUM(conn))));
2539 return ERROR_DOS(ERRSRV,ERRerror);
2545 DEBUG(3,("call_trans2setfsinfo: unknown level (0x%X) not implemented yet.\n",
2547 return ERROR_DOS(ERRDOS,ERRunknownlevel);
2552 * sending this reply works fine,
2553 * but I'm not sure it's the same
2554 * like windows do...
2557 outsize = set_message(outbuf,10,0,True);
2562 /****************************************************************************
2563 Utility function to set bad path error.
2564 ****************************************************************************/
2566 int set_bad_path_error(int err, BOOL bad_path, char *outbuf, int def_class, uint32 def_code)
2568 DEBUG(10,("set_bad_path_error: err = %d bad_path = %d\n",
2569 err, (int)bad_path ));
2573 return ERROR_NT(NT_STATUS_OBJECT_PATH_NOT_FOUND);
2575 return ERROR_NT(NT_STATUS_OBJECT_NAME_NOT_FOUND);
2578 return UNIXERROR(def_class,def_code);
2581 #if defined(HAVE_POSIX_ACLS)
2582 /****************************************************************************
2583 Utility function to count the number of entries in a POSIX acl.
2584 ****************************************************************************/
2586 static unsigned int count_acl_entries(connection_struct *conn, SMB_ACL_T posix_acl)
2588 unsigned int ace_count = 0;
2589 int entry_id = SMB_ACL_FIRST_ENTRY;
2590 SMB_ACL_ENTRY_T entry;
2592 while ( posix_acl && (SMB_VFS_SYS_ACL_GET_ENTRY(conn, posix_acl, entry_id, &entry) == 1)) {
2594 if (entry_id == SMB_ACL_FIRST_ENTRY) {
2595 entry_id = SMB_ACL_NEXT_ENTRY;
2602 /****************************************************************************
2603 Utility function to marshall a POSIX acl into wire format.
2604 ****************************************************************************/
2606 static BOOL marshall_posix_acl(connection_struct *conn, char *pdata, SMB_STRUCT_STAT *pst, SMB_ACL_T posix_acl)
2608 int entry_id = SMB_ACL_FIRST_ENTRY;
2609 SMB_ACL_ENTRY_T entry;
2611 while ( posix_acl && (SMB_VFS_SYS_ACL_GET_ENTRY(conn, posix_acl, entry_id, &entry) == 1)) {
2612 SMB_ACL_TAG_T tagtype;
2613 SMB_ACL_PERMSET_T permset;
2614 unsigned char perms = 0;
2615 unsigned int own_grp;
2618 if (entry_id == SMB_ACL_FIRST_ENTRY) {
2619 entry_id = SMB_ACL_NEXT_ENTRY;
2622 if (SMB_VFS_SYS_ACL_GET_TAG_TYPE(conn, entry, &tagtype) == -1) {
2623 DEBUG(0,("marshall_posix_acl: SMB_VFS_SYS_ACL_GET_TAG_TYPE failed.\n"));
2627 if (SMB_VFS_SYS_ACL_GET_PERMSET(conn, entry, &permset) == -1) {
2628 DEBUG(0,("marshall_posix_acl: SMB_VFS_SYS_ACL_GET_PERMSET failed.\n"));
2632 perms |= (SMB_VFS_SYS_ACL_GET_PERM(conn, permset, SMB_ACL_READ) ? SMB_POSIX_ACL_READ : 0);
2633 perms |= (SMB_VFS_SYS_ACL_GET_PERM(conn, permset, SMB_ACL_WRITE) ? SMB_POSIX_ACL_WRITE : 0);
2634 perms |= (SMB_VFS_SYS_ACL_GET_PERM(conn, permset, SMB_ACL_EXECUTE) ? SMB_POSIX_ACL_EXECUTE : 0);
2636 SCVAL(pdata,1,perms);
2639 case SMB_ACL_USER_OBJ:
2640 SCVAL(pdata,0,SMB_POSIX_ACL_USER_OBJ);
2641 own_grp = (unsigned int)pst->st_uid;
2642 SIVAL(pdata,2,own_grp);
2647 uid_t *puid = (uid_t *)SMB_VFS_SYS_ACL_GET_QUALIFIER(conn, entry);
2649 DEBUG(0,("marshall_posix_acl: SMB_VFS_SYS_ACL_GET_QUALIFIER failed.\n"));
2651 own_grp = (unsigned int)*puid;
2652 SMB_VFS_SYS_ACL_FREE_QUALIFIER(conn, (void *)puid,tagtype);
2653 SCVAL(pdata,0,SMB_POSIX_ACL_USER);
2654 SIVAL(pdata,2,own_grp);
2658 case SMB_ACL_GROUP_OBJ:
2659 SCVAL(pdata,0,SMB_POSIX_ACL_GROUP_OBJ);
2660 own_grp = (unsigned int)pst->st_gid;
2661 SIVAL(pdata,2,own_grp);
2666 gid_t *pgid= (gid_t *)SMB_VFS_SYS_ACL_GET_QUALIFIER(conn, entry);
2668 DEBUG(0,("marshall_posix_acl: SMB_VFS_SYS_ACL_GET_QUALIFIER failed.\n"));
2670 own_grp = (unsigned int)*pgid;
2671 SMB_VFS_SYS_ACL_FREE_QUALIFIER(conn, (void *)pgid,tagtype);
2672 SCVAL(pdata,0,SMB_POSIX_ACL_GROUP);
2673 SIVAL(pdata,2,own_grp);
2678 SCVAL(pdata,0,SMB_POSIX_ACL_MASK);
2679 SIVAL(pdata,2,0xFFFFFFFF);
2680 SIVAL(pdata,6,0xFFFFFFFF);
2683 SCVAL(pdata,0,SMB_POSIX_ACL_OTHER);
2684 SIVAL(pdata,2,0xFFFFFFFF);
2685 SIVAL(pdata,6,0xFFFFFFFF);
2688 DEBUG(0,("marshall_posix_acl: unknown tagtype.\n"));
2691 pdata += SMB_POSIX_ACL_ENTRY_SIZE;
2698 /****************************************************************************
2699 Reply to a TRANS2_QFILEPATHINFO or TRANSACT2_QFILEINFO (query file info by
2700 file name or file id).
2701 ****************************************************************************/
2703 static int call_trans2qfilepathinfo(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize,
2704 unsigned int tran_call,
2705 char **pparams, int total_params, char **ppdata, int total_data,
2706 unsigned int max_data_bytes)
2708 char *params = *pparams;
2709 char *pdata = *ppdata;
2712 SMB_OFF_T file_size=0;
2713 SMB_BIG_UINT allocation_size=0;
2714 unsigned int data_size = 0;
2715 unsigned int param_size = 2;
2716 SMB_STRUCT_STAT sbuf;
2717 pstring fname, dos_fname;
2722 BOOL bad_path = False;
2723 BOOL delete_pending = False;
2726 files_struct *fsp = NULL;
2727 TALLOC_CTX *ea_ctx = NULL;
2728 struct ea_list *ea_list = NULL;
2729 uint32 desired_access = 0x12019F; /* Default - GENERIC_EXECUTE mapping from Windows */
2732 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
2736 if (tran_call == TRANSACT2_QFILEINFO) {
2737 if (total_params < 4) {
2738 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
2741 fsp = file_fsp(params,0);
2742 info_level = SVAL(params,2);
2744 DEBUG(3,("call_trans2qfilepathinfo: TRANSACT2_QFILEINFO: level = %d\n", info_level));
2746 if(fsp && (fsp->fake_file_handle)) {
2748 * This is actually for the QUOTA_FAKE_FILE --metze
2751 pstrcpy(fname, fsp->fsp_name);
2752 /* We know this name is ok, it's already passed the checks. */
2754 } else if(fsp && (fsp->is_directory || fsp->fd == -1)) {
2756 * This is actually a QFILEINFO on a directory
2757 * handle (returned from an NT SMB). NT5.0 seems
2758 * to do this call. JRA.
2760 /* We know this name is ok, it's already passed the checks. */
2761 pstrcpy(fname, fsp->fsp_name);
2763 if (INFO_LEVEL_IS_UNIX(info_level)) {
2764 /* Always do lstat for UNIX calls. */
2765 if (SMB_VFS_LSTAT(conn,fname,&sbuf)) {
2766 DEBUG(3,("call_trans2qfilepathinfo: SMB_VFS_LSTAT of %s failed (%s)\n",fname,strerror(errno)));
2767 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRbadpath);
2769 } else if (SMB_VFS_STAT(conn,fname,&sbuf)) {
2770 DEBUG(3,("call_trans2qfilepathinfo: SMB_VFS_STAT of %s failed (%s)\n",fname,strerror(errno)));
2771 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRbadpath);
2774 delete_pending = fsp->is_directory ? fsp->directory_delete_on_close : 0;
2777 * Original code - this is an open file.
2779 CHECK_FSP(fsp,conn);
2781 pstrcpy(fname, fsp->fsp_name);
2782 if (SMB_VFS_FSTAT(fsp,fsp->fd,&sbuf) != 0) {
2783 DEBUG(3,("fstat of fnum %d failed (%s)\n", fsp->fnum, strerror(errno)));
2784 return(UNIXERROR(ERRDOS,ERRbadfid));
2786 pos = fsp->position_information;
2787 delete_pending = fsp->delete_on_close;
2788 desired_access = fsp->desired_access;
2791 NTSTATUS status = NT_STATUS_OK;
2794 if (total_params < 6) {
2795 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
2798 info_level = SVAL(params,0);
2800 DEBUG(3,("call_trans2qfilepathinfo: TRANSACT2_QPATHINFO: level = %d\n", info_level));
2802 srvstr_get_path(inbuf, fname, ¶ms[6], sizeof(fname), -1, STR_TERMINATE, &status, False);
2803 if (!NT_STATUS_IS_OK(status)) {
2804 return ERROR_NT(status);
2807 RESOLVE_DFSPATH(fname, conn, inbuf, outbuf);
2809 unix_convert(fname,conn,0,&bad_path,&sbuf);
2811 return ERROR_NT(NT_STATUS_OBJECT_PATH_NOT_FOUND);
2813 if (!check_name(fname,conn)) {
2814 DEBUG(3,("call_trans2qfilepathinfo: fileinfo of %s failed (%s)\n",fname,strerror(errno)));
2815 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRbadpath);
2818 if (INFO_LEVEL_IS_UNIX(info_level)) {
2819 /* Always do lstat for UNIX calls. */
2820 if (SMB_VFS_LSTAT(conn,fname,&sbuf)) {
2821 DEBUG(3,("call_trans2qfilepathinfo: SMB_VFS_LSTAT of %s failed (%s)\n",fname,strerror(errno)));
2822 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRbadpath);
2824 } else if (!VALID_STAT(sbuf) && SMB_VFS_STAT(conn,fname,&sbuf) && (info_level != SMB_INFO_IS_NAME_VALID)) {
2825 DEBUG(3,("call_trans2qfilepathinfo: SMB_VFS_STAT of %s failed (%s)\n",fname,strerror(errno)));
2826 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRbadpath);
2830 if (INFO_LEVEL_IS_UNIX(info_level) && !lp_unix_extensions())
2831 return ERROR_DOS(ERRDOS,ERRunknownlevel);
2833 DEBUG(3,("call_trans2qfilepathinfo %s (fnum = %d) level=%d call=%d total_data=%d\n",
2834 fname,fsp ? fsp->fnum : -1, info_level,tran_call,total_data));
2836 p = strrchr_m(fname,'/');
2842 mode = dos_mode(conn,fname,&sbuf);
2844 mode = FILE_ATTRIBUTE_NORMAL;
2846 fullpathname = fname;
2847 file_size = get_file_size(sbuf);
2849 /* This is necessary, as otherwise the desktop.ini file in
2850 * this folder is ignored */
2851 mode |= (lp_profile_acls(SNUM(conn)) ? aRONLY : 0);
2855 /* Pull any EA list from the data portion. */
2856 if (info_level == SMB_INFO_QUERY_EAS_FROM_LIST) {
2859 if (total_data < 4) {
2860 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
2862 ea_size = IVAL(pdata,0);
2864 if (total_data > 0 && ea_size != total_data) {
2865 DEBUG(4,("call_trans2qfilepathinfo: Rejecting EA request with incorrect \
2866 total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pdata,0) ));
2867 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
2870 if (!lp_ea_support(SNUM(conn))) {
2871 return ERROR_DOS(ERRDOS,ERReasnotsupported);
2874 if ((ea_ctx = talloc_init("ea_list")) == NULL) {
2875 return ERROR_NT(NT_STATUS_NO_MEMORY);
2878 /* Pull out the list of names. */
2879 ea_list = read_ea_name_list(ea_ctx, pdata + 4, ea_size - 4);
2881 talloc_destroy(ea_ctx);
2882 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
2886 params = SMB_REALLOC(*pparams,2);
2887 if (params == NULL) {
2888 talloc_destroy(ea_ctx);
2889 return ERROR_NT(NT_STATUS_NO_MEMORY);
2893 data_size = max_data_bytes + DIR_ENTRY_SAFETY_MARGIN;
2894 pdata = SMB_REALLOC(*ppdata, data_size);
2895 if ( pdata == NULL ) {
2896 talloc_destroy(ea_ctx);
2897 return ERROR_NT(NT_STATUS_NO_MEMORY);
2901 c_time = get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(conn)));
2903 allocation_size = get_allocation_size(conn,fsp,&sbuf);
2906 if (fsp->pending_modtime) {
2907 /* the pending modtime overrides the current modtime */
2908 sbuf.st_mtime = fsp->pending_modtime;
2911 /* Do we have this path open ? */
2912 files_struct *fsp1 = file_find_di_first(sbuf.st_dev, sbuf.st_ino);
2913 if (fsp1 && fsp1->pending_modtime) {
2914 /* the pending modtime overrides the current modtime */
2915 sbuf.st_mtime = fsp1->pending_modtime;
2917 if (fsp1 && fsp1->initial_allocation_size) {
2918 allocation_size = get_allocation_size(conn, fsp1, &sbuf);
2922 if (lp_dos_filetime_resolution(SNUM(conn))) {
2924 sbuf.st_atime &= ~1;
2925 sbuf.st_ctime &= ~1;
2926 sbuf.st_mtime &= ~1;
2929 /* NT expects the name to be in an exact form of the *full*
2930 filename. See the trans2 torture test */
2931 if (strequal(base_name,".")) {
2932 pstrcpy(dos_fname, "\\");
2934 pstr_sprintf(dos_fname, "\\%s", fname);
2935 string_replace(dos_fname, '/', '\\');
2938 switch (info_level) {
2939 case SMB_INFO_STANDARD:
2940 DEBUG(10,("call_trans2qfilepathinfo: SMB_INFO_STANDARD\n"));
2942 put_dos_date2(pdata,l1_fdateCreation,c_time);
2943 put_dos_date2(pdata,l1_fdateLastAccess,sbuf.st_atime);
2944 put_dos_date2(pdata,l1_fdateLastWrite,sbuf.st_mtime); /* write time */
2945 SIVAL(pdata,l1_cbFile,(uint32)file_size);
2946 SIVAL(pdata,l1_cbFileAlloc,(uint32)allocation_size);
2947 SSVAL(pdata,l1_attrFile,mode);
2950 case SMB_INFO_QUERY_EA_SIZE:
2952 unsigned int ea_size = estimate_ea_size(conn, fsp, fname);
2953 DEBUG(10,("call_trans2qfilepathinfo: SMB_INFO_QUERY_EA_SIZE\n"));
2955 put_dos_date2(pdata,0,c_time);
2956 put_dos_date2(pdata,4,sbuf.st_atime);
2957 put_dos_date2(pdata,8,sbuf.st_mtime); /* write time */
2958 SIVAL(pdata,12,(uint32)file_size);
2959 SIVAL(pdata,16,(uint32)allocation_size);
2960 SSVAL(pdata,20,mode);
2961 SIVAL(pdata,22,ea_size);
2965 case SMB_INFO_IS_NAME_VALID:
2966 DEBUG(10,("call_trans2qfilepathinfo: SMB_INFO_IS_NAME_VALID\n"));
2967 if (tran_call == TRANSACT2_QFILEINFO) {
2968 /* os/2 needs this ? really ?*/
2969 return ERROR_DOS(ERRDOS,ERRbadfunc);
2975 case SMB_INFO_QUERY_EAS_FROM_LIST:
2977 size_t total_ea_len = 0;
2978 struct ea_list *ea_file_list = NULL;
2980 DEBUG(10,("call_trans2qfilepathinfo: SMB_INFO_QUERY_EAS_FROM_LIST\n"));
2982 ea_file_list = get_ea_list_from_file(ea_ctx, conn, fsp, fname, &total_ea_len);
2983 ea_list = ea_list_union(ea_list, ea_file_list, &total_ea_len);
2985 if (!ea_list || (total_ea_len > data_size)) {
2986 talloc_destroy(ea_ctx);
2988 SIVAL(pdata,0,4); /* EA List Length must be set to 4 if no EA's. */
2992 data_size = fill_ea_buffer(ea_ctx, pdata, data_size, conn, ea_list);
2993 talloc_destroy(ea_ctx);
2997 case SMB_INFO_QUERY_ALL_EAS:
2999 /* We have data_size bytes to put EA's into. */
3000 size_t total_ea_len = 0;
3002 DEBUG(10,("call_trans2qfilepathinfo: SMB_INFO_QUERY_ALL_EAS\n"));
3004 ea_ctx = talloc_init("ea_ctx");
3006 return ERROR_NT(NT_STATUS_NO_MEMORY);
3009 ea_list = get_ea_list_from_file(ea_ctx, conn, fsp, fname, &total_ea_len);
3010 if (!ea_list || (total_ea_len > data_size)) {
3011 talloc_destroy(ea_ctx);
3013 SIVAL(pdata,0,4); /* EA List Length must be set to 4 if no EA's. */
3017 data_size = fill_ea_buffer(ea_ctx, pdata, data_size, conn, ea_list);
3018 talloc_destroy(ea_ctx);
3022 case SMB_FILE_BASIC_INFORMATION:
3023 case SMB_QUERY_FILE_BASIC_INFO:
3025 if (info_level == SMB_QUERY_FILE_BASIC_INFO) {
3026 DEBUG(10,("call_trans2qfilepathinfo: SMB_QUERY_FILE_BASIC_INFO\n"));
3027 data_size = 36; /* w95 returns 40 bytes not 36 - why ?. */
3029 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_BASIC_INFORMATION\n"));
3033 put_long_date(pdata,c_time);
3034 put_long_date(pdata+8,sbuf.st_atime);
3035 put_long_date(pdata+16,sbuf.st_mtime); /* write time */
3036 put_long_date(pdata+24,sbuf.st_mtime); /* change time */
3037 SIVAL(pdata,32,mode);
3039 DEBUG(5,("SMB_QFBI - "));
3041 time_t create_time = c_time;
3042 DEBUG(5,("create: %s ", ctime(&create_time)));
3044 DEBUG(5,("access: %s ", ctime(&sbuf.st_atime)));
3045 DEBUG(5,("write: %s ", ctime(&sbuf.st_mtime)));
3046 DEBUG(5,("change: %s ", ctime(&sbuf.st_mtime)));
3047 DEBUG(5,("mode: %x\n", mode));
3050 case SMB_FILE_STANDARD_INFORMATION:
3051 case SMB_QUERY_FILE_STANDARD_INFO:
3053 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_STANDARD_INFORMATION\n"));
3055 SOFF_T(pdata,0,allocation_size);
3056 SOFF_T(pdata,8,file_size);
3057 if (delete_pending & sbuf.st_nlink)
3058 SIVAL(pdata,16,sbuf.st_nlink - 1);
3060 SIVAL(pdata,16,sbuf.st_nlink);
3062 SCVAL(pdata,21,(mode&aDIR)?1:0);
3063 SSVAL(pdata,22,0); /* Padding. */
3066 case SMB_FILE_EA_INFORMATION:
3067 case SMB_QUERY_FILE_EA_INFO:
3069 unsigned int ea_size = estimate_ea_size(conn, fsp, fname);
3070 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_EA_INFORMATION\n"));
3072 SIVAL(pdata,0,ea_size);
3076 /* Get the 8.3 name - used if NT SMB was negotiated. */
3077 case SMB_QUERY_FILE_ALT_NAME_INFO:
3078 case SMB_FILE_ALTERNATE_NAME_INFORMATION:
3082 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_ALTERNATE_NAME_INFORMATION\n"));
3083 pstrcpy(short_name,base_name);
3084 /* Mangle if not already 8.3 */
3085 if(!mangle_is_8_3(short_name, True, SNUM(conn))) {
3086 mangle_map(short_name,True,True,SNUM(conn));
3088 len = srvstr_push(outbuf, pdata+4, short_name, -1, STR_UNICODE);
3089 data_size = 4 + len;
3094 case SMB_QUERY_FILE_NAME_INFO:
3096 this must be *exactly* right for ACLs on mapped drives to work
3098 len = srvstr_push(outbuf, pdata+4, dos_fname, -1, STR_UNICODE);
3099 DEBUG(10,("call_trans2qfilepathinfo: SMB_QUERY_FILE_NAME_INFO\n"));
3100 data_size = 4 + len;
3104 case SMB_FILE_ALLOCATION_INFORMATION:
3105 case SMB_QUERY_FILE_ALLOCATION_INFO:
3106 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_ALLOCATION_INFORMATION\n"));
3108 SOFF_T(pdata,0,allocation_size);
3111 case SMB_FILE_END_OF_FILE_INFORMATION:
3112 case SMB_QUERY_FILE_END_OF_FILEINFO:
3113 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_END_OF_FILE_INFORMATION\n"));
3115 SOFF_T(pdata,0,file_size);
3118 case SMB_QUERY_FILE_ALL_INFO:
3119 case SMB_FILE_ALL_INFORMATION:
3121 unsigned int ea_size = estimate_ea_size(conn, fsp, fname);
3122 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_ALL_INFORMATION\n"));
3123 put_long_date(pdata,c_time);
3124 put_long_date(pdata+8,sbuf.st_atime);
3125 put_long_date(pdata+16,sbuf.st_mtime); /* write time */
3126 put_long_date(pdata+24,sbuf.st_mtime); /* change time */
3127 SIVAL(pdata,32,mode);
3128 SIVAL(pdata,36,0); /* padding. */
3130 SOFF_T(pdata,0,allocation_size);
3131 SOFF_T(pdata,8,file_size);
3132 if (delete_pending && sbuf.st_nlink)
3133 SIVAL(pdata,16,sbuf.st_nlink - 1);
3135 SIVAL(pdata,16,sbuf.st_nlink);
3136 SCVAL(pdata,20,delete_pending);
3137 SCVAL(pdata,21,(mode&aDIR)?1:0);
3140 SIVAL(pdata,0,ea_size);
3141 pdata += 4; /* EA info */
3142 len = srvstr_push(outbuf, pdata+4, dos_fname, -1, STR_UNICODE);
3145 data_size = PTR_DIFF(pdata,(*ppdata));
3148 case SMB_FILE_INTERNAL_INFORMATION:
3149 /* This should be an index number - looks like
3152 I think this causes us to fail the IFSKIT
3153 BasicFileInformationTest. -tpot */
3155 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_INTERNAL_INFORMATION\n"));
3156 SIVAL(pdata,0,sbuf.st_dev);
3157 SIVAL(pdata,4,sbuf.st_ino);
3161 case SMB_FILE_ACCESS_INFORMATION:
3162 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_ACCESS_INFORMATION\n"));
3163 SIVAL(pdata,0,desired_access);
3167 case SMB_FILE_NAME_INFORMATION:
3168 /* Pathname with leading '\'. */
3171 byte_len = dos_PutUniCode(pdata+4,dos_fname,max_data_bytes,False);
3172 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_NAME_INFORMATION\n"));
3173 SIVAL(pdata,0,byte_len);
3174 data_size = 4 + byte_len;
3178 case SMB_FILE_DISPOSITION_INFORMATION:
3179 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_DISPOSITION_INFORMATION\n"));
3181 SCVAL(pdata,0,delete_pending);
3184 case SMB_FILE_POSITION_INFORMATION:
3185 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_POSITION_INFORMATION\n"));
3187 SOFF_T(pdata,0,pos);
3190 case SMB_FILE_MODE_INFORMATION:
3191 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_MODE_INFORMATION\n"));
3192 SIVAL(pdata,0,mode);
3196 case SMB_FILE_ALIGNMENT_INFORMATION:
3197 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_ALIGNMENT_INFORMATION\n"));
3198 SIVAL(pdata,0,0); /* No alignment needed. */
3204 * NT4 server just returns "invalid query" to this - if we try to answer
3205 * it then NTws gets a BSOD! (tridge).
3206 * W2K seems to want this. JRA.
3208 case SMB_QUERY_FILE_STREAM_INFO:
3210 case SMB_FILE_STREAM_INFORMATION:
3211 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_STREAM_INFORMATION\n"));
3215 size_t byte_len = dos_PutUniCode(pdata+24,"::$DATA", 0xE, False);
3216 SIVAL(pdata,0,0); /* ??? */
3217 SIVAL(pdata,4,byte_len); /* Byte length of unicode string ::$DATA */
3218 SOFF_T(pdata,8,file_size);
3219 SIVAL(pdata,16,allocation_size);
3220 SIVAL(pdata,20,0); /* ??? */
3221 data_size = 24 + byte_len;
3225 case SMB_QUERY_COMPRESSION_INFO:
3226 case SMB_FILE_COMPRESSION_INFORMATION:
3227 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_COMPRESSION_INFORMATION\n"));
3228 SOFF_T(pdata,0,file_size);
3229 SIVAL(pdata,8,0); /* ??? */
3230 SIVAL(pdata,12,0); /* ??? */
3234 case SMB_FILE_NETWORK_OPEN_INFORMATION:
3235 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_NETWORK_OPEN_INFORMATION\n"));
3236 put_long_date(pdata,c_time);
3237 put_long_date(pdata+8,sbuf.st_atime);
3238 put_long_date(pdata+16,sbuf.st_mtime); /* write time */
3239 put_long_date(pdata+24,sbuf.st_mtime); /* change time */
3240 SIVAL(pdata,32,allocation_size);
3241 SOFF_T(pdata,40,file_size);
3242 SIVAL(pdata,48,mode);
3243 SIVAL(pdata,52,0); /* ??? */
3247 case SMB_FILE_ATTRIBUTE_TAG_INFORMATION:
3248 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_ATTRIBUTE_TAG_INFORMATION\n"));
3249 SIVAL(pdata,0,mode);
3255 * CIFS UNIX Extensions.
3258 case SMB_QUERY_FILE_UNIX_BASIC:
3260 DEBUG(10,("call_trans2qfilepathinfo: SMB_QUERY_FILE_UNIX_BASIC\n"));
3261 DEBUG(4,("call_trans2qfilepathinfo: st_mode=%o\n",(int)sbuf.st_mode));
3263 SOFF_T(pdata,0,get_file_size(sbuf)); /* File size 64 Bit */
3266 SOFF_T(pdata,0,get_allocation_size(conn,fsp,&sbuf)); /* Number of bytes used on disk - 64 Bit */
3269 put_long_date(pdata,sbuf.st_ctime); /* Creation Time 64 Bit */
3270 put_long_date(pdata+8,sbuf.st_atime); /* Last access time 64 Bit */
3271 put_long_date(pdata+16,sbuf.st_mtime); /* Last modification time 64 Bit */
3274 SIVAL(pdata,0,sbuf.st_uid); /* user id for the owner */
3278 SIVAL(pdata,0,sbuf.st_gid); /* group id of owner */
3282 SIVAL(pdata,0,unix_filetype(sbuf.st_mode));
3285 SIVAL(pdata,0,unix_dev_major(sbuf.st_rdev)); /* Major device number if type is device */
3289 SIVAL(pdata,0,unix_dev_minor(sbuf.st_rdev)); /* Minor device number if type is device */
3293 SINO_T(pdata,0,(SMB_INO_T)sbuf.st_ino); /* inode number */
3296 SIVAL(pdata,0, unix_perms_to_wire(sbuf.st_mode)); /* Standard UNIX file permissions */
3300 SIVAL(pdata,0,sbuf.st_nlink); /* number of hard links */
3303 data_size = PTR_DIFF(pdata,(*ppdata));
3307 DEBUG(4,("call_trans2qfilepathinfo: SMB_QUERY_FILE_UNIX_BASIC"));
3309 for (i=0; i<100; i++)
3310 DEBUG(4,("%d=%x, ",i, (*ppdata)[i]));
3316 case SMB_QUERY_FILE_UNIX_LINK:
3320 DEBUG(10,("call_trans2qfilepathinfo: SMB_QUERY_FILE_UNIX_LINK\n"));
3322 if(!S_ISLNK(sbuf.st_mode))
3323 return(UNIXERROR(ERRSRV,ERRbadlink));
3325 return(UNIXERROR(ERRDOS,ERRbadlink));
3327 len = SMB_VFS_READLINK(conn,fullpathname, buffer, sizeof(pstring)-1); /* read link */
3329 return(UNIXERROR(ERRDOS,ERRnoaccess));
3331 len = srvstr_push(outbuf, pdata, buffer, -1, STR_TERMINATE);
3333 data_size = PTR_DIFF(pdata,(*ppdata));
3338 #if defined(HAVE_POSIX_ACLS)
3339 case SMB_QUERY_POSIX_ACL:
3341 SMB_ACL_T file_acl = NULL;
3342 SMB_ACL_T def_acl = NULL;
3343 uint16 num_file_acls = 0;
3344 uint16 num_def_acls = 0;
3346 if (fsp && !fsp->is_directory && (fsp->fd != -1)) {
3347 file_acl = SMB_VFS_SYS_ACL_GET_FD(fsp, fsp->fd);
3349 file_acl = SMB_VFS_SYS_ACL_GET_FILE(conn, fname, SMB_ACL_TYPE_ACCESS);
3352 if (file_acl == NULL && no_acl_syscall_error(errno)) {
3353 DEBUG(5,("call_trans2qfilepathinfo: ACLs not implemented on filesystem containing %s\n",
3355 return ERROR_NT(NT_STATUS_NOT_IMPLEMENTED);
3358 if (S_ISDIR(sbuf.st_mode)) {
3359 if (fsp && fsp->is_directory) {
3360 def_acl = SMB_VFS_SYS_ACL_GET_FILE(conn, fsp->fsp_name, SMB_ACL_TYPE_DEFAULT);
3362 def_acl = SMB_VFS_SYS_ACL_GET_FILE(conn, fname, SMB_ACL_TYPE_DEFAULT);
3364 def_acl = free_empty_sys_acl(conn, def_acl);
3367 num_file_acls = count_acl_entries(conn, file_acl);
3368 num_def_acls = count_acl_entries(conn, def_acl);
3370 if ( data_size < (num_file_acls + num_def_acls)*SMB_POSIX_ACL_ENTRY_SIZE + SMB_POSIX_ACL_HEADER_SIZE) {
3371 DEBUG(5,("call_trans2qfilepathinfo: data_size too small (%u) need %u\n",
3373 (unsigned int)((num_file_acls + num_def_acls)*SMB_POSIX_ACL_ENTRY_SIZE +
3374 SMB_POSIX_ACL_HEADER_SIZE) ));
3376 SMB_VFS_SYS_ACL_FREE_ACL(conn, file_acl);
3379 SMB_VFS_SYS_ACL_FREE_ACL(conn, def_acl);
3381 return ERROR_NT(NT_STATUS_BUFFER_TOO_SMALL);
3384 SSVAL(pdata,0,SMB_POSIX_ACL_VERSION);
3385 SSVAL(pdata,2,num_file_acls);
3386 SSVAL(pdata,4,num_def_acls);
3387 if (!marshall_posix_acl(conn, pdata + SMB_POSIX_ACL_HEADER_SIZE, &sbuf, file_acl)) {
3389 SMB_VFS_SYS_ACL_FREE_ACL(conn, file_acl);
3392 SMB_VFS_SYS_ACL_FREE_ACL(conn, def_acl);
3394 return ERROR_NT(NT_STATUS_INTERNAL_ERROR);
3396 if (!marshall_posix_acl(conn, pdata + SMB_POSIX_ACL_HEADER_SIZE + (num_file_acls*SMB_POSIX_ACL_ENTRY_SIZE), &sbuf, def_acl)) {
3398 SMB_VFS_SYS_ACL_FREE_ACL(conn, file_acl);
3401 SMB_VFS_SYS_ACL_FREE_ACL(conn, def_acl);
3403 return ERROR_NT(NT_STATUS_INTERNAL_ERROR);
3407 SMB_VFS_SYS_ACL_FREE_ACL(conn, file_acl);
3410 SMB_VFS_SYS_ACL_FREE_ACL(conn, def_acl);
3412 data_size = (num_file_acls + num_def_acls)*SMB_POSIX_ACL_ENTRY_SIZE + SMB_POSIX_ACL_HEADER_SIZE;
3418 return ERROR_DOS(ERRDOS,ERRunknownlevel);
3421 send_trans2_replies(outbuf, bufsize, params, param_size, *ppdata, data_size);
3426 /****************************************************************************
3427 Deal with the internal needs of setting the delete on close flag. Note that
3428 as the tdb locking is recursive, it is safe to call this from within
3429 open_file_shared. JRA.
3430 ****************************************************************************/
3432 NTSTATUS set_delete_on_close_internal(files_struct *fsp, BOOL delete_on_close, uint32 dosmode)
3434 if (delete_on_close) {
3436 * Only allow delete on close for writable files.
3439 if (!lp_delete_readonly(SNUM(fsp->conn))) {
3440 if (dosmode & aRONLY) {
3441 DEBUG(10,("set_delete_on_close_internal: file %s delete on close flag set but file attribute is readonly.\n",
3443 return NT_STATUS_CANNOT_DELETE;
3448 * Only allow delete on close for writable shares.
3451 if (!CAN_WRITE(fsp->conn)) {
3452 DEBUG(10,("set_delete_on_close_internal: file %s delete on close flag set but write access denied on share.\n",
3454 return NT_STATUS_ACCESS_DENIED;
3458 * Only allow delete on close for files/directories opened with delete intent.
3461 if (!(fsp->desired_access & DELETE_ACCESS)) {
3462 DEBUG(10,("set_delete_on_close_internal: file %s delete on close flag set but delete access denied.\n",
3464 return NT_STATUS_ACCESS_DENIED;
3468 if(fsp->is_directory) {
3469 fsp->directory_delete_on_close = delete_on_close;
3470 DEBUG(10, ("set_delete_on_close_internal: %s delete on close flag for fnum = %d, directory %s\n",
3471 delete_on_close ? "Added" : "Removed", fsp->fnum, fsp->fsp_name ));
3473 fsp->delete_on_close = delete_on_close;
3474 DEBUG(10, ("set_delete_on_close_internal: %s delete on close flag for fnum = %d, file %s\n",
3475 delete_on_close ? "Added" : "Removed", fsp->fnum, fsp->fsp_name ));
3478 return NT_STATUS_OK;
3481 /****************************************************************************
3482 Sets the delete on close flag over all share modes on this file.
3483 Modify the share mode entry for all files open
3484 on this device and inode to tell other smbds we have
3485 changed the delete on close flag. This will be noticed
3486 in the close code, the last closer will delete the file
3488 ****************************************************************************/
3490 NTSTATUS set_delete_on_close_over_all(files_struct *fsp, BOOL delete_on_close)
3492 DEBUG(10,("set_delete_on_close_over_all: %s delete on close flag for fnum = %d, file %s\n",
3493 delete_on_close ? "Adding" : "Removing", fsp->fnum, fsp->fsp_name ));
3495 if (fsp->is_directory || fsp->is_stat)
3496 return NT_STATUS_OK;
3498 if (lock_share_entry_fsp(fsp) == False)
3499 return NT_STATUS_ACCESS_DENIED;
3501 if (!modify_delete_flag(fsp->dev, fsp->inode, delete_on_close)) {
3502 DEBUG(0,("set_delete_on_close_over_all: failed to change delete on close flag for file %s\n",
3504 unlock_share_entry_fsp(fsp);
3505 return NT_STATUS_ACCESS_DENIED;
3508 unlock_share_entry_fsp(fsp);
3509 return NT_STATUS_OK;
3512 /****************************************************************************
3513 Set a hard link (called by UNIX extensions and by NT rename with HARD link
3515 ****************************************************************************/
3517 NTSTATUS hardlink_internals(connection_struct *conn, char *oldname, char *newname)
3519 BOOL bad_path_oldname = False;
3520 BOOL bad_path_newname = False;
3521 SMB_STRUCT_STAT sbuf1, sbuf2;
3522 pstring last_component_oldname;
3523 pstring last_component_newname;
3524 NTSTATUS status = NT_STATUS_OK;
3530 if (ms_has_wild(newname) || ms_has_wild(oldname)) {
3531 return NT_STATUS_OBJECT_PATH_SYNTAX_BAD;
3534 unix_convert(oldname,conn,last_component_oldname,&bad_path_oldname,&sbuf1);
3535 if (bad_path_oldname) {
3536 return NT_STATUS_OBJECT_PATH_NOT_FOUND;
3539 /* Quick check for "." and ".." */
3540 if (last_component_oldname[0] == '.') {
3541 if (!last_component_oldname[1] || (last_component_oldname[1] == '.' && !last_component_oldname[2])) {
3542 return NT_STATUS_OBJECT_NAME_INVALID;
3546 /* source must already exist. */
3547 if (!VALID_STAT(sbuf1)) {
3548 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3551 if (!check_name(oldname,conn)) {
3552 return NT_STATUS_ACCESS_DENIED;
3555 unix_convert(newname,conn,last_component_newname,&bad_path_newname,&sbuf2);
3556 if (bad_path_newname) {
3557 return NT_STATUS_OBJECT_PATH_NOT_FOUND;
3560 /* Quick check for "." and ".." */
3561 if (last_component_newname[0] == '.') {
3562 if (!last_component_newname[1] || (last_component_newname[1] == '.' && !last_component_newname[2])) {
3563 return NT_STATUS_OBJECT_NAME_INVALID;
3567 /* Disallow if newname already exists. */
3568 if (VALID_STAT(sbuf2)) {
3569 return NT_STATUS_OBJECT_NAME_COLLISION;
3572 if (!check_name(newname,conn)) {
3573 return NT_STATUS_ACCESS_DENIED;
3576 /* No links from a directory. */
3577 if (S_ISDIR(sbuf1.st_mode)) {
3578 return NT_STATUS_FILE_IS_A_DIRECTORY;
3581 /* Ensure this is within the share. */
3582 if (!reduce_name(conn, oldname) != 0)
3583 return NT_STATUS_ACCESS_DENIED;
3585 DEBUG(10,("hardlink_internals: doing hard link %s -> %s\n", newname, oldname ));
3587 if (SMB_VFS_LINK(conn,oldname,newname) != 0) {
3588 status = map_nt_error_from_unix(errno);
3589 DEBUG(3,("hardlink_internals: Error %s hard link %s -> %s\n",
3590 nt_errstr(status), newname, oldname));
3596 /****************************************************************************
3597 Reply to a TRANS2_SETFILEINFO (set file info by fileid).
3598 ****************************************************************************/
3600 static int call_trans2setfilepathinfo(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize,
3601 unsigned int tran_call,
3602 char **pparams, int total_params, char **ppdata, int total_data,
3603 unsigned int max_data_bytes)
3605 char *params = *pparams;
3606 char *pdata = *ppdata;
3611 SMB_STRUCT_STAT sbuf;
3614 BOOL bad_path = False;
3615 files_struct *fsp = NULL;
3616 uid_t set_owner = (uid_t)SMB_UID_NO_CHANGE;
3617 gid_t set_grp = (uid_t)SMB_GID_NO_CHANGE;
3618 mode_t unixmode = 0;
3619 NTSTATUS status = NT_STATUS_OK;
3622 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
3627 if (tran_call == TRANSACT2_SETFILEINFO) {
3628 if (total_params < 4) {
3629 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
3632 fsp = file_fsp(params,0);
3633 info_level = SVAL(params,2);
3635 if(fsp && (fsp->is_directory || fsp->fd == -1)) {
3637 * This is actually a SETFILEINFO on a directory
3638 * handle (returned from an NT SMB). NT5.0 seems
3639 * to do this call. JRA.
3641 pstrcpy(fname, fsp->fsp_name);
3642 if (SMB_VFS_STAT(conn,fname,&sbuf) != 0) {
3643 DEBUG(3,("call_trans2setfilepathinfo: fileinfo of %s failed (%s)\n",fname,strerror(errno)));
3644 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRbadpath);
3646 } else if (fsp && fsp->print_file) {
3648 * Doing a DELETE_ON_CLOSE should cancel a print job.
3650 if ((info_level == SMB_SET_FILE_DISPOSITION_INFO) && CVAL(pdata,0)) {
3651 fsp->share_mode = FILE_DELETE_ON_CLOSE;
3653 DEBUG(3,("call_trans2setfilepathinfo: Cancelling print job (%s)\n", fsp->fsp_name ));
3656 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
3659 return (UNIXERROR(ERRDOS,ERRbadpath));
3662 * Original code - this is an open file.
3664 CHECK_FSP(fsp,conn);
3666 pstrcpy(fname, fsp->fsp_name);
3669 if (SMB_VFS_FSTAT(fsp,fd,&sbuf) != 0) {
3670 DEBUG(3,("call_trans2setfilepathinfo: fstat of fnum %d failed (%s)\n",fsp->fnum, strerror(errno)));
3671 return(UNIXERROR(ERRDOS,ERRbadfid));
3676 if (total_params < 6) {
3677 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
3680 info_level = SVAL(params,0);
3681 srvstr_get_path(inbuf, fname, ¶ms[6], sizeof(fname), -1, STR_TERMINATE, &status, False);
3682 if (!NT_STATUS_IS_OK(status)) {
3683 return ERROR_NT(status);
3685 unix_convert(fname,conn,0,&bad_path,&sbuf);
3687 return ERROR_NT(NT_STATUS_OBJECT_PATH_NOT_FOUND);
3691 * For CIFS UNIX extensions the target name may not exist.
3694 if(!VALID_STAT(sbuf) && !INFO_LEVEL_IS_UNIX(info_level)) {
3695 DEBUG(3,("call_trans2setfilepathinfo: stat of %s failed (%s)\n", fname, strerror(errno)));
3696 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRbadpath);
3699 if(!check_name(fname, conn)) {
3700 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRbadpath);
3705 if (!CAN_WRITE(conn))
3706 return ERROR_DOS(ERRSRV,ERRaccess);
3708 if (INFO_LEVEL_IS_UNIX(info_level) && !lp_unix_extensions())
3709 return ERROR_DOS(ERRDOS,ERRunknownlevel);
3711 if (VALID_STAT(sbuf))
3712 unixmode = sbuf.st_mode;
3714 DEBUG(3,("call_trans2setfilepathinfo(%d) %s (fnum %d) info_level=%d totdata=%d\n",
3715 tran_call,fname, fsp ? fsp->fnum : -1, info_level,total_data));
3717 /* Realloc the parameter size */
3718 params = SMB_REALLOC(*pparams,2);
3719 if(params == NULL) {
3720 return ERROR_NT(NT_STATUS_NO_MEMORY);
3726 if (fsp && fsp->pending_modtime) {
3727 /* the pending modtime overrides the current modtime */
3728 sbuf.st_mtime = fsp->pending_modtime;
3731 size = get_file_size(sbuf);
3732 tvs.modtime = sbuf.st_mtime;
3733 tvs.actime = sbuf.st_atime;
3734 dosmode = dos_mode(conn,fname,&sbuf);
3735 unixmode = sbuf.st_mode;
3737 set_owner = VALID_STAT(sbuf) ? sbuf.st_uid : (uid_t)SMB_UID_NO_CHANGE;
3738 set_grp = VALID_STAT(sbuf) ? sbuf.st_gid : (gid_t)SMB_GID_NO_CHANGE;
3740 switch (info_level) {
3741 case SMB_INFO_STANDARD:
3743 if (total_data < 12) {
3744 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
3748 tvs.actime = make_unix_date2(pdata+l1_fdateLastAccess);
3750 tvs.modtime = make_unix_date2(pdata+l1_fdateLastWrite);
3754 case SMB_INFO_SET_EA:
3756 struct ea_list *ea_list = NULL;
3757 TALLOC_CTX *ctx = NULL;
3759 if (total_data < 10) {
3760 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
3763 if (IVAL(pdata,0) > total_data) {
3764 DEBUG(10,("call_trans2setfilepathinfo: bad total data size (%u) > %u\n",
3765 IVAL(pdata,0), (unsigned int)total_data));
3766 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
3769 ctx = talloc_init("SMB_INFO_SET_EA");
3771 return ERROR_NT(NT_STATUS_NO_MEMORY);
3773 ea_list = read_ea_list(ctx, pdata + 4, total_data - 4);
3775 talloc_destroy(ctx);
3776 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
3778 status = set_ea(conn, fsp, fname, ea_list);
3779 talloc_destroy(ctx);
3781 if (!NT_STATUS_IS_OK(status)) {
3782 return ERROR_NT(status);
3785 /* We're done. We only get EA info in this call. */
3787 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
3792 /* The following 2 info levels are only valid on query, not set. Remove them. JRA. */
3793 /* XXXX um, i don't think this is right.
3794 it's also not in the cifs6.txt spec.
3796 case SMB_INFO_QUERY_EAS_FROM_LIST:
3797 if (total_data < 28)
3798 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
3800 tvs.actime = make_unix_date2(pdata+8);
3801 tvs.modtime = make_unix_date2(pdata+12);
3802 size = IVAL(pdata,16);
3803 dosmode = IVAL(pdata,24);
3806 /* XXXX nor this. not in cifs6.txt, either. */
3807 case SMB_INFO_QUERY_ALL_EAS:
3808 if (total_data < 28)
3809 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
3811 tvs.actime = make_unix_date2(pdata+8);
3812 tvs.modtime = make_unix_date2(pdata+12);
3813 size = IVAL(pdata,16);
3814 dosmode = IVAL(pdata,24);
3818 case SMB_SET_FILE_BASIC_INFO:
3819 case SMB_FILE_BASIC_INFORMATION:
3821 /* Patch to do this correctly from Paul Eggert <eggert@twinsun.com>. */
3823 time_t changed_time;
3825 if (total_data < 36) {
3826 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
3829 /* Ignore create time at offset pdata. */
3832 tvs.actime = interpret_long_date(pdata+8);
3834 write_time = interpret_long_date(pdata+16);
3835 changed_time = interpret_long_date(pdata+24);
3837 tvs.modtime = MIN(write_time, changed_time);
3839 if (write_time > tvs.modtime && write_time != (time_t)-1) {
3840 tvs.modtime = write_time;
3842 /* Prefer a defined time to an undefined one. */
3843 if (null_mtime(tvs.modtime)) {
3844 tvs.modtime = null_mtime(write_time) ? changed_time : write_time;
3848 dosmode = IVAL(pdata,32);
3852 case SMB_FILE_ALLOCATION_INFORMATION:
3853 case SMB_SET_FILE_ALLOCATION_INFO:
3856 SMB_BIG_UINT allocation_size;
3858 if (total_data < 8) {
3859 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
3862 allocation_size = (SMB_BIG_UINT)IVAL(pdata,0);
3863 #ifdef LARGE_SMB_OFF_T
3864 allocation_size |= (((SMB_BIG_UINT)IVAL(pdata,4)) << 32);
3865 #else /* LARGE_SMB_OFF_T */
3866 if (IVAL(pdata,4) != 0) /* more than 32 bits? */
3867 return ERROR_DOS(ERRDOS,ERRunknownlevel);
3868 #endif /* LARGE_SMB_OFF_T */
3869 DEBUG(10,("call_trans2setfilepathinfo: Set file allocation info for file %s to %.0f\n",
3870 fname, (double)allocation_size ));
3872 if (allocation_size) {
3873 allocation_size = smb_roundup(conn, allocation_size);
3876 if(allocation_size != get_file_size(sbuf)) {
3877 SMB_STRUCT_STAT new_sbuf;
3879 DEBUG(10,("call_trans2setfilepathinfo: file %s : setting new allocation size to %.0f\n",
3880 fname, (double)allocation_size ));
3883 files_struct *new_fsp = NULL;
3884 int access_mode = 0;
3887 if(global_oplock_break) {
3888 /* Queue this file modify as we are the process of an oplock break. */
3890 DEBUG(2,("call_trans2setfilepathinfo: queueing message due to being "));
3891 DEBUGADD(2,( "in oplock break state.\n"));
3893 push_oplock_pending_smb_message(inbuf, length);
3897 new_fsp = open_file_shared1(conn, fname, &sbuf,FILE_WRITE_DATA,
3898 SET_OPEN_MODE(DOS_OPEN_RDWR),
3899 (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN),
3900 FILE_ATTRIBUTE_NORMAL,
3901 INTERNAL_OPEN_ONLY, &access_mode, &action);
3903 if (new_fsp == NULL)
3904 return(UNIXERROR(ERRDOS,ERRbadpath));
3905 ret = vfs_allocate_file_space(new_fsp, allocation_size);
3906 if (SMB_VFS_FSTAT(new_fsp,new_fsp->fd,&new_sbuf) != 0) {
3907 DEBUG(3,("call_trans2setfilepathinfo: fstat of fnum %d failed (%s)\n",
3908 new_fsp->fnum, strerror(errno)));
3911 close_file(new_fsp,True);
3913 ret = vfs_allocate_file_space(fsp, allocation_size);
3914 if (SMB_VFS_FSTAT(fsp,fd,&new_sbuf) != 0) {
3915 DEBUG(3,("call_trans2setfilepathinfo: fstat of fnum %d failed (%s)\n",
3916 fsp->fnum, strerror(errno)));
3921 return ERROR_NT(NT_STATUS_DISK_FULL);
3923 /* Allocate can truncate size... */
3924 size = get_file_size(new_sbuf);
3930 case SMB_FILE_END_OF_FILE_INFORMATION:
3931 case SMB_SET_FILE_END_OF_FILE_INFO:
3933 if (total_data < 8) {
3934 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
3937 size = IVAL(pdata,0);
3938 #ifdef LARGE_SMB_OFF_T
3939 size |= (((SMB_OFF_T)IVAL(pdata,4)) << 32);
3940 #else /* LARGE_SMB_OFF_T */
3941 if (IVAL(pdata,4) != 0) /* more than 32 bits? */
3942 return ERROR_DOS(ERRDOS,ERRunknownlevel);
3943 #endif /* LARGE_SMB_OFF_T */
3944 DEBUG(10,("call_trans2setfilepathinfo: Set end of file info for file %s to %.0f\n", fname, (double)size ));
3948 case SMB_FILE_DISPOSITION_INFORMATION:
3949 case SMB_SET_FILE_DISPOSITION_INFO: /* Set delete on close for open file. */
3951 BOOL delete_on_close;
3953 if (total_data < 1) {
3954 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
3957 delete_on_close = (CVAL(pdata,0) ? True : False);
3959 /* Just ignore this set on a path. */
3960 if (tran_call != TRANSACT2_SETFILEINFO)
3964 return(UNIXERROR(ERRDOS,ERRbadfid));
3966 status = set_delete_on_close_internal(fsp, delete_on_close, dosmode);
3968 if (!NT_STATUS_IS_OK(status)) {
3969 return ERROR_NT(status);
3972 /* The set is across all open files on this dev/inode pair. */
3973 status =set_delete_on_close_over_all(fsp, delete_on_close);
3974 if (!NT_STATUS_IS_OK(status)) {
3975 return ERROR_NT(status);
3979 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
3983 case SMB_FILE_POSITION_INFORMATION:
3985 SMB_BIG_UINT position_information;
3987 if (total_data < 8) {
3988 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
3991 position_information = (SMB_BIG_UINT)IVAL(pdata,0);
3992 #ifdef LARGE_SMB_OFF_T
3993 position_information |= (((SMB_BIG_UINT)IVAL(pdata,4)) << 32);
3994 #else /* LARGE_SMB_OFF_T */
3995 if (IVAL(pdata,4) != 0) /* more than 32 bits? */
3996 return ERROR_DOS(ERRDOS,ERRunknownlevel);
3997 #endif /* LARGE_SMB_OFF_T */
3998 DEBUG(10,("call_trans2setfilepathinfo: Set file position information for file %s to %.0f\n",
3999 fname, (double)position_information ));
4001 fsp->position_information = position_information;
4004 /* We're done. We only get position info in this call. */
4006 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
4010 /* From tridge Samba4 :
4011 * MODE_INFORMATION in setfileinfo (I have no
4012 * idea what "mode information" on a file is - it takes a value of 0,
4013 * 2, 4 or 6. What could it be?).
4016 case SMB_FILE_MODE_INFORMATION:
4020 if (total_data < 4) {
4021 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
4023 mode = IVAL(pdata,0);
4024 if (mode != 0 && mode != 2 && mode != 4 && mode != 6) {
4025 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
4028 /* We're done. We only get mode info in this call. */
4030 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
4035 * CIFS UNIX extensions.
4038 case SMB_SET_FILE_UNIX_BASIC:
4040 uint32 raw_unixmode;
4042 if (total_data < 100) {
4043 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
4046 if(IVAL(pdata, 0) != SMB_SIZE_NO_CHANGE_LO &&
4047 IVAL(pdata, 4) != SMB_SIZE_NO_CHANGE_HI) {
4048 size=IVAL(pdata,0); /* first 8 Bytes are size */
4049 #ifdef LARGE_SMB_OFF_T
4050 size |= (((SMB_OFF_T)IVAL(pdata,4)) << 32);
4051 #else /* LARGE_SMB_OFF_T */
4052 if (IVAL(pdata,4) != 0) /* more than 32 bits? */
4053 return ERROR_DOS(ERRDOS,ERRunknownlevel);
4054 #endif /* LARGE_SMB_OFF_T */
4056 pdata+=24; /* ctime & st_blocks are not changed */
4057 tvs.actime = interpret_long_date(pdata); /* access_time */
4058 tvs.modtime = interpret_long_date(pdata+8); /* modification_time */
4060 set_owner = (uid_t)IVAL(pdata,0);
4062 set_grp = (gid_t)IVAL(pdata,0);
4064 raw_unixmode = IVAL(pdata,28);
4065 unixmode = unix_perms_from_wire(conn, &sbuf, raw_unixmode);
4066 dosmode = 0; /* Ensure dos mode change doesn't override this. */
4068 DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_BASIC: name = %s \
4069 size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n",
4070 fname, (double)size, (unsigned int)set_owner, (unsigned int)set_grp, (int)raw_unixmode));
4072 if (!VALID_STAT(sbuf)) {
4075 * The only valid use of this is to create character and block
4076 * devices, and named pipes. This is deprecated (IMHO) and
4077 * a new info level should be used for mknod. JRA.
4080 uint32 file_type = IVAL(pdata,0);
4081 #if defined(HAVE_MAKEDEV)
4082 uint32 dev_major = IVAL(pdata,4);
4083 uint32 dev_minor = IVAL(pdata,12);
4086 uid_t myuid = geteuid();
4087 gid_t mygid = getegid();
4088 SMB_DEV_T dev = (SMB_DEV_T)0;
4090 if (tran_call == TRANSACT2_SETFILEINFO)
4091 return(ERROR_DOS(ERRDOS,ERRnoaccess));
4093 if (raw_unixmode == SMB_MODE_NO_CHANGE) {
4094 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
4097 #if defined(HAVE_MAKEDEV)
4098 dev = makedev(dev_major, dev_minor);
4101 /* We can only create as the owner/group we are. */
4103 if ((set_owner != myuid) && (set_owner != (uid_t)SMB_UID_NO_CHANGE))
4104 return(ERROR_DOS(ERRDOS,ERRnoaccess));
4105 if ((set_grp != mygid) && (set_grp != (gid_t)SMB_GID_NO_CHANGE))
4106 return(ERROR_DOS(ERRDOS,ERRnoaccess));
4108 switch (file_type) {
4109 #if defined(S_IFIFO)
4110 case UNIX_TYPE_FIFO:
4111 unixmode |= S_IFIFO;
4114 #if defined(S_IFSOCK)
4115 case UNIX_TYPE_SOCKET:
4116 unixmode |= S_IFSOCK;
4119 #if defined(S_IFCHR)
4120 case UNIX_TYPE_CHARDEV:
4121 unixmode |= S_IFCHR;
4124 #if defined(S_IFBLK)
4125 case UNIX_TYPE_BLKDEV:
4126 unixmode |= S_IFBLK;
4130 return(ERROR_DOS(ERRDOS,ERRnoaccess));
4133 DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_BASIC doing mknod dev %.0f mode \
4134 0%o for file %s\n", (double)dev, unixmode, fname ));
4136 /* Ok - do the mknod. */
4137 if (SMB_VFS_MKNOD(conn,fname, unixmode, dev) != 0)
4138 return(UNIXERROR(ERRDOS,ERRnoaccess));
4140 inherit_access_acl(conn, fname, unixmode);
4143 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
4148 * Deal with the UNIX specific mode set.
4151 if (raw_unixmode != SMB_MODE_NO_CHANGE) {
4152 DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_BASIC setting mode 0%o for file %s\n",
4153 (unsigned int)unixmode, fname ));
4154 if (SMB_VFS_CHMOD(conn,fname,unixmode) != 0)
4155 return(UNIXERROR(ERRDOS,ERRnoaccess));
4159 * Deal with the UNIX specific uid set.
4162 if ((set_owner != (uid_t)SMB_UID_NO_CHANGE) && (sbuf.st_uid != set_owner)) {
4163 DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_BASIC changing owner %u for file %s\n",
4164 (unsigned int)set_owner, fname ));
4165 if (SMB_VFS_CHOWN(conn,fname,set_owner, (gid_t)-1) != 0)
4166 return(UNIXERROR(ERRDOS,ERRnoaccess));
4170 * Deal with the UNIX specific gid set.
4173 if ((set_grp != (uid_t)SMB_GID_NO_CHANGE) && (sbuf.st_gid != set_grp)) {
4174 DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_BASIC changing group %u for file %s\n",
4175 (unsigned int)set_owner, fname ));
4176 if (SMB_VFS_CHOWN(conn,fname,(uid_t)-1, set_grp) != 0)
4177 return(UNIXERROR(ERRDOS,ERRnoaccess));
4182 case SMB_SET_FILE_UNIX_LINK:
4184 pstring link_target;
4185 char *newname = fname;
4187 /* Set a symbolic link. */
4188 /* Don't allow this if follow links is false. */
4190 if (!lp_symlinks(SNUM(conn)))
4191 return(ERROR_DOS(ERRDOS,ERRnoaccess));
4193 srvstr_pull(inbuf, link_target, pdata, sizeof(link_target), -1, STR_TERMINATE);
4195 /* !widelinks forces the target path to be within the share. */
4196 /* This means we can interpret the target as a pathname. */
4197 if (!lp_widelinks(SNUM(conn))) {
4199 char *last_dirp = NULL;
4201 unix_format(link_target);
4202 if (*link_target == '/') {
4203 /* No absolute paths allowed. */
4204 return(UNIXERROR(ERRDOS,ERRnoaccess));
4206 pstrcpy(rel_name, newname);
4207 last_dirp = strrchr_m(rel_name, '/');
4209 last_dirp[1] = '\0';
4211 pstrcpy(rel_name, "./");
4213 pstrcat(rel_name, link_target);
4215 if (!check_name(rel_name, conn)) {
4216 return(UNIXERROR(ERRDOS,ERRnoaccess));
4220 DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_LINK doing symlink %s -> %s\n",
4221 fname, link_target ));
4223 if (SMB_VFS_SYMLINK(conn,link_target,newname) != 0)
4224 return(UNIXERROR(ERRDOS,ERRnoaccess));
4226 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
4230 case SMB_SET_FILE_UNIX_HLINK:
4233 char *newname = fname;
4235 /* Set a hard link. */
4236 srvstr_get_path(inbuf, oldname, pdata, sizeof(oldname), -1, STR_TERMINATE, &status, False);
4237 if (!NT_STATUS_IS_OK(status)) {
4238 return ERROR_NT(status);
4241 DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_LINK doing hard link %s -> %s\n",
4244 status = hardlink_internals(conn, oldname, newname);
4245 if (!NT_STATUS_IS_OK(status)) {
4246 return ERROR_NT(status);
4250 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
4254 case SMB_FILE_RENAME_INFORMATION:
4263 if (total_data < 12) {
4264 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
4267 overwrite = (CVAL(pdata,0) ? True : False);
4268 root_fid = IVAL(pdata,4);
4269 len = IVAL(pdata,8);
4270 srvstr_get_path(inbuf, newname, &pdata[12], sizeof(newname), len, 0, &status, False);
4271 if (!NT_STATUS_IS_OK(status)) {
4272 return ERROR_NT(status);
4275 /* Check the new name has no '/' characters. */
4276 if (strchr_m(newname, '/'))
4277 return ERROR_NT(NT_STATUS_NOT_SUPPORTED);
4279 RESOLVE_DFSPATH(newname, conn, inbuf, outbuf);
4281 /* Create the base directory. */
4282 pstrcpy(base_name, fname);
4283 p = strrchr_m(base_name, '/');
4286 /* Append the new name. */
4287 pstrcat(base_name, "/");
4288 pstrcat(base_name, newname);
4291 DEBUG(10,("call_trans2setfilepathinfo: SMB_FILE_RENAME_INFORMATION (fnum %d) %s -> %s\n",
4292 fsp->fnum, fsp->fsp_name, base_name ));
4293 status = rename_internals_fsp(conn, fsp, base_name, 0, overwrite);
4295 DEBUG(10,("call_trans2setfilepathinfo: SMB_FILE_RENAME_INFORMATION %s -> %s\n",
4297 status = rename_internals(conn, fname, base_name, 0, overwrite);
4299 if (!NT_STATUS_IS_OK(status)) {
4300 return ERROR_NT(status);
4302 process_pending_change_notify_queue((time_t)0);
4304 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
4308 #if defined(HAVE_POSIX_ACLS)
4309 case SMB_SET_POSIX_ACL:
4311 uint16 posix_acl_version;
4312 uint16 num_file_acls;
4313 uint16 num_def_acls;
4314 BOOL valid_file_acls = True;
4315 BOOL valid_def_acls = True;
4317 if (total_data < SMB_POSIX_ACL_HEADER_SIZE) {
4318 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
4320 posix_acl_version = SVAL(pdata,0);
4321 num_file_acls = SVAL(pdata,2);
4322 num_def_acls = SVAL(pdata,4);
4324 if (num_file_acls == SMB_POSIX_IGNORE_ACE_ENTRIES) {
4325 valid_file_acls = False;
4329 if (num_def_acls == SMB_POSIX_IGNORE_ACE_ENTRIES) {
4330 valid_def_acls = False;
4334 if (posix_acl_version != SMB_POSIX_ACL_VERSION) {
4335 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
4338 if (total_data < SMB_POSIX_ACL_HEADER_SIZE +
4339 (num_file_acls+num_def_acls)*SMB_POSIX_ACL_ENTRY_SIZE) {
4340 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
4343 if (valid_file_acls && !set_unix_posix_acl(conn, fsp, fname, num_file_acls,
4344 pdata + SMB_POSIX_ACL_HEADER_SIZE)) {
4345 return(UNIXERROR(ERRDOS,ERRnoaccess));
4348 if (valid_def_acls && !set_unix_posix_default_acl(conn, fname, &sbuf, num_def_acls,
4349 pdata + SMB_POSIX_ACL_HEADER_SIZE +
4350 (num_file_acls*SMB_POSIX_ACL_ENTRY_SIZE))) {
4351 return(UNIXERROR(ERRDOS,ERRnoaccess));
4355 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
4361 return ERROR_DOS(ERRDOS,ERRunknownlevel);
4364 /* get some defaults (no modifications) if any info is zero or -1. */
4365 if (null_mtime(tvs.actime)) {
4366 tvs.actime = sbuf.st_atime;
4369 if (null_mtime(tvs.modtime)) {
4370 tvs.modtime = sbuf.st_mtime;
4373 DEBUG(6,("actime: %s " , ctime(&tvs.actime)));
4374 DEBUG(6,("modtime: %s ", ctime(&tvs.modtime)));
4375 DEBUG(6,("size: %.0f ", (double)size));
4378 if (S_ISDIR(sbuf.st_mode))
4384 DEBUG(6,("dosmode: %x\n" , dosmode));
4386 if(!((info_level == SMB_SET_FILE_END_OF_FILE_INFO) ||
4387 (info_level == SMB_SET_FILE_ALLOCATION_INFO) ||
4388 (info_level == SMB_FILE_ALLOCATION_INFORMATION) ||
4389 (info_level == SMB_FILE_END_OF_FILE_INFORMATION))) {
4392 * Only do this test if we are not explicitly
4393 * changing the size of a file.
4396 size = get_file_size(sbuf);
4400 * Try and set the times, size and mode of this file -
4401 * if they are different from the current values
4404 /* check the mode isn't different, before changing it */
4405 if ((dosmode != 0) && (dosmode != dos_mode(conn, fname, &sbuf))) {
4407 DEBUG(10,("call_trans2setfilepathinfo: file %s : setting dos mode %x\n", fname, dosmode ));
4409 if(file_set_dosmode(conn, fname, dosmode, &sbuf, False)) {
4410 DEBUG(2,("file_set_dosmode of %s failed (%s)\n", fname, strerror(errno)));
4411 return(UNIXERROR(ERRDOS,ERRnoaccess));
4416 if (size != get_file_size(sbuf)) {
4420 DEBUG(10,("call_trans2setfilepathinfo: file %s : setting new size to %.0f\n",
4421 fname, (double)size ));
4424 files_struct *new_fsp = NULL;
4425 int access_mode = 0;
4428 if(global_oplock_break) {
4429 /* Queue this file modify as we are the process of an oplock break. */
4431 DEBUG(2,("call_trans2setfilepathinfo: queueing message due to being "));
4432 DEBUGADD(2,( "in oplock break state.\n"));
4434 push_oplock_pending_smb_message(inbuf, length);
4438 new_fsp = open_file_shared(conn, fname, &sbuf,
4439 SET_OPEN_MODE(DOS_OPEN_RDWR),
4440 (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN),
4441 FILE_ATTRIBUTE_NORMAL,
4442 INTERNAL_OPEN_ONLY, &access_mode, &action);
4444 if (new_fsp == NULL)
4445 return(UNIXERROR(ERRDOS,ERRbadpath));
4446 ret = vfs_set_filelen(new_fsp, size);
4447 close_file(new_fsp,True);
4449 ret = vfs_set_filelen(fsp, size);
4453 return (UNIXERROR(ERRHRD,ERRdiskfull));
4457 * Finally the times.
4459 if (sbuf.st_mtime != tvs.modtime || sbuf.st_atime != tvs.actime) {
4462 * This was a setfileinfo on an open file.
4463 * NT does this a lot. We also need to
4464 * set the time here, as it can be read by
4465 * FindFirst/FindNext and with the patch for bug #2045
4466 * in smbd/fileio.c it ensures that this timestamp is
4467 * kept sticky even after a write. We save the request
4468 * away and will set it on file close and after a write. JRA.
4471 if (tvs.modtime != (time_t)0 && tvs.modtime != (time_t)-1) {
4472 DEBUG(10,("call_trans2setfilepathinfo: setting pending modtime to %s\n", ctime(&tvs.modtime) ));
4473 fsp_set_pending_modtime(fsp, tvs.modtime);
4477 DEBUG(10,("call_trans2setfilepathinfo: setting utimes to modified values.\n"));
4479 if(file_utime(conn, fname, &tvs)!=0) {
4480 return(UNIXERROR(ERRDOS,ERRnoaccess));
4485 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
4490 /****************************************************************************
4491 Reply to a TRANS2_MKDIR (make directory with extended attributes).
4492 ****************************************************************************/
4494 static int call_trans2mkdir(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize,
4495 char **pparams, int total_params, char **ppdata, int total_data,
4496 unsigned int max_data_bytes)
4498 char *params = *pparams;
4499 char *pdata = *ppdata;
4502 SMB_STRUCT_STAT sbuf;
4503 BOOL bad_path = False;
4504 NTSTATUS status = NT_STATUS_OK;
4505 TALLOC_CTX *ctx = NULL;
4506 struct ea_list *ea_list = NULL;
4508 if (!CAN_WRITE(conn))
4509 return ERROR_DOS(ERRSRV,ERRaccess);
4511 if (total_params < 4) {
4512 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
4515 srvstr_get_path(inbuf, directory, ¶ms[4], sizeof(directory), -1, STR_TERMINATE, &status, False);
4516 if (!NT_STATUS_IS_OK(status)) {
4517 return ERROR_NT(status);
4520 DEBUG(3,("call_trans2mkdir : name = %s\n", directory));
4522 unix_convert(directory,conn,0,&bad_path,&sbuf);
4524 return ERROR_NT(NT_STATUS_OBJECT_PATH_NOT_FOUND);
4527 /* Any data in this call is an EA list. */
4528 if (total_data && !lp_ea_support(SNUM(conn))) {
4529 return ERROR_NT(NT_STATUS_EAS_NOT_SUPPORTED);
4533 if (total_data < 10) {
4534 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
4537 if (IVAL(pdata,0) > total_data) {
4538 DEBUG(10,("call_trans2mkdir: bad total data size (%u) > %u\n",
4539 IVAL(pdata,0), (unsigned int)total_data));
4540 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
4543 ctx = talloc_init("TRANS2_MKDIR_SET_EA");
4545 return ERROR_NT(NT_STATUS_NO_MEMORY);
4547 ea_list = read_ea_list(ctx, pdata + 4, total_data - 4);
4549 talloc_destroy(ctx);
4550 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
4554 if (check_name(directory,conn)) {
4555 ret = vfs_MkDir(conn,directory,unix_mode(conn,aDIR,directory,True));
4559 talloc_destroy(ctx);
4560 DEBUG(5,("call_trans2mkdir error (%s)\n", strerror(errno)));
4561 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRnoaccess);
4564 /* Try and set any given EA. */
4566 status = set_ea(conn, NULL, directory, ea_list);
4567 talloc_destroy(ctx);
4568 if (!NT_STATUS_IS_OK(status)) {
4569 return ERROR_NT(status);
4573 /* Realloc the parameter and data sizes */
4574 params = SMB_REALLOC(*pparams,2);
4575 if(params == NULL) {
4576 return ERROR_NT(NT_STATUS_NO_MEMORY);
4582 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
4587 /****************************************************************************
4588 Reply to a TRANS2_FINDNOTIFYFIRST (start monitoring a directory for changes).
4589 We don't actually do this - we just send a null response.
4590 ****************************************************************************/
4592 static int call_trans2findnotifyfirst(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize,
4593 char **pparams, int total_params, char **ppdata, int total_data,
4594 unsigned int max_data_bytes)
4596 static uint16 fnf_handle = 257;
4597 char *params = *pparams;
4600 if (total_params < 6) {
4601 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
4604 info_level = SVAL(params,4);
4605 DEBUG(3,("call_trans2findnotifyfirst - info_level %d\n", info_level));
4607 switch (info_level) {
4612 return ERROR_DOS(ERRDOS,ERRunknownlevel);
4615 /* Realloc the parameter and data sizes */
4616 params = SMB_REALLOC(*pparams,6);
4617 if(params == NULL) {
4618 return ERROR_NT(NT_STATUS_NO_MEMORY);
4622 SSVAL(params,0,fnf_handle);
4623 SSVAL(params,2,0); /* No changes */
4624 SSVAL(params,4,0); /* No EA errors */
4631 send_trans2_replies(outbuf, bufsize, params, 6, *ppdata, 0);
4636 /****************************************************************************
4637 Reply to a TRANS2_FINDNOTIFYNEXT (continue monitoring a directory for
4638 changes). Currently this does nothing.
4639 ****************************************************************************/
4641 static int call_trans2findnotifynext(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize,
4642 char **pparams, int total_params, char **ppdata, int total_data,
4643 unsigned int max_data_bytes)
4645 char *params = *pparams;
4647 DEBUG(3,("call_trans2findnotifynext\n"));
4649 /* Realloc the parameter and data sizes */
4650 params = SMB_REALLOC(*pparams,4);
4651 if(params == NULL) {
4652 return ERROR_NT(NT_STATUS_NO_MEMORY);
4656 SSVAL(params,0,0); /* No changes */
4657 SSVAL(params,2,0); /* No EA errors */
4659 send_trans2_replies(outbuf, bufsize, params, 4, *ppdata, 0);
4664 /****************************************************************************
4665 Reply to a TRANS2_GET_DFS_REFERRAL - Shirish Kalele <kalele@veritas.com>.
4666 ****************************************************************************/
4668 static int call_trans2getdfsreferral(connection_struct *conn, char* inbuf, char* outbuf, int length, int bufsize,
4669 char **pparams, int total_params, char **ppdata, int total_data,
4670 unsigned int max_data_bytes)
4672 char *params = *pparams;
4675 int max_referral_level;
4677 DEBUG(10,("call_trans2getdfsreferral\n"));
4679 if (total_params < 2) {
4680 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
4683 max_referral_level = SVAL(params,0);
4685 if(!lp_host_msdfs())
4686 return ERROR_DOS(ERRDOS,ERRbadfunc);
4688 srvstr_pull(inbuf, pathname, ¶ms[2], sizeof(pathname), -1, STR_TERMINATE);
4689 if((reply_size = setup_dfs_referral(conn, pathname,max_referral_level,ppdata)) < 0)
4690 return UNIXERROR(ERRDOS,ERRbadfile);
4692 SSVAL(outbuf,smb_flg2,SVAL(outbuf,smb_flg2) | FLAGS2_DFS_PATHNAMES);
4693 send_trans2_replies(outbuf,bufsize,0,0,*ppdata,reply_size);
4698 #define LMCAT_SPL 0x53
4699 #define LMFUNC_GETJOBID 0x60
4701 /****************************************************************************
4702 Reply to a TRANS2_IOCTL - used for OS/2 printing.
4703 ****************************************************************************/
4705 static int call_trans2ioctl(connection_struct *conn, char* inbuf, char* outbuf, int length, int bufsize,
4706 char **pparams, int total_params, char **ppdata, int total_data,
4707 unsigned int max_data_bytes)
4709 char *pdata = *ppdata;
4710 files_struct *fsp = file_fsp(inbuf,smb_vwv15);
4712 /* check for an invalid fid before proceeding */
4715 return(ERROR_DOS(ERRDOS,ERRbadfid));
4717 if ((SVAL(inbuf,(smb_setup+4)) == LMCAT_SPL) &&
4718 (SVAL(inbuf,(smb_setup+6)) == LMFUNC_GETJOBID)) {
4719 pdata = SMB_REALLOC(*ppdata, 32);
4721 return ERROR_NT(NT_STATUS_NO_MEMORY);
4725 /* NOTE - THIS IS ASCII ONLY AT THE MOMENT - NOT SURE IF OS/2
4726 CAN ACCEPT THIS IN UNICODE. JRA. */
4728 SSVAL(pdata,0,fsp->rap_print_jobid); /* Job number */
4729 srvstr_push( outbuf, pdata + 2, global_myname(), 15, STR_ASCII|STR_TERMINATE); /* Our NetBIOS name */
4730 srvstr_push( outbuf, pdata+18, lp_servicename(SNUM(conn)), 13, STR_ASCII|STR_TERMINATE); /* Service name */
4731 send_trans2_replies(outbuf,bufsize,*pparams,0,*ppdata,32);
4734 DEBUG(2,("Unknown TRANS2_IOCTL\n"));
4735 return ERROR_DOS(ERRSRV,ERRerror);
4739 /****************************************************************************
4740 Reply to a SMBfindclose (stop trans2 directory search).
4741 ****************************************************************************/
4743 int reply_findclose(connection_struct *conn,
4744 char *inbuf,char *outbuf,int length,int bufsize)
4747 int dptr_num=SVALS(inbuf,smb_vwv0);
4748 START_PROFILE(SMBfindclose);
4750 DEBUG(3,("reply_findclose, dptr_num = %d\n", dptr_num));
4752 dptr_close(&dptr_num);
4754 outsize = set_message(outbuf,0,0,True);
4756 DEBUG(3,("SMBfindclose dptr_num = %d\n", dptr_num));
4758 END_PROFILE(SMBfindclose);
4762 /****************************************************************************
4763 Reply to a SMBfindnclose (stop FINDNOTIFYFIRST directory search).
4764 ****************************************************************************/
4766 int reply_findnclose(connection_struct *conn,
4767 char *inbuf,char *outbuf,int length,int bufsize)
4771 START_PROFILE(SMBfindnclose);
4773 dptr_num = SVAL(inbuf,smb_vwv0);
4775 DEBUG(3,("reply_findnclose, dptr_num = %d\n", dptr_num));
4777 /* We never give out valid handles for a
4778 findnotifyfirst - so any dptr_num is ok here.
4781 outsize = set_message(outbuf,0,0,True);
4783 DEBUG(3,("SMB_findnclose dptr_num = %d\n", dptr_num));
4785 END_PROFILE(SMBfindnclose);
4789 /****************************************************************************
4790 Reply to a SMBtranss2 - just ignore it!
4791 ****************************************************************************/
4793 int reply_transs2(connection_struct *conn,
4794 char *inbuf,char *outbuf,int length,int bufsize)
4796 START_PROFILE(SMBtranss2);
4797 DEBUG(4,("Ignoring transs2 of length %d\n",length));
4798 END_PROFILE(SMBtranss2);
4802 /****************************************************************************
4803 Reply to a SMBtrans2.
4804 ****************************************************************************/
4806 int reply_trans2(connection_struct *conn,
4807 char *inbuf,char *outbuf,int length,int bufsize)
4810 unsigned int total_params = SVAL(inbuf, smb_tpscnt);
4811 unsigned int total_data =SVAL(inbuf, smb_tdscnt);
4812 unsigned int max_data_bytes = SVAL(inbuf, smb_mdrcnt);
4814 unsigned int max_param_reply = SVAL(inbuf, smb_mprcnt);
4815 unsigned int max_setup_fields = SVAL(inbuf, smb_msrcnt);
4816 BOOL close_tid = BITSETW(inbuf+smb_flags,0);
4817 BOOL no_final_response = BITSETW(inbuf+smb_flags,1);
4818 int32 timeout = IVALS(inbuf,smb_timeout);
4820 unsigned int suwcnt = SVAL(inbuf, smb_suwcnt);
4821 unsigned int tran_call = SVAL(inbuf, smb_setup0);
4822 char *params = NULL, *data = NULL;
4823 unsigned int num_params, num_params_sofar, num_data, num_data_sofar;
4824 START_PROFILE(SMBtrans2);
4826 if(global_oplock_break && (tran_call == TRANSACT2_OPEN)) {
4827 /* Queue this open message as we are the process of an
4830 DEBUG(2,("reply_trans2: queueing message trans2open due to being "));
4831 DEBUGADD(2,( "in oplock break state.\n"));
4833 push_oplock_pending_smb_message(inbuf, length);
4834 END_PROFILE(SMBtrans2);
4838 if (IS_IPC(conn) && (tran_call != TRANSACT2_OPEN)
4839 && (tran_call != TRANSACT2_GET_DFS_REFERRAL)) {
4840 END_PROFILE(SMBtrans2);
4841 return ERROR_DOS(ERRSRV,ERRaccess);
4844 outsize = set_message(outbuf,0,0,True);
4846 /* All trans2 messages we handle have smb_sucnt == 1 - ensure this
4847 is so as a sanity check */
4850 * Need to have rc=0 for ioctl to get job id for OS/2.
4851 * Network printing will fail if function is not successful.
4852 * Similar function in reply.c will be used if protocol
4853 * is LANMAN1.0 instead of LM1.2X002.
4854 * Until DosPrintSetJobInfo with PRJINFO3 is supported,
4855 * outbuf doesn't have to be set(only job id is used).
4857 if ( (suwcnt == 4) && (tran_call == TRANSACT2_IOCTL) &&
4858 (SVAL(inbuf,(smb_setup+4)) == LMCAT_SPL) &&
4859 (SVAL(inbuf,(smb_setup+6)) == LMFUNC_GETJOBID)) {
4860 DEBUG(2,("Got Trans2 DevIOctl jobid\n"));
4862 DEBUG(2,("Invalid smb_sucnt in trans2 call(%u)\n",suwcnt));
4863 DEBUG(2,("Transaction is %d\n",tran_call));
4864 END_PROFILE(SMBtrans2);
4865 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
4869 /* Allocate the space for the maximum needed parameters and data */
4870 if (total_params > 0)
4871 params = (char *)SMB_MALLOC(total_params);
4873 data = (char *)SMB_MALLOC(total_data);
4875 if ((total_params && !params) || (total_data && !data)) {
4876 DEBUG(2,("Out of memory in reply_trans2\n"));
4879 END_PROFILE(SMBtrans2);
4880 return ERROR_NT(NT_STATUS_NO_MEMORY);
4883 /* Copy the param and data bytes sent with this request into
4884 the params buffer */
4885 num_params = num_params_sofar = SVAL(inbuf,smb_pscnt);
4886 num_data = num_data_sofar = SVAL(inbuf, smb_dscnt);
4888 if (num_params > total_params || num_data > total_data)
4889 exit_server("invalid params in reply_trans2");
4892 unsigned int psoff = SVAL(inbuf, smb_psoff);
4893 if ((psoff + num_params < psoff) || (psoff + num_params < num_params))
4895 if ((smb_base(inbuf) + psoff + num_params > inbuf + length) ||
4896 (smb_base(inbuf) + psoff + num_params < smb_base(inbuf)))
4898 memcpy( params, smb_base(inbuf) + psoff, num_params);
4901 unsigned int dsoff = SVAL(inbuf, smb_dsoff);
4902 if ((dsoff + num_data < dsoff) || (dsoff + num_data < num_data))
4904 if ((smb_base(inbuf) + dsoff + num_data > inbuf + length) ||
4905 (smb_base(inbuf) + dsoff + num_data < smb_base(inbuf)))
4907 memcpy( data, smb_base(inbuf) + dsoff, num_data);
4910 srv_signing_trans_start(SVAL(inbuf,smb_mid));
4912 if(num_data_sofar < total_data || num_params_sofar < total_params) {
4913 /* We need to send an interim response then receive the rest
4914 of the parameter/data bytes */
4915 outsize = set_message(outbuf,0,0,True);
4916 srv_signing_trans_stop();
4918 if (!send_smb(smbd_server_fd(),outbuf))
4919 exit_server("reply_trans2: send_smb failed.");
4921 while (num_data_sofar < total_data ||
4922 num_params_sofar < total_params) {
4924 unsigned int param_disp;
4925 unsigned int param_off;
4926 unsigned int data_disp;
4927 unsigned int data_off;
4929 ret = receive_next_smb(inbuf,bufsize,SMB_SECONDARY_WAIT);
4931 /* We need to re-calcuate the new length after we've read the secondary packet. */
4932 length = smb_len(inbuf) + 4;
4935 * The sequence number for the trans reply is always
4936 * based on the last secondary received.
4939 srv_signing_trans_start(SVAL(inbuf,smb_mid));
4942 (CVAL(inbuf, smb_com) != SMBtranss2)) || !ret) {
4943 outsize = set_message(outbuf,0,0,True);
4945 DEBUG(0,("reply_trans2: Invalid secondary trans2 packet\n"));
4947 DEBUG(0,("reply_trans2: %s in getting secondary trans2 response.\n",
4948 (smb_read_error == READ_ERROR) ? "error" : "timeout" ));
4952 /* Revise total_params and total_data in case
4953 they have changed downwards */
4954 if (SVAL(inbuf, smb_tpscnt) < total_params)
4955 total_params = SVAL(inbuf, smb_tpscnt);
4956 if (SVAL(inbuf, smb_tdscnt) < total_data)
4957 total_data = SVAL(inbuf, smb_tdscnt);
4959 num_params = SVAL(inbuf,smb_spscnt);
4960 param_off = SVAL(inbuf, smb_spsoff);
4961 param_disp = SVAL(inbuf, smb_spsdisp);
4962 num_params_sofar += num_params;
4964 num_data = SVAL(inbuf, smb_sdscnt);
4965 data_off = SVAL(inbuf, smb_sdsoff);
4966 data_disp = SVAL(inbuf, smb_sdsdisp);
4967 num_data_sofar += num_data;
4969 if (num_params_sofar > total_params || num_data_sofar > total_data)
4973 if (param_disp + num_params > total_params)
4975 if ((param_disp + num_params < param_disp) ||
4976 (param_disp + num_params < num_params))
4978 if (param_disp > total_params)
4980 if ((smb_base(inbuf) + param_off + num_params > inbuf + length) ||
4981 (smb_base(inbuf) + param_off + num_params < smb_base(inbuf)))
4983 if (params + param_disp < params)
4986 memcpy( ¶ms[param_disp], smb_base(inbuf) + param_off, num_params);
4989 if (data_disp + num_data > total_data)
4991 if ((data_disp + num_data < data_disp) ||
4992 (data_disp + num_data < num_data))
4994 if (data_disp > total_data)
4996 if ((smb_base(inbuf) + data_off + num_data > inbuf + length) ||
4997 (smb_base(inbuf) + data_off + num_data < smb_base(inbuf)))
4999 if (data + data_disp < data)
5002 memcpy( &data[data_disp], smb_base(inbuf) + data_off, num_data);
5007 if (Protocol >= PROTOCOL_NT1) {
5008 SSVAL(outbuf,smb_flg2,SVAL(outbuf,smb_flg2) | 0x40); /* IS_LONG_NAME */
5011 /* Now we must call the relevant TRANS2 function */
5013 case TRANSACT2_OPEN:
5014 START_PROFILE_NESTED(Trans2_open);
5015 outsize = call_trans2open(conn, inbuf, outbuf, bufsize,
5016 ¶ms, total_params, &data, total_data, max_data_bytes);
5017 END_PROFILE_NESTED(Trans2_open);
5020 case TRANSACT2_FINDFIRST:
5021 START_PROFILE_NESTED(Trans2_findfirst);
5022 outsize = call_trans2findfirst(conn, inbuf, outbuf, bufsize,
5023 ¶ms, total_params, &data, total_data, max_data_bytes);
5024 END_PROFILE_NESTED(Trans2_findfirst);
5027 case TRANSACT2_FINDNEXT:
5028 START_PROFILE_NESTED(Trans2_findnext);
5029 outsize = call_trans2findnext(conn, inbuf, outbuf, length, bufsize,
5030 ¶ms, total_params, &data, total_data, max_data_bytes);
5031 END_PROFILE_NESTED(Trans2_findnext);
5034 case TRANSACT2_QFSINFO:
5035 START_PROFILE_NESTED(Trans2_qfsinfo);
5036 outsize = call_trans2qfsinfo(conn, inbuf, outbuf, length, bufsize,
5037 ¶ms, total_params, &data, total_data, max_data_bytes);
5038 END_PROFILE_NESTED(Trans2_qfsinfo);
5041 case TRANSACT2_SETFSINFO:
5042 START_PROFILE_NESTED(Trans2_setfsinfo);
5043 outsize = call_trans2setfsinfo(conn, inbuf, outbuf, length, bufsize,
5044 ¶ms, total_params, &data, total_data, max_data_bytes);
5045 END_PROFILE_NESTED(Trans2_setfsinfo);
5048 case TRANSACT2_QPATHINFO:
5049 case TRANSACT2_QFILEINFO:
5050 START_PROFILE_NESTED(Trans2_qpathinfo);
5051 outsize = call_trans2qfilepathinfo(conn, inbuf, outbuf, length, bufsize, tran_call,
5052 ¶ms, total_params, &data, total_data, max_data_bytes);
5053 END_PROFILE_NESTED(Trans2_qpathinfo);
5055 case TRANSACT2_SETPATHINFO:
5056 case TRANSACT2_SETFILEINFO:
5057 START_PROFILE_NESTED(Trans2_setpathinfo);
5058 outsize = call_trans2setfilepathinfo(conn, inbuf, outbuf, length, bufsize, tran_call,
5059 ¶ms, total_params, &data, total_data, max_data_bytes);
5060 END_PROFILE_NESTED(Trans2_setpathinfo);
5063 case TRANSACT2_FINDNOTIFYFIRST:
5064 START_PROFILE_NESTED(Trans2_findnotifyfirst);
5065 outsize = call_trans2findnotifyfirst(conn, inbuf, outbuf, length, bufsize,
5066 ¶ms, total_params, &data, total_data, max_data_bytes);
5067 END_PROFILE_NESTED(Trans2_findnotifyfirst);
5070 case TRANSACT2_FINDNOTIFYNEXT:
5071 START_PROFILE_NESTED(Trans2_findnotifynext);
5072 outsize = call_trans2findnotifynext(conn, inbuf, outbuf, length, bufsize,
5073 ¶ms, total_params, &data, total_data, max_data_bytes);
5074 END_PROFILE_NESTED(Trans2_findnotifynext);
5076 case TRANSACT2_MKDIR:
5077 START_PROFILE_NESTED(Trans2_mkdir);
5078 outsize = call_trans2mkdir(conn, inbuf, outbuf, length, bufsize,
5079 ¶ms, total_params, &data, total_data, max_data_bytes);
5080 END_PROFILE_NESTED(Trans2_mkdir);
5083 case TRANSACT2_GET_DFS_REFERRAL:
5084 START_PROFILE_NESTED(Trans2_get_dfs_referral);
5085 outsize = call_trans2getdfsreferral(conn,inbuf,outbuf,length, bufsize,
5086 ¶ms, total_params, &data, total_data, max_data_bytes);
5087 END_PROFILE_NESTED(Trans2_get_dfs_referral);
5089 case TRANSACT2_IOCTL:
5090 START_PROFILE_NESTED(Trans2_ioctl);
5091 outsize = call_trans2ioctl(conn,inbuf,outbuf,length, bufsize,
5092 ¶ms, total_params, &data, total_data, max_data_bytes);
5093 END_PROFILE_NESTED(Trans2_ioctl);
5096 /* Error in request */
5097 DEBUG(2,("Unknown request %d in trans2 call\n", tran_call));
5100 END_PROFILE(SMBtrans2);
5101 srv_signing_trans_stop();
5102 return ERROR_DOS(ERRSRV,ERRerror);
5105 /* As we do not know how many data packets will need to be
5106 returned here the various call_trans2xxxx calls
5107 must send their own. Thus a call_trans2xxx routine only
5108 returns a value other than -1 when it wants to send
5112 srv_signing_trans_stop();
5116 END_PROFILE(SMBtrans2);
5117 return outsize; /* If a correct response was needed the
5118 call_trans2xxx calls have already sent
5119 it. If outsize != -1 then it is returning */
5123 srv_signing_trans_stop();
5126 END_PROFILE(SMBtrans2);
5127 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);