2 Unix SMB/CIFS implementation.
3 SMB transaction2 handling
4 Copyright (C) Jeremy Allison 1994-2003
5 Copyright (C) Stefan (metze) Metzmacher 2003
7 Extensively modified by Andrew Tridgell, 1995
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26 extern enum protocol_types Protocol;
27 extern int smb_read_error;
28 extern fstring local_machine;
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 SMB_ROUNDUP_ALLOCATION_SIZE boundary.
38 Only do this for Windows clients.
39 ********************************************************************/
41 SMB_BIG_UINT smb_roundup(SMB_BIG_UINT val)
43 /* Only roundup for Windows clients. */
44 enum remote_arch_types ra_type = get_remote_arch();
45 if ((ra_type != RA_SAMBA) && (ra_type != RA_CIFSFS)) {
46 val = SMB_ROUNDUP(val,SMB_ROUNDUP_ALLOCATION_SIZE);
51 /********************************************************************
52 Given a stat buffer return the allocated size on disk, taking into
54 ********************************************************************/
56 SMB_BIG_UINT get_allocation_size(files_struct *fsp, SMB_STRUCT_STAT *sbuf)
60 #if defined(HAVE_STAT_ST_BLOCKS) && defined(STAT_ST_BLOCKSIZE)
61 ret = (SMB_BIG_UINT)STAT_ST_BLOCKSIZE * (SMB_BIG_UINT)sbuf->st_blocks;
63 ret = (SMB_BIG_UINT)get_file_size(*sbuf);
66 if (!ret && fsp && fsp->initial_allocation_size)
67 ret = fsp->initial_allocation_size;
69 ret = smb_roundup(ret);
74 /****************************************************************************
75 Utility functions for dealing with extended attributes.
76 ****************************************************************************/
78 static const char *prohibited_ea_names[] = {
79 SAMBA_POSIX_INHERITANCE_EA_NAME,
80 SAMBA_XATTR_DOS_ATTRIB,
84 /****************************************************************************
85 Refuse to allow clients to overwrite our private xattrs.
86 ****************************************************************************/
88 static BOOL samba_private_attr_name(const char *unix_ea_name)
92 for (i = 0; prohibited_ea_names[i]; i++) {
93 if (strequal( prohibited_ea_names[i], unix_ea_name))
100 struct ea_list *next, *prev;
104 /****************************************************************************
105 Get one EA value. Fill in a struct ea_struct.
106 ****************************************************************************/
108 static BOOL get_ea_value(TALLOC_CTX *mem_ctx, connection_struct *conn, files_struct *fsp,
109 const char *fname, char *ea_name, struct ea_struct *pea)
111 /* Get the value of this xattr. Max size is 64k. */
112 size_t attr_size = 256;
118 val = TALLOC_REALLOC_ARRAY(mem_ctx, val, char, attr_size);
123 if (fsp && fsp->fd != -1) {
124 sizeret = SMB_VFS_FGETXATTR(fsp, fsp->fd, ea_name, val, attr_size);
126 sizeret = SMB_VFS_GETXATTR(conn, fname, ea_name, val, attr_size);
129 if (sizeret == -1 && errno == ERANGE && attr_size != 65536) {
138 DEBUG(10,("get_ea_value: EA %s is of length %d: ", ea_name, sizeret));
139 dump_data(10, val, sizeret);
142 if (strnequal(ea_name, "user.", 5)) {
143 pea->name = &ea_name[5];
147 pea->value.data = val;
148 pea->value.length = (size_t)sizeret;
152 /****************************************************************************
153 Return a linked list of the total EA's. Plus the total size
154 ****************************************************************************/
156 static struct ea_list *get_ea_list(TALLOC_CTX *mem_ctx, connection_struct *conn, files_struct *fsp, 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: 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: 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: 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(char *pdata, unsigned int total_data_size,
233 connection_struct *conn, files_struct *fsp, const char *fname)
235 unsigned int ret_data_size = 4;
239 struct ea_list *ea_list;
241 SMB_ASSERT(total_data_size >= 4);
244 if (!lp_ea_support(SNUM(conn))) {
247 mem_ctx = talloc_init("fill_ea_buffer");
252 ea_list = get_ea_list(mem_ctx, conn, fsp, fname, &total_ea_len);
254 talloc_destroy(mem_ctx);
258 if (total_ea_len > total_data_size) {
259 talloc_destroy(mem_ctx);
263 for (p = pdata + 4; ea_list; ea_list = ea_list->next) {
266 push_ascii_fstring(dos_ea_name, ea_list->ea.name);
267 dos_namelen = strlen(dos_ea_name);
268 if (dos_namelen > 255 || dos_namelen == 0) {
271 if (ea_list->ea.value.length > 65535) {
274 if (4 + dos_namelen + 1 + ea_list->ea.value.length > total_data_size) {
278 /* We know we have room. */
279 SCVAL(p,0,ea_list->ea.flags);
280 SCVAL(p,1,dos_namelen);
281 SSVAL(p,2,ea_list->ea.value.length);
282 fstrcpy(p+4, dos_ea_name);
283 memcpy( p + 4 + dos_namelen + 1, ea_list->ea.value.data, ea_list->ea.value.length);
285 total_data_size -= 4 + dos_namelen + 1 + ea_list->ea.value.length;
286 p += 4 + dos_namelen + 1 + ea_list->ea.value.length;
289 ret_data_size = PTR_DIFF(p, pdata);
290 DEBUG(10,("fill_ea_buffer: data_size = %u, total_ea_len = %u\n",
291 ret_data_size, total_ea_len ));
292 talloc_destroy(mem_ctx);
293 SIVAL(pdata,0,ret_data_size);
294 return ret_data_size;
297 static unsigned int estimate_ea_size(connection_struct *conn, files_struct *fsp, const char *fname)
299 size_t total_ea_len = 0;
300 TALLOC_CTX *mem_ctx = NULL;
302 if (!lp_ea_support(SNUM(conn))) {
305 mem_ctx = talloc_init("estimate_ea_size");
306 (void)get_ea_list(mem_ctx, conn, fsp, fname, &total_ea_len);
307 talloc_destroy(mem_ctx);
311 /****************************************************************************
312 Ensure the EA name is case insensitive by matching any existing EA name.
313 ****************************************************************************/
315 static void canonicalize_ea_name(connection_struct *conn, files_struct *fsp, const char *fname, fstring unix_ea_name)
318 TALLOC_CTX *mem_ctx = talloc_init("canonicalize_ea_name");
319 struct ea_list *ea_list = get_ea_list(mem_ctx, conn, fsp, fname, &total_ea_len);
321 for (; ea_list; ea_list = ea_list->next) {
322 if (strequal(&unix_ea_name[5], ea_list->ea.name)) {
323 DEBUG(10,("canonicalize_ea_name: %s -> %s\n",
324 &unix_ea_name[5], ea_list->ea.name));
325 safe_strcpy(&unix_ea_name[5], ea_list->ea.name, sizeof(fstring)-6);
329 talloc_destroy(mem_ctx);
332 /****************************************************************************
333 Set or delete an extended attribute.
334 ****************************************************************************/
336 static NTSTATUS set_ea(connection_struct *conn, files_struct *fsp, const char *fname,
337 char *pdata, int total_data)
339 unsigned int namelen;
342 fstring unix_ea_name;
344 if (!lp_ea_support(SNUM(conn))) {
345 return NT_STATUS_EAS_NOT_SUPPORTED;
348 if (total_data < 8) {
349 return NT_STATUS_INVALID_PARAMETER;
352 if (IVAL(pdata,0) > total_data) {
353 DEBUG(10,("set_ea: bad total data size (%u) > %u\n", IVAL(pdata,0), (unsigned int)total_data));
354 return NT_STATUS_INVALID_PARAMETER;
358 namelen = CVAL(pdata,1);
359 ealen = SVAL(pdata,2);
361 if (total_data < 8 + namelen + 1 + ealen) {
362 DEBUG(10,("set_ea: bad total data size (%u) < 8 + namelen (%u) + 1 + ealen (%u)\n",
363 (unsigned int)total_data, namelen, ealen));
364 return NT_STATUS_INVALID_PARAMETER;
367 if (pdata[namelen] != '\0') {
368 DEBUG(10,("set_ea: ea name not null terminated\n"));
369 return NT_STATUS_INVALID_PARAMETER;
372 fstrcpy(unix_ea_name, "user."); /* All EA's must start with user. */
373 pull_ascii(&unix_ea_name[5], pdata, sizeof(fstring) - 5, -1, STR_TERMINATE);
374 pdata += (namelen + 1);
376 canonicalize_ea_name(conn, fsp, fname, unix_ea_name);
378 DEBUG(10,("set_ea: ea_name %s ealen = %u\n", unix_ea_name, ealen));
380 DEBUG(10,("set_ea: data :\n"));
381 dump_data(10, pdata, ealen);
384 if (samba_private_attr_name(unix_ea_name)) {
385 DEBUG(10,("set_ea: ea name %s is a private Samba name.\n", unix_ea_name));
386 return NT_STATUS_ACCESS_DENIED;
390 /* Remove the attribute. */
391 if (fsp && (fsp->fd != -1)) {
392 DEBUG(10,("set_ea: deleting ea name %s on file %s by file descriptor.\n",
393 unix_ea_name, fsp->fsp_name));
394 ret = SMB_VFS_FREMOVEXATTR(fsp, fsp->fd, unix_ea_name);
396 DEBUG(10,("set_ea: deleting ea name %s on file %s.\n",
397 unix_ea_name, fname));
398 ret = SMB_VFS_REMOVEXATTR(conn, fname, unix_ea_name);
401 /* Removing a non existent attribute always succeeds. */
402 if (ret == -1 && errno == ENOATTR) {
403 DEBUG(10,("set_ea: deleting ea name %s didn't exist - succeeding by default.\n", unix_ea_name));
408 if (fsp && (fsp->fd != -1)) {
409 DEBUG(10,("set_ea: setting ea name %s on file %s by file descriptor.\n",
410 unix_ea_name, fsp->fsp_name));
411 ret = SMB_VFS_FSETXATTR(fsp, fsp->fd, unix_ea_name, pdata, ealen, 0);
413 DEBUG(10,("set_ea: setting ea name %s on file %s.\n",
414 unix_ea_name, fname));
415 ret = SMB_VFS_SETXATTR(conn, fname, unix_ea_name, pdata, ealen, 0);
421 if (errno == ENOTSUP) {
422 return NT_STATUS_EAS_NOT_SUPPORTED;
425 return map_nt_error_from_unix(errno);
431 /****************************************************************************
432 Send the required number of replies back.
433 We assume all fields other than the data fields are
434 set correctly for the type of call.
435 HACK ! Always assumes smb_setup field is zero.
436 ****************************************************************************/
438 static int send_trans2_replies(char *outbuf,
445 /* As we are using a protocol > LANMAN1 then the max_send
446 variable must have been set in the sessetupX call.
447 This takes precedence over the max_xmit field in the
448 global struct. These different max_xmit variables should
449 be merged as this is now too confusing */
452 int data_to_send = datasize;
453 int params_to_send = paramsize;
457 int params_sent_thistime, data_sent_thistime, total_sent_thistime;
458 int alignment_offset = 1; /* JRA. This used to be 3. Set to 1 to make netmon parse ok. */
459 int data_alignment_offset = 0;
461 /* Initially set the wcnt area to be 10 - this is true for all trans2 replies */
463 set_message(outbuf,10,0,True);
465 /* If there genuinely are no parameters or data to send just send the empty packet */
467 if(params_to_send == 0 && data_to_send == 0) {
468 if (!send_smb(smbd_server_fd(),outbuf))
469 exit_server("send_trans2_replies: send_smb failed.");
473 /* When sending params and data ensure that both are nicely aligned */
474 /* Only do this alignment when there is also data to send - else
475 can cause NT redirector problems. */
477 if (((params_to_send % 4) != 0) && (data_to_send != 0))
478 data_alignment_offset = 4 - (params_to_send % 4);
480 /* Space is bufsize minus Netbios over TCP header minus SMB header */
481 /* The alignment_offset is to align the param bytes on an even byte
482 boundary. NT 4.0 Beta needs this to work correctly. */
484 useable_space = bufsize - ((smb_buf(outbuf)+ alignment_offset+data_alignment_offset) - outbuf);
486 /* useable_space can never be more than max_send minus the alignment offset. */
488 useable_space = MIN(useable_space, max_send - (alignment_offset+data_alignment_offset));
490 while (params_to_send || data_to_send) {
491 /* Calculate whether we will totally or partially fill this packet */
493 total_sent_thistime = params_to_send + data_to_send + alignment_offset + data_alignment_offset;
495 /* We can never send more than useable_space */
497 * Note that 'useable_space' does not include the alignment offsets,
498 * but we must include the alignment offsets in the calculation of
499 * the length of the data we send over the wire, as the alignment offsets
500 * are sent here. Fix from Marc_Jacobsen@hp.com.
503 total_sent_thistime = MIN(total_sent_thistime, useable_space+ alignment_offset + data_alignment_offset);
505 set_message(outbuf, 10, total_sent_thistime, True);
507 /* Set total params and data to be sent */
508 SSVAL(outbuf,smb_tprcnt,paramsize);
509 SSVAL(outbuf,smb_tdrcnt,datasize);
511 /* Calculate how many parameters and data we can fit into
512 * this packet. Parameters get precedence
515 params_sent_thistime = MIN(params_to_send,useable_space);
516 data_sent_thistime = useable_space - params_sent_thistime;
517 data_sent_thistime = MIN(data_sent_thistime,data_to_send);
519 SSVAL(outbuf,smb_prcnt, params_sent_thistime);
521 /* smb_proff is the offset from the start of the SMB header to the
522 parameter bytes, however the first 4 bytes of outbuf are
523 the Netbios over TCP header. Thus use smb_base() to subtract
524 them from the calculation */
526 SSVAL(outbuf,smb_proff,((smb_buf(outbuf)+alignment_offset) - smb_base(outbuf)));
528 if(params_sent_thistime == 0)
529 SSVAL(outbuf,smb_prdisp,0);
531 /* Absolute displacement of param bytes sent in this packet */
532 SSVAL(outbuf,smb_prdisp,pp - params);
534 SSVAL(outbuf,smb_drcnt, data_sent_thistime);
535 if(data_sent_thistime == 0) {
536 SSVAL(outbuf,smb_droff,0);
537 SSVAL(outbuf,smb_drdisp, 0);
539 /* The offset of the data bytes is the offset of the
540 parameter bytes plus the number of parameters being sent this time */
541 SSVAL(outbuf,smb_droff,((smb_buf(outbuf)+alignment_offset) -
542 smb_base(outbuf)) + params_sent_thistime + data_alignment_offset);
543 SSVAL(outbuf,smb_drdisp, pd - pdata);
546 /* Copy the param bytes into the packet */
548 if(params_sent_thistime)
549 memcpy((smb_buf(outbuf)+alignment_offset),pp,params_sent_thistime);
551 /* Copy in the data bytes */
552 if(data_sent_thistime)
553 memcpy(smb_buf(outbuf)+alignment_offset+params_sent_thistime+
554 data_alignment_offset,pd,data_sent_thistime);
556 DEBUG(9,("t2_rep: params_sent_thistime = %d, data_sent_thistime = %d, useable_space = %d\n",
557 params_sent_thistime, data_sent_thistime, useable_space));
558 DEBUG(9,("t2_rep: params_to_send = %d, data_to_send = %d, paramsize = %d, datasize = %d\n",
559 params_to_send, data_to_send, paramsize, datasize));
561 /* Send the packet */
562 if (!send_smb(smbd_server_fd(),outbuf))
563 exit_server("send_trans2_replies: send_smb failed.");
565 pp += params_sent_thistime;
566 pd += data_sent_thistime;
568 params_to_send -= params_sent_thistime;
569 data_to_send -= data_sent_thistime;
572 if(params_to_send < 0 || data_to_send < 0) {
573 DEBUG(0,("send_trans2_replies failed sanity check pts = %d, dts = %d\n!!!",
574 params_to_send, data_to_send));
582 /****************************************************************************
583 Reply to a TRANSACT2_OPEN.
584 ****************************************************************************/
586 static int call_trans2open(connection_struct *conn, char *inbuf, char *outbuf, int bufsize,
587 char **pparams, int total_params, char **ppdata, int total_data,
588 unsigned int max_data_bytes)
590 char *params = *pparams;
595 BOOL return_additional_info;
604 int fmode=0,mtime=0,rmode;
606 SMB_STRUCT_STAT sbuf;
608 BOOL bad_path = False;
613 * Ensure we have enough parameters to perform the operation.
616 if (total_params < 29)
617 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
619 open_mode = SVAL(params, 2);
620 open_attr = SVAL(params,6);
621 oplock_request = (((SVAL(params,0)|(1<<1))>>1) | ((SVAL(params,0)|(1<<2))>>1));
623 return_additional_info = BITSETW(params,0);
624 open_sattr = SVAL(params, 4);
625 open_time = make_unix_date3(params+8);
627 open_ofun = SVAL(params,12);
628 open_size = IVAL(params,14);
632 return(ERROR_DOS(ERRSRV,ERRaccess));
634 srvstr_get_path(inbuf, fname, pname, sizeof(fname), -1, STR_TERMINATE, &status, False);
635 if (!NT_STATUS_IS_OK(status)) {
636 return ERROR_NT(status);
639 DEBUG(3,("trans2open %s mode=%d attr=%d ofun=%d size=%d\n",
640 fname,open_mode, open_attr, open_ofun, open_size));
642 /* XXXX we need to handle passed times, sattr and flags */
644 unix_convert(fname,conn,0,&bad_path,&sbuf);
646 return ERROR_NT(NT_STATUS_OBJECT_PATH_NOT_FOUND);
649 if (!check_name(fname,conn)) {
650 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRnoaccess);
653 fsp = open_file_shared(conn,fname,&sbuf,open_mode,open_ofun,(uint32)open_attr,
654 oplock_request, &rmode,&smb_action);
657 if (open_was_deferred(SVAL(inbuf,smb_mid))) {
658 /* We have re-scheduled this call. */
659 clear_cached_errors();
662 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRnoaccess);
665 size = get_file_size(sbuf);
666 fmode = dos_mode(conn,fname,&sbuf);
667 mtime = sbuf.st_mtime;
670 close_file(fsp,False);
671 return(ERROR_DOS(ERRDOS,ERRnoaccess));
674 /* Realloc the size of parameters and data we will return */
675 params = SMB_REALLOC(*pparams, 28);
677 return(ERROR_DOS(ERRDOS,ERRnomem));
680 memset((char *)params,'\0',28);
681 SSVAL(params,0,fsp->fnum);
682 SSVAL(params,2,fmode);
683 put_dos_date2(params,4, mtime);
684 SIVAL(params,8, (uint32)size);
685 SSVAL(params,12,rmode);
687 if (oplock_request && lp_fake_oplocks(SNUM(conn)))
688 smb_action |= EXTENDED_OPLOCK_GRANTED;
690 SSVAL(params,18,smb_action);
693 * WARNING - this may need to be changed if SMB_INO_T <> 4 bytes.
695 SIVAL(params,20,inode);
697 /* Send the required number of replies */
698 send_trans2_replies(outbuf, bufsize, params, 28, *ppdata, 0);
703 /*********************************************************
704 Routine to check if a given string matches exactly.
705 as a special case a mask of "." does NOT match. That
706 is required for correct wildcard semantics
707 Case can be significant or not.
708 **********************************************************/
710 static BOOL exact_match(char *str,char *mask, BOOL case_sig)
712 if (mask[0] == '.' && mask[1] == 0)
715 return strcmp(str,mask)==0;
716 if (StrCaseCmp(str,mask) != 0) {
719 if (ms_has_wild(str)) {
725 /****************************************************************************
726 Return the filetype for UNIX extensions.
727 ****************************************************************************/
729 static uint32 unix_filetype(mode_t mode)
732 return UNIX_TYPE_FILE;
733 else if(S_ISDIR(mode))
734 return UNIX_TYPE_DIR;
736 else if(S_ISLNK(mode))
737 return UNIX_TYPE_SYMLINK;
740 else if(S_ISCHR(mode))
741 return UNIX_TYPE_CHARDEV;
744 else if(S_ISBLK(mode))
745 return UNIX_TYPE_BLKDEV;
748 else if(S_ISFIFO(mode))
749 return UNIX_TYPE_FIFO;
752 else if(S_ISSOCK(mode))
753 return UNIX_TYPE_SOCKET;
756 DEBUG(0,("unix_filetype: unknown filetype %u", (unsigned)mode));
757 return UNIX_TYPE_UNKNOWN;
760 /****************************************************************************
761 Map wire perms onto standard UNIX permissions. Obey share restrictions.
762 ****************************************************************************/
764 static mode_t unix_perms_from_wire( connection_struct *conn, SMB_STRUCT_STAT *pst, uint32 perms)
768 if (perms == SMB_MODE_NO_CHANGE)
771 ret |= ((perms & UNIX_X_OTH ) ? S_IXOTH : 0);
772 ret |= ((perms & UNIX_W_OTH ) ? S_IWOTH : 0);
773 ret |= ((perms & UNIX_R_OTH ) ? S_IROTH : 0);
774 ret |= ((perms & UNIX_X_GRP ) ? S_IXGRP : 0);
775 ret |= ((perms & UNIX_W_GRP ) ? S_IWGRP : 0);
776 ret |= ((perms & UNIX_R_GRP ) ? S_IRGRP : 0);
777 ret |= ((perms & UNIX_X_USR ) ? S_IXUSR : 0);
778 ret |= ((perms & UNIX_W_USR ) ? S_IWUSR : 0);
779 ret |= ((perms & UNIX_R_USR ) ? S_IRUSR : 0);
781 ret |= ((perms & UNIX_STICKY ) ? S_ISVTX : 0);
784 ret |= ((perms & UNIX_SET_GID ) ? S_ISGID : 0);
787 ret |= ((perms & UNIX_SET_UID ) ? S_ISUID : 0);
790 if (VALID_STAT(*pst) && S_ISDIR(pst->st_mode)) {
791 ret &= lp_dir_mask(SNUM(conn));
792 /* Add in force bits */
793 ret |= lp_force_dir_mode(SNUM(conn));
795 /* Apply mode mask */
796 ret &= lp_create_mask(SNUM(conn));
797 /* Add in force bits */
798 ret |= lp_force_create_mode(SNUM(conn));
804 /****************************************************************************
805 Checks for SMB_TIME_NO_CHANGE and if not found calls interpret_long_date.
806 ****************************************************************************/
808 time_t interpret_long_unix_date(char *p)
810 DEBUG(10,("interpret_long_unix_date\n"));
811 if(IVAL(p,0) == SMB_TIME_NO_CHANGE_LO &&
812 IVAL(p,4) == SMB_TIME_NO_CHANGE_HI) {
815 return interpret_long_date(p);
819 /****************************************************************************
820 Get a level dependent lanman2 dir entry.
821 ****************************************************************************/
823 static BOOL get_lanman2_dir_entry(connection_struct *conn,
824 void *inbuf, void *outbuf,
825 char *path_mask,int dirtype,int info_level,
826 int requires_resume_key,
827 BOOL dont_descend,char **ppdata,
828 char *base_data, int space_remaining,
829 BOOL *out_of_space, BOOL *got_exact_match,
834 SMB_STRUCT_STAT sbuf;
838 char *p, *q, *pdata = *ppdata;
842 SMB_OFF_T file_size = 0;
843 SMB_BIG_UINT allocation_size = 0;
845 time_t mdate=0, adate=0, cdate=0;
848 int nt_extmode; /* Used for NT connections instead of mode */
849 BOOL needslash = ( conn->dirpath[strlen(conn->dirpath) -1] != '/');
852 *out_of_space = False;
853 *got_exact_match = False;
858 p = strrchr_m(path_mask,'/');
865 pstrcpy(mask, path_mask);
870 /* Needed if we run out of space */
871 long curr_dirpos = prev_dirpos = dptr_TellDir(conn->dirptr);
872 dname = dptr_ReadDirName(conn->dirptr,&curr_dirpos,&sbuf);
875 * Due to bugs in NT client redirectors we are not using
876 * resume keys any more - set them to zero.
877 * Check out the related comments in findfirst/findnext.
883 DEBUG(8,("get_lanman2_dir_entry:readdir on dirptr 0x%lx now at offset %ld\n",
884 (long)conn->dirptr,curr_dirpos));
889 pstrcpy(fname,dname);
891 if(!(got_match = *got_exact_match = exact_match(fname, mask, conn->case_sensitive)))
892 got_match = mask_match(fname, mask, conn->case_sensitive);
894 if(!got_match && !mangle_is_8_3(fname, False)) {
897 * It turns out that NT matches wildcards against
898 * both long *and* short names. This may explain some
899 * of the wildcard wierdness from old DOS clients
900 * that some people have been seeing.... JRA.
904 pstrcpy( newname, fname);
905 mangle_map( newname, True, False, SNUM(conn));
906 if(!(got_match = *got_exact_match = exact_match(newname, mask, conn->case_sensitive)))
907 got_match = mask_match(newname, mask, conn->case_sensitive);
911 BOOL isdots = (strequal(fname,"..") || strequal(fname,"."));
912 if (dont_descend && !isdots)
915 pstrcpy(pathreal,conn->dirpath);
917 pstrcat(pathreal,"/");
918 pstrcat(pathreal,dname);
920 if (INFO_LEVEL_IS_UNIX(info_level)) {
921 if (SMB_VFS_LSTAT(conn,pathreal,&sbuf) != 0) {
922 DEBUG(5,("get_lanman2_dir_entry:Couldn't lstat [%s] (%s)\n",
923 pathreal,strerror(errno)));
926 } else if (!VALID_STAT(sbuf) && SMB_VFS_STAT(conn,pathreal,&sbuf) != 0) {
928 /* Needed to show the msdfs symlinks as
931 if(lp_host_msdfs() &&
932 lp_msdfs_root(SNUM(conn)) &&
933 is_msdfs_link(conn, pathreal, NULL, NULL,
936 DEBUG(5,("get_lanman2_dir_entry: Masquerading msdfs link %s as a directory\n", pathreal));
937 sbuf.st_mode = (sbuf.st_mode & 0xFFF) | S_IFDIR;
941 DEBUG(5,("get_lanman2_dir_entry:Couldn't stat [%s] (%s)\n",
942 pathreal,strerror(errno)));
947 mode = dos_mode(conn,pathreal,&sbuf);
949 if (!dir_check_ftype(conn,mode,dirtype)) {
950 DEBUG(5,("[%s] attribs didn't match %x\n",fname,dirtype));
954 file_size = get_file_size(sbuf);
955 allocation_size = get_allocation_size(NULL,&sbuf);
956 mdate = sbuf.st_mtime;
957 adate = sbuf.st_atime;
958 cdate = get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(conn)));
960 if (lp_dos_filetime_resolution(SNUM(conn))) {
967 /* This is necessary, as otherwise the
968 * desktop.ini file in this folder is
970 mode |= (lp_profile_acls(SNUM(conn)) ? aRONLY : 0);
974 DEBUG(5,("get_lanman2_dir_entry found %s fname=%s\n",pathreal,fname));
980 mangle_map(fname,False,True,SNUM(conn));
985 nt_extmode = mode ? mode : FILE_ATTRIBUTE_NORMAL;
987 switch (info_level) {
988 case SMB_INFO_STANDARD:
989 DEBUG(10,("get_lanman2_dir_entry: SMB_INFO_STANDARD\n"));
990 if(requires_resume_key) {
994 put_dos_date2(p,l1_fdateCreation,cdate);
995 put_dos_date2(p,l1_fdateLastAccess,adate);
996 put_dos_date2(p,l1_fdateLastWrite,mdate);
997 SIVAL(p,l1_cbFile,(uint32)file_size);
998 SIVAL(p,l1_cbFileAlloc,(uint32)allocation_size);
999 SSVAL(p,l1_attrFile,mode);
1002 p += align_string(outbuf, p, 0);
1003 len = srvstr_push(outbuf, p, fname, -1, STR_TERMINATE);
1004 if (SVAL(outbuf, smb_flg2) & FLAGS2_UNICODE_STRINGS) {
1006 SCVAL(nameptr, -1, len - 2);
1008 SCVAL(nameptr, -1, 0);
1012 SCVAL(nameptr, -1, len - 1);
1014 SCVAL(nameptr, -1, 0);
1020 case SMB_INFO_QUERY_EA_SIZE:
1021 DEBUG(10,("get_lanman2_dir_entry: SMB_INFO_QUERY_EA_SIZE\n"));
1022 if(requires_resume_key) {
1026 put_dos_date2(p,l2_fdateCreation,cdate);
1027 put_dos_date2(p,l2_fdateLastAccess,adate);
1028 put_dos_date2(p,l2_fdateLastWrite,mdate);
1029 SIVAL(p,l2_cbFile,(uint32)file_size);
1030 SIVAL(p,l2_cbFileAlloc,(uint32)allocation_size);
1031 SSVAL(p,l2_attrFile,mode);
1033 unsigned int ea_size = estimate_ea_size(conn, NULL, pathreal);
1034 SIVAL(p,l2_cbList,ea_size); /* Extended attributes */
1038 len = srvstr_push(outbuf, p, fname, -1, STR_TERMINATE | STR_NOALIGN);
1039 if (SVAL(outbuf, smb_flg2) & FLAGS2_UNICODE_STRINGS) {
1052 SCVAL(nameptr,0,len);
1054 SCVAL(p,0,0); p += 1; /* Extra zero byte ? - why.. */
1057 case SMB_FIND_FILE_BOTH_DIRECTORY_INFO:
1058 DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_FILE_BOTH_DIRECTORY_INFO\n"));
1059 was_8_3 = mangle_is_8_3(fname, True);
1061 SIVAL(p,0,reskey); p += 4;
1062 put_long_date(p,cdate); p += 8;
1063 put_long_date(p,adate); p += 8;
1064 put_long_date(p,mdate); p += 8;
1065 put_long_date(p,mdate); p += 8;
1066 SOFF_T(p,0,file_size); p += 8;
1067 SOFF_T(p,0,allocation_size); p += 8;
1068 SIVAL(p,0,nt_extmode); p += 4;
1069 q = p; p += 4; /* q is placeholder for name length. */
1071 unsigned int ea_size = estimate_ea_size(conn, NULL, pathreal);
1072 SIVAL(p,0,ea_size); /* Extended attributes */
1075 /* Clear the short name buffer. This is
1076 * IMPORTANT as not doing so will trigger
1077 * a Win2k client bug. JRA.
1080 if (!was_8_3 && lp_manglednames(SNUM(conn))) {
1081 pstring mangled_name;
1082 pstrcpy(mangled_name, fname);
1083 mangle_map(mangled_name,True,True,SNUM(conn));
1084 mangled_name[12] = 0;
1085 len = srvstr_push(outbuf, p+2, mangled_name, 24, STR_UPPER|STR_UNICODE);
1092 len = srvstr_push(outbuf, p, fname, -1, STR_TERMINATE_ASCII);
1095 len = PTR_DIFF(p, pdata);
1096 len = (len + 3) & ~3;
1101 case SMB_FIND_FILE_DIRECTORY_INFO:
1102 DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_FILE_DIRECTORY_INFO\n"));
1104 SIVAL(p,0,reskey); p += 4;
1105 put_long_date(p,cdate); p += 8;
1106 put_long_date(p,adate); p += 8;
1107 put_long_date(p,mdate); p += 8;
1108 put_long_date(p,mdate); p += 8;
1109 SOFF_T(p,0,file_size); p += 8;
1110 SOFF_T(p,0,allocation_size); p += 8;
1111 SIVAL(p,0,nt_extmode); p += 4;
1112 len = srvstr_push(outbuf, p + 4, fname, -1, STR_TERMINATE_ASCII);
1115 len = PTR_DIFF(p, pdata);
1116 len = (len + 3) & ~3;
1121 case SMB_FIND_FILE_FULL_DIRECTORY_INFO:
1122 DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_FILE_FULL_DIRECTORY_INFO\n"));
1124 SIVAL(p,0,reskey); p += 4;
1125 put_long_date(p,cdate); p += 8;
1126 put_long_date(p,adate); p += 8;
1127 put_long_date(p,mdate); p += 8;
1128 put_long_date(p,mdate); p += 8;
1129 SOFF_T(p,0,file_size); p += 8;
1130 SOFF_T(p,0,allocation_size); p += 8;
1131 SIVAL(p,0,nt_extmode); p += 4;
1132 q = p; p += 4; /* q is placeholder for name length. */
1134 unsigned int ea_size = estimate_ea_size(conn, NULL, pathreal);
1135 SIVAL(p,0,ea_size); /* Extended attributes */
1138 len = srvstr_push(outbuf, p, fname, -1, STR_TERMINATE_ASCII);
1142 len = PTR_DIFF(p, pdata);
1143 len = (len + 3) & ~3;
1148 case SMB_FIND_FILE_NAMES_INFO:
1149 DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_FILE_NAMES_INFO\n"));
1151 SIVAL(p,0,reskey); p += 4;
1153 /* this must *not* be null terminated or w2k gets in a loop trying to set an
1154 acl on a dir (tridge) */
1155 len = srvstr_push(outbuf, p, fname, -1, STR_TERMINATE_ASCII);
1158 len = PTR_DIFF(p, pdata);
1159 len = (len + 3) & ~3;
1164 case SMB_FIND_ID_FULL_DIRECTORY_INFO:
1165 DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_ID_FULL_DIRECTORY_INFO\n"));
1167 SIVAL(p,0,reskey); p += 4;
1168 put_long_date(p,cdate); p += 8;
1169 put_long_date(p,adate); p += 8;
1170 put_long_date(p,mdate); p += 8;
1171 put_long_date(p,mdate); p += 8;
1172 SOFF_T(p,0,file_size); p += 8;
1173 SOFF_T(p,0,allocation_size); p += 8;
1174 SIVAL(p,0,nt_extmode); p += 4;
1175 q = p; p += 4; /* q is placeholder for name length. */
1177 unsigned int ea_size = estimate_ea_size(conn, NULL, pathreal);
1178 SIVAL(p,0,ea_size); /* Extended attributes */
1181 SIVAL(p,0,0); p += 4; /* Unknown - reserved ? */
1182 SIVAL(p,0,sbuf.st_dev); p += 4;
1183 SIVAL(p,0,sbuf.st_ino); p += 4;
1184 len = srvstr_push(outbuf, p, fname, -1, STR_TERMINATE_ASCII);
1187 len = PTR_DIFF(p, pdata);
1188 len = (len + 3) & ~3;
1193 case SMB_FIND_ID_BOTH_DIRECTORY_INFO:
1194 DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_ID_BOTH_DIRECTORY_INFO\n"));
1195 was_8_3 = mangle_is_8_3(fname, True);
1197 SIVAL(p,0,reskey); p += 4;
1198 put_long_date(p,cdate); p += 8;
1199 put_long_date(p,adate); p += 8;
1200 put_long_date(p,mdate); p += 8;
1201 put_long_date(p,mdate); p += 8;
1202 SOFF_T(p,0,file_size); p += 8;
1203 SOFF_T(p,0,allocation_size); p += 8;
1204 SIVAL(p,0,nt_extmode); p += 4;
1205 q = p; p += 4; /* q is placeholder for name length */
1207 unsigned int ea_size = estimate_ea_size(conn, NULL, pathreal);
1208 SIVAL(p,0,ea_size); /* Extended attributes */
1211 /* Clear the short name buffer. This is
1212 * IMPORTANT as not doing so will trigger
1213 * a Win2k client bug. JRA.
1216 if (!was_8_3 && lp_manglednames(SNUM(conn))) {
1217 pstring mangled_name;
1218 pstrcpy(mangled_name, fname);
1219 mangle_map(mangled_name,True,True,SNUM(conn));
1220 mangled_name[12] = 0;
1221 len = srvstr_push(outbuf, p+2, mangled_name, 24, STR_UPPER|STR_UNICODE);
1228 SSVAL(p,0,0); p += 2; /* Reserved ? */
1229 SIVAL(p,0,sbuf.st_dev); p += 4;
1230 SIVAL(p,0,sbuf.st_ino); p += 4;
1231 len = srvstr_push(outbuf, p, fname, -1, STR_TERMINATE_ASCII);
1234 len = PTR_DIFF(p, pdata);
1235 len = (len + 3) & ~3;
1240 /* CIFS UNIX Extension. */
1242 case SMB_FIND_FILE_UNIX:
1243 DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_FILE_UNIX\n"));
1245 SIVAL(p,0,reskey); p+= 4; /* Used for continuing search. */
1247 /* Begin of SMB_QUERY_FILE_UNIX_BASIC */
1248 SOFF_T(p,0,get_file_size(sbuf)); /* File size 64 Bit */
1251 SOFF_T(p,0,get_allocation_size(NULL,&sbuf)); /* Number of bytes used on disk - 64 Bit */
1254 put_long_date(p,sbuf.st_ctime); /* Inode change Time 64 Bit */
1255 put_long_date(p+8,sbuf.st_atime); /* Last access time 64 Bit */
1256 put_long_date(p+16,sbuf.st_mtime); /* Last modification time 64 Bit */
1259 SIVAL(p,0,sbuf.st_uid); /* user id for the owner */
1263 SIVAL(p,0,sbuf.st_gid); /* group id of owner */
1267 SIVAL(p,0,unix_filetype(sbuf.st_mode));
1270 SIVAL(p,0,unix_dev_major(sbuf.st_rdev)); /* Major device number if type is device */
1274 SIVAL(p,0,unix_dev_minor(sbuf.st_rdev)); /* Minor device number if type is device */
1278 SINO_T(p,0,(SMB_INO_T)sbuf.st_ino); /* inode number */
1281 SIVAL(p,0, unix_perms_to_wire(sbuf.st_mode)); /* Standard UNIX file permissions */
1285 SIVAL(p,0,sbuf.st_nlink); /* number of hard links */
1289 len = srvstr_push(outbuf, p, fname, -1, STR_TERMINATE);
1292 len = PTR_DIFF(p, pdata);
1293 len = (len + 3) & ~3;
1294 SIVAL(pdata,0,len); /* Offset from this structure to the beginning of the next one */
1296 /* End of SMB_QUERY_FILE_UNIX_BASIC */
1305 if (PTR_DIFF(p,pdata) > space_remaining) {
1306 /* Move the dirptr back to prev_dirpos */
1307 dptr_SeekDir(conn->dirptr, prev_dirpos);
1308 *out_of_space = True;
1309 DEBUG(9,("get_lanman2_dir_entry: out of space\n"));
1310 return False; /* Not finished - just out of space */
1313 /* Setup the last_filename pointer, as an offset from base_data */
1314 *last_name_off = PTR_DIFF(nameptr,base_data);
1315 /* Advance the data pointer to the next slot */
1321 /****************************************************************************
1322 Reply to a TRANS2_FINDFIRST.
1323 ****************************************************************************/
1325 static int call_trans2findfirst(connection_struct *conn, char *inbuf, char *outbuf, int bufsize,
1326 char **pparams, int total_params, char **ppdata, int total_data,
1327 unsigned int max_data_bytes)
1329 /* We must be careful here that we don't return more than the
1330 allowed number of data bytes. If this means returning fewer than
1331 maxentries then so be it. We assume that the redirector has
1332 enough room for the fixed number of parameter bytes it has
1334 char *params = *pparams;
1335 char *pdata = *ppdata;
1336 int dirtype = SVAL(params,0);
1337 int maxentries = SVAL(params,2);
1338 uint16 findfirst_flags = SVAL(params,4);
1339 BOOL close_after_first = (findfirst_flags & FLAG_TRANS2_FIND_CLOSE);
1340 BOOL close_if_end = (findfirst_flags & FLAG_TRANS2_FIND_CLOSE_IF_END);
1341 BOOL requires_resume_key = (findfirst_flags & FLAG_TRANS2_FIND_REQUIRE_RESUME);
1342 int info_level = SVAL(params,6);
1346 int last_name_off=0;
1350 BOOL finished = False;
1351 BOOL dont_descend = False;
1352 BOOL out_of_space = False;
1353 int space_remaining;
1354 BOOL bad_path = False;
1355 SMB_STRUCT_STAT sbuf;
1356 NTSTATUS ntstatus = NT_STATUS_OK;
1358 if (total_params < 12)
1359 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
1361 *directory = *mask = 0;
1363 DEBUG(3,("call_trans2findfirst: dirtype = %d, maxentries = %d, close_after_first=%d, \
1364 close_if_end = %d requires_resume_key = %d level = 0x%x, max_data_bytes = %d\n",
1365 dirtype, maxentries, close_after_first, close_if_end, requires_resume_key,
1366 info_level, max_data_bytes));
1369 /* W2K3 seems to treat zero as 1. */
1373 switch (info_level) {
1374 case SMB_INFO_STANDARD:
1375 case SMB_INFO_QUERY_EA_SIZE:
1376 case SMB_FIND_FILE_DIRECTORY_INFO:
1377 case SMB_FIND_FILE_FULL_DIRECTORY_INFO:
1378 case SMB_FIND_FILE_NAMES_INFO:
1379 case SMB_FIND_FILE_BOTH_DIRECTORY_INFO:
1380 case SMB_FIND_ID_FULL_DIRECTORY_INFO:
1381 case SMB_FIND_ID_BOTH_DIRECTORY_INFO:
1383 case SMB_FIND_FILE_UNIX:
1384 if (!lp_unix_extensions())
1385 return(ERROR_DOS(ERRDOS,ERRunknownlevel));
1388 return(ERROR_DOS(ERRDOS,ERRunknownlevel));
1391 srvstr_get_path(inbuf, directory, params+12, sizeof(directory), -1, STR_TERMINATE, &ntstatus, True);
1392 if (!NT_STATUS_IS_OK(ntstatus)) {
1393 return ERROR_NT(ntstatus);
1396 RESOLVE_FINDFIRST_DFSPATH(directory, conn, inbuf, outbuf);
1398 unix_convert(directory,conn,0,&bad_path,&sbuf);
1400 return ERROR_NT(NT_STATUS_OBJECT_PATH_NOT_FOUND);
1402 if(!check_name(directory,conn)) {
1403 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRbadpath);
1406 p = strrchr_m(directory,'/');
1408 /* Windows and OS/2 systems treat search on the root '\' as if it were '\*' */
1409 if((directory[0] == '.') && (directory[1] == '\0'))
1412 pstrcpy(mask,directory);
1413 pstrcpy(directory,"./");
1419 DEBUG(5,("dir=%s, mask = %s\n",directory, mask));
1421 pdata = SMB_REALLOC(*ppdata, max_data_bytes + DIR_ENTRY_SAFETY_MARGIN);
1423 return(ERROR_DOS(ERRDOS,ERRnomem));
1426 memset((char *)pdata,'\0',max_data_bytes + DIR_ENTRY_SAFETY_MARGIN);
1428 /* Realloc the params space */
1429 params = SMB_REALLOC(*pparams, 10);
1431 return ERROR_DOS(ERRDOS,ERRnomem);
1434 dptr_num = dptr_create(conn,directory, False, True ,SVAL(inbuf,smb_pid));
1436 return(UNIXERROR(ERRDOS,ERRbadfile));
1438 /* Save the wildcard match and attribs we are using on this directory -
1439 needed as lanman2 assumes these are being saved between calls */
1441 if (!dptr_set_wcard_and_attributes(dptr_num, mask, dirtype)) {
1442 dptr_close(&dptr_num);
1443 return ERROR_DOS(ERRDOS,ERRnomem);
1446 DEBUG(4,("dptr_num is %d, wcard = %s, attr = %d\n",dptr_num, mask, dirtype));
1448 /* We don't need to check for VOL here as this is returned by
1449 a different TRANS2 call. */
1451 DEBUG(8,("dirpath=<%s> dontdescend=<%s>\n", conn->dirpath,lp_dontdescend(SNUM(conn))));
1452 if (in_list(conn->dirpath,lp_dontdescend(SNUM(conn)),conn->case_sensitive))
1453 dont_descend = True;
1456 space_remaining = max_data_bytes;
1457 out_of_space = False;
1459 for (i=0;(i<maxentries) && !finished && !out_of_space;i++) {
1460 BOOL got_exact_match = False;
1462 /* this is a heuristic to avoid seeking the dirptr except when
1463 absolutely necessary. It allows for a filename of about 40 chars */
1464 if (space_remaining < DIRLEN_GUESS && numentries > 0) {
1465 out_of_space = True;
1468 finished = !get_lanman2_dir_entry(conn,
1470 mask,dirtype,info_level,
1471 requires_resume_key,dont_descend,
1472 &p,pdata,space_remaining, &out_of_space, &got_exact_match,
1476 if (finished && out_of_space)
1479 if (!finished && !out_of_space)
1483 * As an optimisation if we know we aren't looking
1484 * for a wildcard name (ie. the name matches the wildcard exactly)
1485 * then we can finish on any (first) match.
1486 * This speeds up large directory searches. JRA.
1492 space_remaining = max_data_bytes - PTR_DIFF(p,pdata);
1495 /* Check if we can close the dirptr */
1496 if(close_after_first || (finished && close_if_end)) {
1497 DEBUG(5,("call_trans2findfirst - (2) closing dptr_num %d\n", dptr_num));
1498 dptr_close(&dptr_num);
1502 * If there are no matching entries we must return ERRDOS/ERRbadfile -
1503 * from observation of NT.
1506 if(numentries == 0) {
1507 dptr_close(&dptr_num);
1508 return ERROR_DOS(ERRDOS,ERRbadfile);
1511 /* At this point pdata points to numentries directory entries. */
1513 /* Set up the return parameter block */
1514 SSVAL(params,0,dptr_num);
1515 SSVAL(params,2,numentries);
1516 SSVAL(params,4,finished);
1517 SSVAL(params,6,0); /* Never an EA error */
1518 SSVAL(params,8,last_name_off);
1520 send_trans2_replies( outbuf, bufsize, params, 10, pdata, PTR_DIFF(p,pdata));
1522 if ((! *directory) && dptr_path(dptr_num))
1523 slprintf(directory,sizeof(directory)-1, "(%s)",dptr_path(dptr_num));
1525 DEBUG( 4, ( "%s mask=%s directory=%s dirtype=%d numentries=%d\n",
1526 smb_fn_name(CVAL(inbuf,smb_com)),
1527 mask, directory, dirtype, numentries ) );
1530 * Force a name mangle here to ensure that the
1531 * mask as an 8.3 name is top of the mangled cache.
1532 * The reasons for this are subtle. Don't remove
1533 * this code unless you know what you are doing
1534 * (see PR#13758). JRA.
1537 if(!mangle_is_8_3_wildcards( mask, False))
1538 mangle_map(mask, True, True, SNUM(conn));
1543 /****************************************************************************
1544 Reply to a TRANS2_FINDNEXT.
1545 ****************************************************************************/
1547 static int call_trans2findnext(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize,
1548 char **pparams, int total_params, char **ppdata, int total_data,
1549 unsigned int max_data_bytes)
1551 /* We must be careful here that we don't return more than the
1552 allowed number of data bytes. If this means returning fewer than
1553 maxentries then so be it. We assume that the redirector has
1554 enough room for the fixed number of parameter bytes it has
1556 char *params = *pparams;
1557 char *pdata = *ppdata;
1558 int dptr_num = SVAL(params,0);
1559 int maxentries = SVAL(params,2);
1560 uint16 info_level = SVAL(params,4);
1561 uint32 resume_key = IVAL(params,6);
1562 uint16 findnext_flags = SVAL(params,10);
1563 BOOL close_after_request = (findnext_flags & FLAG_TRANS2_FIND_CLOSE);
1564 BOOL close_if_end = (findnext_flags & FLAG_TRANS2_FIND_CLOSE_IF_END);
1565 BOOL requires_resume_key = (findnext_flags & FLAG_TRANS2_FIND_REQUIRE_RESUME);
1566 BOOL continue_bit = (findnext_flags & FLAG_TRANS2_FIND_CONTINUE);
1567 pstring resume_name;
1573 int i, last_name_off=0;
1574 BOOL finished = False;
1575 BOOL dont_descend = False;
1576 BOOL out_of_space = False;
1577 int space_remaining;
1578 NTSTATUS ntstatus = NT_STATUS_OK;
1580 if (total_params < 12)
1581 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
1583 *mask = *directory = *resume_name = 0;
1585 srvstr_get_path(inbuf, resume_name, params+12, sizeof(resume_name), -1, STR_TERMINATE, &ntstatus, True);
1586 if (!NT_STATUS_IS_OK(ntstatus)) {
1587 return ERROR_NT(ntstatus);
1590 DEBUG(3,("call_trans2findnext: dirhandle = %d, max_data_bytes = %d, maxentries = %d, \
1591 close_after_request=%d, close_if_end = %d requires_resume_key = %d \
1592 resume_key = %d resume name = %s continue=%d level = %d\n",
1593 dptr_num, max_data_bytes, maxentries, close_after_request, close_if_end,
1594 requires_resume_key, resume_key, resume_name, continue_bit, info_level));
1597 /* W2K3 seems to treat zero as 1. */
1601 switch (info_level) {
1602 case SMB_INFO_STANDARD:
1603 case SMB_INFO_QUERY_EA_SIZE:
1604 case SMB_FIND_FILE_DIRECTORY_INFO:
1605 case SMB_FIND_FILE_FULL_DIRECTORY_INFO:
1606 case SMB_FIND_FILE_NAMES_INFO:
1607 case SMB_FIND_FILE_BOTH_DIRECTORY_INFO:
1609 case SMB_FIND_FILE_UNIX:
1610 if (!lp_unix_extensions())
1611 return(ERROR_DOS(ERRDOS,ERRunknownlevel));
1614 return ERROR_DOS(ERRDOS,ERRunknownlevel);
1617 pdata = SMB_REALLOC( *ppdata, max_data_bytes + DIR_ENTRY_SAFETY_MARGIN);
1619 return ERROR_DOS(ERRDOS,ERRnomem);
1622 memset((char *)pdata,'\0',max_data_bytes + DIR_ENTRY_SAFETY_MARGIN);
1624 /* Realloc the params space */
1625 params = SMB_REALLOC(*pparams, 6*SIZEOFWORD);
1626 if( params == NULL )
1627 return ERROR_DOS(ERRDOS,ERRnomem);
1631 /* Check that the dptr is valid */
1632 if(!(conn->dirptr = dptr_fetch_lanman2(dptr_num)))
1633 return ERROR_DOS(ERRDOS,ERRnofiles);
1635 string_set(&conn->dirpath,dptr_path(dptr_num));
1637 /* Get the wildcard mask from the dptr */
1638 if((p = dptr_wcard(dptr_num))== NULL) {
1639 DEBUG(2,("dptr_num %d has no wildcard\n", dptr_num));
1640 return ERROR_DOS(ERRDOS,ERRnofiles);
1644 pstrcpy(directory,conn->dirpath);
1646 /* Get the attr mask from the dptr */
1647 dirtype = dptr_attr(dptr_num);
1649 DEBUG(3,("dptr_num is %d, mask = %s, attr = %x, dirptr=(0x%lX,%ld)\n",
1650 dptr_num, mask, dirtype,
1652 dptr_TellDir(conn->dirptr)));
1654 /* We don't need to check for VOL here as this is returned by
1655 a different TRANS2 call. */
1657 DEBUG(8,("dirpath=<%s> dontdescend=<%s>\n",conn->dirpath,lp_dontdescend(SNUM(conn))));
1658 if (in_list(conn->dirpath,lp_dontdescend(SNUM(conn)),conn->case_sensitive))
1659 dont_descend = True;
1662 space_remaining = max_data_bytes;
1663 out_of_space = False;
1666 * Seek to the correct position. We no longer use the resume key but
1667 * depend on the last file name instead.
1670 if(*resume_name && !continue_bit) {
1673 long current_pos = 0;
1675 * Remember, mangle_map is called by
1676 * get_lanman2_dir_entry(), so the resume name
1677 * could be mangled. Ensure we check the unmangled name.
1680 if (mangle_is_mangled(resume_name)) {
1681 mangle_check_cache(resume_name, sizeof(resume_name)-1);
1685 * Fix for NT redirector problem triggered by resume key indexes
1686 * changing between directory scans. We now return a resume key of 0
1687 * and instead look for the filename to continue from (also given
1688 * to us by NT/95/smbfs/smbclient). If no other scans have been done between the
1689 * findfirst/findnext (as is usual) then the directory pointer
1690 * should already be at the correct place.
1693 finished = !dptr_SearchDir(conn->dirptr, resume_name, ¤t_pos, &st);
1694 } /* end if resume_name && !continue_bit */
1696 for (i=0;(i<(int)maxentries) && !finished && !out_of_space ;i++) {
1697 BOOL got_exact_match = False;
1699 /* this is a heuristic to avoid seeking the dirptr except when
1700 absolutely necessary. It allows for a filename of about 40 chars */
1701 if (space_remaining < DIRLEN_GUESS && numentries > 0) {
1702 out_of_space = True;
1705 finished = !get_lanman2_dir_entry(conn,
1707 mask,dirtype,info_level,
1708 requires_resume_key,dont_descend,
1709 &p,pdata,space_remaining, &out_of_space, &got_exact_match,
1713 if (finished && out_of_space)
1716 if (!finished && !out_of_space)
1720 * As an optimisation if we know we aren't looking
1721 * for a wildcard name (ie. the name matches the wildcard exactly)
1722 * then we can finish on any (first) match.
1723 * This speeds up large directory searches. JRA.
1729 space_remaining = max_data_bytes - PTR_DIFF(p,pdata);
1732 /* Check if we can close the dirptr */
1733 if(close_after_request || (finished && close_if_end)) {
1734 DEBUG(5,("call_trans2findnext: closing dptr_num = %d\n", dptr_num));
1735 dptr_close(&dptr_num); /* This frees up the saved mask */
1738 /* Set up the return parameter block */
1739 SSVAL(params,0,numentries);
1740 SSVAL(params,2,finished);
1741 SSVAL(params,4,0); /* Never an EA error */
1742 SSVAL(params,6,last_name_off);
1744 send_trans2_replies( outbuf, bufsize, params, 8, pdata, PTR_DIFF(p,pdata));
1746 if ((! *directory) && dptr_path(dptr_num))
1747 slprintf(directory,sizeof(directory)-1, "(%s)",dptr_path(dptr_num));
1749 DEBUG( 3, ( "%s mask=%s directory=%s dirtype=%d numentries=%d\n",
1750 smb_fn_name(CVAL(inbuf,smb_com)),
1751 mask, directory, dirtype, numentries ) );
1756 /****************************************************************************
1757 Reply to a TRANS2_QFSINFO (query filesystem info).
1758 ****************************************************************************/
1760 static int call_trans2qfsinfo(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize,
1761 char **pparams, int total_params, char **ppdata, int total_data,
1762 unsigned int max_data_bytes)
1764 char *pdata = *ppdata;
1765 char *params = *pparams;
1766 uint16 info_level = SVAL(params,0);
1769 char *vname = volume_label(SNUM(conn));
1770 int snum = SNUM(conn);
1771 char *fstype = lp_fstype(SNUM(conn));
1774 DEBUG(3,("call_trans2qfsinfo: level = %d\n", info_level));
1776 if(SMB_VFS_STAT(conn,".",&st)!=0) {
1777 DEBUG(2,("call_trans2qfsinfo: stat of . failed (%s)\n", strerror(errno)));
1778 return ERROR_DOS(ERRSRV,ERRinvdevice);
1781 pdata = SMB_REALLOC(*ppdata, max_data_bytes + DIR_ENTRY_SAFETY_MARGIN);
1782 if ( pdata == NULL )
1783 return ERROR_DOS(ERRDOS,ERRnomem);
1786 memset((char *)pdata,'\0',max_data_bytes + DIR_ENTRY_SAFETY_MARGIN);
1788 switch (info_level) {
1789 case SMB_INFO_ALLOCATION:
1791 SMB_BIG_UINT dfree,dsize,bsize,block_size,sectors_per_unit,bytes_per_sector;
1793 SMB_VFS_DISK_FREE(conn,".",False,&bsize,&dfree,&dsize);
1794 block_size = lp_block_size(snum);
1795 if (bsize < block_size) {
1796 SMB_BIG_UINT factor = block_size/bsize;
1801 if (bsize > block_size) {
1802 SMB_BIG_UINT factor = bsize/block_size;
1807 bytes_per_sector = 512;
1808 sectors_per_unit = bsize/bytes_per_sector;
1810 DEBUG(5,("call_trans2qfsinfo : SMB_INFO_ALLOCATION id=%x, bsize=%u, cSectorUnit=%u, \
1811 cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)st.st_dev, (unsigned int)bsize, (unsigned int)sectors_per_unit,
1812 (unsigned int)bytes_per_sector, (unsigned int)dsize, (unsigned int)dfree));
1814 SIVAL(pdata,l1_idFileSystem,st.st_dev);
1815 SIVAL(pdata,l1_cSectorUnit,sectors_per_unit);
1816 SIVAL(pdata,l1_cUnit,dsize);
1817 SIVAL(pdata,l1_cUnitAvail,dfree);
1818 SSVAL(pdata,l1_cbSector,bytes_per_sector);
1822 case SMB_INFO_VOLUME:
1823 /* Return volume name */
1825 * Add volume serial number - hash of a combination of
1826 * the called hostname and the service name.
1828 SIVAL(pdata,0,str_checksum(lp_servicename(snum)) ^ (str_checksum(local_machine)<<16) );
1829 len = srvstr_push(outbuf, pdata+l2_vol_szVolLabel, vname, -1, STR_NOALIGN);
1830 SCVAL(pdata,l2_vol_cch,len);
1831 data_len = l2_vol_szVolLabel + len;
1832 DEBUG(5,("call_trans2qfsinfo : time = %x, namelen = %d, name = %s\n",
1833 (unsigned)st.st_ctime, len, vname));
1836 case SMB_QUERY_FS_ATTRIBUTE_INFO:
1837 case SMB_FS_ATTRIBUTE_INFORMATION:
1840 #if defined(HAVE_SYS_QUOTAS)
1841 quota_flag = FILE_VOLUME_QUOTAS;
1844 SIVAL(pdata,0,FILE_CASE_PRESERVED_NAMES|FILE_CASE_SENSITIVE_SEARCH|
1845 (lp_nt_acl_support(SNUM(conn)) ? FILE_PERSISTENT_ACLS : 0)|
1846 quota_flag); /* FS ATTRIBUTES */
1848 SIVAL(pdata,4,255); /* Max filename component length */
1849 /* NOTE! the fstype must *not* be null terminated or win98 won't recognise it
1850 and will think we can't do long filenames */
1851 len = srvstr_push(outbuf, pdata+12, fstype, -1, STR_UNICODE);
1853 data_len = 12 + len;
1856 case SMB_QUERY_FS_LABEL_INFO:
1857 case SMB_FS_LABEL_INFORMATION:
1858 len = srvstr_push(outbuf, pdata+4, vname, -1, 0);
1863 case SMB_QUERY_FS_VOLUME_INFO:
1864 case SMB_FS_VOLUME_INFORMATION:
1867 * Add volume serial number - hash of a combination of
1868 * the called hostname and the service name.
1870 SIVAL(pdata,8,str_checksum(lp_servicename(snum)) ^
1871 (str_checksum(local_machine)<<16));
1873 len = srvstr_push(outbuf, pdata+18, vname, -1, STR_UNICODE);
1874 SIVAL(pdata,12,len);
1876 DEBUG(5,("call_trans2qfsinfo : SMB_QUERY_FS_VOLUME_INFO namelen = %d, vol=%s serv=%s\n",
1877 (int)strlen(vname),vname, lp_servicename(snum)));
1880 case SMB_QUERY_FS_SIZE_INFO:
1881 case SMB_FS_SIZE_INFORMATION:
1883 SMB_BIG_UINT dfree,dsize,bsize,block_size,sectors_per_unit,bytes_per_sector;
1885 SMB_VFS_DISK_FREE(conn,".",False,&bsize,&dfree,&dsize);
1886 block_size = lp_block_size(snum);
1887 if (bsize < block_size) {
1888 SMB_BIG_UINT factor = block_size/bsize;
1893 if (bsize > block_size) {
1894 SMB_BIG_UINT factor = bsize/block_size;
1899 bytes_per_sector = 512;
1900 sectors_per_unit = bsize/bytes_per_sector;
1901 DEBUG(5,("call_trans2qfsinfo : SMB_QUERY_FS_SIZE_INFO bsize=%u, cSectorUnit=%u, \
1902 cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize, (unsigned int)sectors_per_unit,
1903 (unsigned int)bytes_per_sector, (unsigned int)dsize, (unsigned int)dfree));
1904 SBIG_UINT(pdata,0,dsize);
1905 SBIG_UINT(pdata,8,dfree);
1906 SIVAL(pdata,16,sectors_per_unit);
1907 SIVAL(pdata,20,bytes_per_sector);
1911 case SMB_FS_FULL_SIZE_INFORMATION:
1913 SMB_BIG_UINT dfree,dsize,bsize,block_size,sectors_per_unit,bytes_per_sector;
1915 SMB_VFS_DISK_FREE(conn,".",False,&bsize,&dfree,&dsize);
1916 block_size = lp_block_size(snum);
1917 if (bsize < block_size) {
1918 SMB_BIG_UINT factor = block_size/bsize;
1923 if (bsize > block_size) {
1924 SMB_BIG_UINT factor = bsize/block_size;
1929 bytes_per_sector = 512;
1930 sectors_per_unit = bsize/bytes_per_sector;
1931 DEBUG(5,("call_trans2qfsinfo : SMB_QUERY_FS_FULL_SIZE_INFO bsize=%u, cSectorUnit=%u, \
1932 cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize, (unsigned int)sectors_per_unit,
1933 (unsigned int)bytes_per_sector, (unsigned int)dsize, (unsigned int)dfree));
1934 SBIG_UINT(pdata,0,dsize); /* Total Allocation units. */
1935 SBIG_UINT(pdata,8,dfree); /* Caller available allocation units. */
1936 SBIG_UINT(pdata,16,dfree); /* Actual available allocation units. */
1937 SIVAL(pdata,24,sectors_per_unit); /* Sectors per allocation unit. */
1938 SIVAL(pdata,28,bytes_per_sector); /* Bytes per sector. */
1942 case SMB_QUERY_FS_DEVICE_INFO:
1943 case SMB_FS_DEVICE_INFORMATION:
1945 SIVAL(pdata,0,0); /* dev type */
1946 SIVAL(pdata,4,0); /* characteristics */
1949 #ifdef HAVE_SYS_QUOTAS
1950 case SMB_FS_QUOTA_INFORMATION:
1952 * what we have to send --metze:
1954 * Unknown1: 24 NULL bytes
1955 * Soft Quota Treshold: 8 bytes seems like SMB_BIG_UINT or so
1956 * Hard Quota Limit: 8 bytes seems like SMB_BIG_UINT or so
1957 * Quota Flags: 2 byte :
1958 * Unknown3: 6 NULL bytes
1962 * details for Quota Flags:
1964 * 0x0020 Log Limit: log if the user exceeds his Hard Quota
1965 * 0x0010 Log Warn: log if the user exceeds his Soft Quota
1966 * 0x0002 Deny Disk: deny disk access when the user exceeds his Hard Quota
1967 * 0x0001 Enable Quotas: enable quota for this fs
1971 /* we need to fake up a fsp here,
1972 * because its not send in this call
1975 SMB_NTQUOTA_STRUCT quotas;
1978 ZERO_STRUCT(quotas);
1985 if (current_user.uid != 0) {
1986 DEBUG(0,("set_user_quota: access_denied service [%s] user [%s]\n",
1987 lp_servicename(SNUM(conn)),conn->user));
1988 return ERROR_DOS(ERRDOS,ERRnoaccess);
1991 if (vfs_get_ntquota(&fsp, SMB_USER_FS_QUOTA_TYPE, NULL, "as)!=0) {
1992 DEBUG(0,("vfs_get_ntquota() failed for service [%s]\n",lp_servicename(SNUM(conn))));
1993 return ERROR_DOS(ERRSRV,ERRerror);
1998 DEBUG(10,("SMB_FS_QUOTA_INFORMATION: for service [%s]\n",lp_servicename(SNUM(conn))));
2000 /* Unknown1 24 NULL bytes*/
2001 SBIG_UINT(pdata,0,(SMB_BIG_UINT)0);
2002 SBIG_UINT(pdata,8,(SMB_BIG_UINT)0);
2003 SBIG_UINT(pdata,16,(SMB_BIG_UINT)0);
2005 /* Default Soft Quota 8 bytes */
2006 SBIG_UINT(pdata,24,quotas.softlim);
2008 /* Default Hard Quota 8 bytes */
2009 SBIG_UINT(pdata,32,quotas.hardlim);
2011 /* Quota flag 2 bytes */
2012 SSVAL(pdata,40,quotas.qflags);
2014 /* Unknown3 6 NULL bytes */
2020 #endif /* HAVE_SYS_QUOTAS */
2021 case SMB_FS_OBJECTID_INFORMATION:
2026 * Query the version and capabilities of the CIFS UNIX extensions
2030 case SMB_QUERY_CIFS_UNIX_INFO:
2031 if (!lp_unix_extensions())
2032 return ERROR_DOS(ERRDOS,ERRunknownlevel);
2034 SSVAL(pdata,0,CIFS_UNIX_MAJOR_VERSION);
2035 SSVAL(pdata,2,CIFS_UNIX_MINOR_VERSION);
2036 SBIG_UINT(pdata,4,((SMB_BIG_UINT)CIFS_UNIX_POSIX_ACLS_CAP)); /* We have POSIX ACLs. */
2039 case SMB_MAC_QUERY_FS_INFO:
2041 * Thursby MAC extension... ONLY on NTFS filesystems
2042 * once we do streams then we don't need this
2044 if (strequal(lp_fstype(SNUM(conn)),"NTFS")) {
2046 SIVAL(pdata,84,0x100); /* Don't support mac... */
2051 return ERROR_DOS(ERRDOS,ERRunknownlevel);
2055 send_trans2_replies( outbuf, bufsize, params, 0, pdata, data_len);
2057 DEBUG( 4, ( "%s info_level = %d\n", smb_fn_name(CVAL(inbuf,smb_com)), info_level) );
2062 #ifdef HAVE_SYS_QUOTAS
2063 /****************************************************************************
2064 Reply to a TRANS2_SETFSINFO (set filesystem info).
2065 ****************************************************************************/
2067 static int call_trans2setfsinfo(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize,
2068 char **pparams, int total_params, char **ppdata, int total_data,
2069 unsigned int max_data_bytes)
2071 char *pdata = *ppdata;
2072 char *params = *pparams;
2073 files_struct *fsp = NULL;
2076 SMB_NTQUOTA_STRUCT quotas;
2078 ZERO_STRUCT(quotas);
2080 DEBUG(10,("call_trans2setfsinfo: SET_FS_QUOTA: for service [%s]\n",lp_servicename(SNUM(conn))));
2083 if ((current_user.uid != 0)||!CAN_WRITE(conn)) {
2084 DEBUG(0,("set_user_quota: access_denied service [%s] user [%s]\n",
2085 lp_servicename(SNUM(conn)),conn->user));
2086 return ERROR_DOS(ERRSRV,ERRaccess);
2090 if (total_params < 4) {
2091 DEBUG(0,("call_trans2setfsinfo: requires total_params(%d) >= 4 bytes!\n",
2093 return ERROR_DOS(ERRDOS,ERRinvalidparam);
2096 fsp = file_fsp(params,0);
2098 if (!CHECK_NTQUOTA_HANDLE_OK(fsp,conn)) {
2099 DEBUG(3,("TRANSACT_GET_USER_QUOTA: no valid QUOTA HANDLE\n"));
2100 return ERROR_NT(NT_STATUS_INVALID_HANDLE);
2103 info_level = SVAL(params,2);
2105 switch(info_level) {
2106 case SMB_FS_QUOTA_INFORMATION:
2107 /* note: normaly there're 48 bytes,
2108 * but we didn't use the last 6 bytes for now
2111 if (total_data < 42) {
2112 DEBUG(0,("call_trans2setfsinfo: SET_FS_QUOTA: requires total_data(%d) >= 42 bytes!\n",
2114 return ERROR_DOS(ERRDOS,ERRunknownlevel);
2117 /* unknown_1 24 NULL bytes in pdata*/
2119 /* the soft quotas 8 bytes (SMB_BIG_UINT)*/
2120 quotas.softlim = (SMB_BIG_UINT)IVAL(pdata,24);
2121 #ifdef LARGE_SMB_OFF_T
2122 quotas.softlim |= (((SMB_BIG_UINT)IVAL(pdata,28)) << 32);
2123 #else /* LARGE_SMB_OFF_T */
2124 if ((IVAL(pdata,28) != 0)&&
2125 ((quotas.softlim != 0xFFFFFFFF)||
2126 (IVAL(pdata,28)!=0xFFFFFFFF))) {
2127 /* more than 32 bits? */
2128 return ERROR_DOS(ERRDOS,ERRunknownlevel);
2130 #endif /* LARGE_SMB_OFF_T */
2132 /* the hard quotas 8 bytes (SMB_BIG_UINT)*/
2133 quotas.hardlim = (SMB_BIG_UINT)IVAL(pdata,32);
2134 #ifdef LARGE_SMB_OFF_T
2135 quotas.hardlim |= (((SMB_BIG_UINT)IVAL(pdata,36)) << 32);
2136 #else /* LARGE_SMB_OFF_T */
2137 if ((IVAL(pdata,36) != 0)&&
2138 ((quotas.hardlim != 0xFFFFFFFF)||
2139 (IVAL(pdata,36)!=0xFFFFFFFF))) {
2140 /* more than 32 bits? */
2141 return ERROR_DOS(ERRDOS,ERRunknownlevel);
2143 #endif /* LARGE_SMB_OFF_T */
2145 /* quota_flags 2 bytes **/
2146 quotas.qflags = SVAL(pdata,40);
2148 /* unknown_2 6 NULL bytes follow*/
2150 /* now set the quotas */
2151 if (vfs_set_ntquota(fsp, SMB_USER_FS_QUOTA_TYPE, NULL, "as)!=0) {
2152 DEBUG(0,("vfs_set_ntquota() failed for service [%s]\n",lp_servicename(SNUM(conn))));
2153 return ERROR_DOS(ERRSRV,ERRerror);
2158 DEBUG(3,("call_trans2setfsinfo: unknown level (0x%X) not implemented yet.\n",
2160 return ERROR_DOS(ERRDOS,ERRunknownlevel);
2165 * sending this reply works fine,
2166 * but I'm not sure it's the same
2167 * like windows do...
2170 outsize = set_message(outbuf,10,0,True);
2174 #endif /* HAVE_SYS_QUOTAS */
2176 /****************************************************************************
2177 Utility function to set bad path error.
2178 ****************************************************************************/
2180 int set_bad_path_error(int err, BOOL bad_path, char *outbuf, int def_class, uint32 def_code)
2182 DEBUG(10,("set_bad_path_error: err = %d bad_path = %d\n",
2183 err, (int)bad_path ));
2187 return ERROR_NT(NT_STATUS_OBJECT_PATH_NOT_FOUND);
2189 return ERROR_NT(NT_STATUS_OBJECT_NAME_NOT_FOUND);
2192 return UNIXERROR(def_class,def_code);
2195 /****************************************************************************
2196 Utility function to count the number of entries in a POSIX acl.
2197 ****************************************************************************/
2199 static unsigned int count_acl_entries(connection_struct *conn, SMB_ACL_T posix_acl)
2201 unsigned int ace_count = 0;
2202 int entry_id = SMB_ACL_FIRST_ENTRY;
2203 SMB_ACL_ENTRY_T entry;
2205 while ( posix_acl && (SMB_VFS_SYS_ACL_GET_ENTRY(conn, posix_acl, entry_id, &entry) == 1)) {
2207 if (entry_id == SMB_ACL_FIRST_ENTRY) {
2208 entry_id = SMB_ACL_NEXT_ENTRY;
2215 /****************************************************************************
2216 Utility function to marshall a POSIX acl into wire format.
2217 ****************************************************************************/
2219 static BOOL marshall_posix_acl(connection_struct *conn, char *pdata, SMB_STRUCT_STAT *pst, SMB_ACL_T posix_acl)
2221 int entry_id = SMB_ACL_FIRST_ENTRY;
2222 SMB_ACL_ENTRY_T entry;
2224 while ( posix_acl && (SMB_VFS_SYS_ACL_GET_ENTRY(conn, posix_acl, entry_id, &entry) == 1)) {
2225 SMB_ACL_TAG_T tagtype;
2226 SMB_ACL_PERMSET_T permset;
2227 unsigned char perms = 0;
2228 unsigned int own_grp;
2231 if (entry_id == SMB_ACL_FIRST_ENTRY) {
2232 entry_id = SMB_ACL_NEXT_ENTRY;
2235 if (SMB_VFS_SYS_ACL_GET_TAG_TYPE(conn, entry, &tagtype) == -1) {
2236 DEBUG(0,("marshall_posix_acl: SMB_VFS_SYS_ACL_GET_TAG_TYPE failed.\n"));
2240 if (SMB_VFS_SYS_ACL_GET_PERMSET(conn, entry, &permset) == -1) {
2241 DEBUG(0,("marshall_posix_acl: SMB_VFS_SYS_ACL_GET_PERMSET failed.\n"));
2245 perms |= (SMB_VFS_SYS_ACL_GET_PERM(conn, permset, SMB_ACL_READ) ? SMB_POSIX_ACL_READ : 0);
2246 perms |= (SMB_VFS_SYS_ACL_GET_PERM(conn, permset, SMB_ACL_WRITE) ? SMB_POSIX_ACL_WRITE : 0);
2247 perms |= (SMB_VFS_SYS_ACL_GET_PERM(conn, permset, SMB_ACL_EXECUTE) ? SMB_POSIX_ACL_EXECUTE : 0);
2249 SCVAL(pdata,1,perms);
2252 case SMB_ACL_USER_OBJ:
2253 SCVAL(pdata,0,SMB_POSIX_ACL_USER_OBJ);
2254 own_grp = (unsigned int)pst->st_uid;
2255 SIVAL(pdata,2,own_grp);
2260 uid_t *puid = (uid_t *)SMB_VFS_SYS_ACL_GET_QUALIFIER(conn, entry);
2262 DEBUG(0,("marshall_posix_acl: SMB_VFS_SYS_ACL_GET_QUALIFIER failed.\n"));
2264 own_grp = (unsigned int)*puid;
2265 SMB_VFS_SYS_ACL_FREE_QUALIFIER(conn, (void *)puid,tagtype);
2266 SCVAL(pdata,0,SMB_POSIX_ACL_USER);
2267 SIVAL(pdata,2,own_grp);
2271 case SMB_ACL_GROUP_OBJ:
2272 SCVAL(pdata,0,SMB_POSIX_ACL_GROUP_OBJ);
2273 own_grp = (unsigned int)pst->st_gid;
2274 SIVAL(pdata,2,own_grp);
2279 gid_t *pgid= (gid_t *)SMB_VFS_SYS_ACL_GET_QUALIFIER(conn, entry);
2281 DEBUG(0,("marshall_posix_acl: SMB_VFS_SYS_ACL_GET_QUALIFIER failed.\n"));
2283 own_grp = (unsigned int)*pgid;
2284 SMB_VFS_SYS_ACL_FREE_QUALIFIER(conn, (void *)pgid,tagtype);
2285 SCVAL(pdata,0,SMB_POSIX_ACL_GROUP);
2286 SIVAL(pdata,2,own_grp);
2291 SCVAL(pdata,0,SMB_POSIX_ACL_MASK);
2292 SIVAL(pdata,2,0xFFFFFFFF);
2293 SIVAL(pdata,6,0xFFFFFFFF);
2296 SCVAL(pdata,0,SMB_POSIX_ACL_OTHER);
2297 SIVAL(pdata,2,0xFFFFFFFF);
2298 SIVAL(pdata,6,0xFFFFFFFF);
2301 DEBUG(0,("marshall_posix_acl: unknown tagtype.\n"));
2304 pdata += SMB_POSIX_ACL_ENTRY_SIZE;
2310 /****************************************************************************
2311 Reply to a TRANS2_QFILEPATHINFO or TRANSACT2_QFILEINFO (query file info by
2312 file name or file id).
2313 ****************************************************************************/
2315 static int call_trans2qfilepathinfo(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize,
2316 char **pparams, int total_params, char **ppdata, int total_data,
2317 unsigned int max_data_bytes)
2319 char *params = *pparams;
2320 char *pdata = *ppdata;
2321 uint16 tran_call = SVAL(inbuf, smb_setup0);
2324 SMB_OFF_T file_size=0;
2325 SMB_BIG_UINT allocation_size=0;
2326 unsigned int data_size;
2327 unsigned int param_size = 2;
2328 SMB_STRUCT_STAT sbuf;
2329 pstring fname, dos_fname;
2334 BOOL bad_path = False;
2335 BOOL delete_pending = False;
2338 files_struct *fsp = NULL;
2339 uint32 desired_access = 0x12019F; /* Default - GENERIC_EXECUTE mapping from Windows */
2342 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
2346 if (tran_call == TRANSACT2_QFILEINFO) {
2347 if (total_params < 4)
2348 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
2350 fsp = file_fsp(params,0);
2351 info_level = SVAL(params,2);
2353 DEBUG(3,("call_trans2qfilepathinfo: TRANSACT2_QFILEINFO: level = %d\n", info_level));
2355 if(fsp && (fsp->fake_file_handle)) {
2357 * This is actually for the QUOTA_FAKE_FILE --metze
2360 pstrcpy(fname, fsp->fsp_name);
2361 /* We know this name is ok, it's already passed the checks. */
2363 } else if(fsp && (fsp->is_directory || fsp->fd == -1)) {
2365 * This is actually a QFILEINFO on a directory
2366 * handle (returned from an NT SMB). NT5.0 seems
2367 * to do this call. JRA.
2369 /* We know this name is ok, it's already passed the checks. */
2370 pstrcpy(fname, fsp->fsp_name);
2372 if (INFO_LEVEL_IS_UNIX(info_level)) {
2373 /* Always do lstat for UNIX calls. */
2374 if (SMB_VFS_LSTAT(conn,fname,&sbuf)) {
2375 DEBUG(3,("call_trans2qfilepathinfo: SMB_VFS_LSTAT of %s failed (%s)\n",fname,strerror(errno)));
2376 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRbadpath);
2378 } else if (SMB_VFS_STAT(conn,fname,&sbuf)) {
2379 DEBUG(3,("call_trans2qfilepathinfo: SMB_VFS_STAT of %s failed (%s)\n",fname,strerror(errno)));
2380 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRbadpath);
2383 delete_pending = fsp->is_directory ? fsp->directory_delete_on_close : 0;
2386 * Original code - this is an open file.
2388 CHECK_FSP(fsp,conn);
2390 pstrcpy(fname, fsp->fsp_name);
2391 if (SMB_VFS_FSTAT(fsp,fsp->fd,&sbuf) != 0) {
2392 DEBUG(3,("fstat of fnum %d failed (%s)\n", fsp->fnum, strerror(errno)));
2393 return(UNIXERROR(ERRDOS,ERRbadfid));
2395 pos = fsp->position_information;
2396 delete_pending = fsp->delete_on_close;
2397 desired_access = fsp->desired_access;
2400 NTSTATUS status = NT_STATUS_OK;
2403 if (total_params < 6)
2404 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
2406 info_level = SVAL(params,0);
2408 DEBUG(3,("call_trans2qfilepathinfo: TRANSACT2_QPATHINFO: level = %d\n", info_level));
2410 srvstr_get_path(inbuf, fname, ¶ms[6], sizeof(fname), -1, STR_TERMINATE, &status, False);
2411 if (!NT_STATUS_IS_OK(status)) {
2412 return ERROR_NT(status);
2415 RESOLVE_DFSPATH(fname, conn, inbuf, outbuf);
2417 unix_convert(fname,conn,0,&bad_path,&sbuf);
2419 return ERROR_NT(NT_STATUS_OBJECT_PATH_NOT_FOUND);
2421 if (!check_name(fname,conn)) {
2422 DEBUG(3,("call_trans2qfilepathinfo: fileinfo of %s failed (%s)\n",fname,strerror(errno)));
2423 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRbadpath);
2426 if (INFO_LEVEL_IS_UNIX(info_level)) {
2427 /* Always do lstat for UNIX calls. */
2428 if (SMB_VFS_LSTAT(conn,fname,&sbuf)) {
2429 DEBUG(3,("call_trans2qfilepathinfo: SMB_VFS_LSTAT of %s failed (%s)\n",fname,strerror(errno)));
2430 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRbadpath);
2432 } else if (!VALID_STAT(sbuf) && SMB_VFS_STAT(conn,fname,&sbuf) && (info_level != SMB_INFO_IS_NAME_VALID)) {
2433 DEBUG(3,("call_trans2qfilepathinfo: SMB_VFS_STAT of %s failed (%s)\n",fname,strerror(errno)));
2434 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRbadpath);
2438 if (INFO_LEVEL_IS_UNIX(info_level) && !lp_unix_extensions())
2439 return ERROR_DOS(ERRDOS,ERRunknownlevel);
2441 DEBUG(3,("call_trans2qfilepathinfo %s (fnum = %d) level=%d call=%d total_data=%d\n",
2442 fname,fsp ? fsp->fnum : -1, info_level,tran_call,total_data));
2444 p = strrchr_m(fname,'/');
2450 mode = dos_mode(conn,fname,&sbuf);
2452 mode = FILE_ATTRIBUTE_NORMAL;
2454 fullpathname = fname;
2455 file_size = get_file_size(sbuf);
2456 allocation_size = get_allocation_size(fsp,&sbuf);
2458 /* This is necessary, as otherwise the desktop.ini file in
2459 * this folder is ignored */
2460 mode |= (lp_profile_acls(SNUM(conn)) ? aRONLY : 0);
2464 params = SMB_REALLOC(*pparams,2);
2466 return ERROR_DOS(ERRDOS,ERRnomem);
2468 memset((char *)params,'\0',2);
2469 data_size = max_data_bytes + DIR_ENTRY_SAFETY_MARGIN;
2470 pdata = SMB_REALLOC(*ppdata, data_size);
2471 if ( pdata == NULL )
2472 return ERROR_DOS(ERRDOS,ERRnomem);
2475 if (total_data > 0 && IVAL(pdata,0) == total_data) {
2476 /* uggh, EAs for OS2 */
2477 DEBUG(4,("Rejecting EA request with total_data=%d\n",total_data));
2478 return ERROR_DOS(ERRDOS,ERReasnotsupported);
2481 memset((char *)pdata,'\0',data_size);
2483 c_time = get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(conn)));
2485 if (fsp && fsp->pending_modtime) {
2486 /* the pending modtime overrides the current modtime */
2487 sbuf.st_mtime = fsp->pending_modtime;
2490 if (lp_dos_filetime_resolution(SNUM(conn))) {
2492 sbuf.st_atime &= ~1;
2493 sbuf.st_ctime &= ~1;
2494 sbuf.st_mtime &= ~1;
2497 /* NT expects the name to be in an exact form of the *full*
2498 filename. See the trans2 torture test */
2499 if (strequal(base_name,".")) {
2500 pstrcpy(dos_fname, "\\");
2502 pstr_sprintf(dos_fname, "\\%s", fname);
2503 string_replace(dos_fname, '/', '\\');
2506 switch (info_level) {
2507 case SMB_INFO_STANDARD:
2508 DEBUG(10,("call_trans2qfilepathinfo: SMB_INFO_STANDARD\n"));
2510 put_dos_date2(pdata,l1_fdateCreation,c_time);
2511 put_dos_date2(pdata,l1_fdateLastAccess,sbuf.st_atime);
2512 put_dos_date2(pdata,l1_fdateLastWrite,sbuf.st_mtime); /* write time */
2513 SIVAL(pdata,l1_cbFile,(uint32)file_size);
2514 SIVAL(pdata,l1_cbFileAlloc,(uint32)allocation_size);
2515 SSVAL(pdata,l1_attrFile,mode);
2518 case SMB_INFO_QUERY_EA_SIZE:
2520 unsigned int ea_size = estimate_ea_size(conn, fsp, fname);
2521 DEBUG(10,("call_trans2qfilepathinfo: SMB_INFO_QUERY_EA_SIZE\n"));
2523 put_dos_date2(pdata,l1_fdateCreation,c_time);
2524 put_dos_date2(pdata,l1_fdateLastAccess,sbuf.st_atime);
2525 put_dos_date2(pdata,l1_fdateLastWrite,sbuf.st_mtime); /* write time */
2526 SIVAL(pdata,l1_cbFile,(uint32)file_size);
2527 SIVAL(pdata,l1_cbFileAlloc,(uint32)allocation_size);
2528 SSVAL(pdata,l1_attrFile,mode);
2529 SIVAL(pdata,l1_attrFile+2,ea_size);
2533 case SMB_INFO_IS_NAME_VALID:
2534 DEBUG(10,("call_trans2qfilepathinfo: SMB_INFO_IS_NAME_VALID\n"));
2535 if (tran_call == TRANSACT2_QFILEINFO) {
2536 /* os/2 needs this ? really ?*/
2537 return ERROR_DOS(ERRDOS,ERRbadfunc);
2543 case SMB_INFO_QUERY_EAS_FROM_LIST:
2544 DEBUG(10,("call_trans2qfilepathinfo: SMB_INFO_QUERY_EAS_FROM_LIST\n"));
2546 put_dos_date2(pdata,0,c_time);
2547 put_dos_date2(pdata,4,sbuf.st_atime);
2548 put_dos_date2(pdata,8,sbuf.st_mtime);
2549 SIVAL(pdata,12,(uint32)file_size);
2550 SIVAL(pdata,16,(uint32)allocation_size);
2551 SIVAL(pdata,20,mode);
2554 case SMB_INFO_QUERY_ALL_EAS:
2555 DEBUG(10,("call_trans2qfilepathinfo: SMB_INFO_QUERY_ALL_EAS\n"));
2556 /* We have data_size bytes to put EA's into. */
2557 data_size = fill_ea_buffer(pdata, data_size, conn, fsp, fname);
2560 case SMB_FILE_BASIC_INFORMATION:
2561 case SMB_QUERY_FILE_BASIC_INFO:
2563 if (info_level == SMB_QUERY_FILE_BASIC_INFO) {
2564 DEBUG(10,("call_trans2qfilepathinfo: SMB_QUERY_FILE_BASIC_INFO\n"));
2565 data_size = 36; /* w95 returns 40 bytes not 36 - why ?. */
2567 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_BASIC_INFORMATION\n"));
2571 put_long_date(pdata,c_time);
2572 put_long_date(pdata+8,sbuf.st_atime);
2573 put_long_date(pdata+16,sbuf.st_mtime); /* write time */
2574 put_long_date(pdata+24,sbuf.st_mtime); /* change time */
2575 SIVAL(pdata,32,mode);
2577 DEBUG(5,("SMB_QFBI - "));
2579 time_t create_time = c_time;
2580 DEBUG(5,("create: %s ", ctime(&create_time)));
2582 DEBUG(5,("access: %s ", ctime(&sbuf.st_atime)));
2583 DEBUG(5,("write: %s ", ctime(&sbuf.st_mtime)));
2584 DEBUG(5,("change: %s ", ctime(&sbuf.st_mtime)));
2585 DEBUG(5,("mode: %x\n", mode));
2589 case SMB_FILE_STANDARD_INFORMATION:
2590 case SMB_QUERY_FILE_STANDARD_INFO:
2592 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_STANDARD_INFORMATION\n"));
2594 SOFF_T(pdata,0,allocation_size);
2595 SOFF_T(pdata,8,file_size);
2596 if (delete_pending & sbuf.st_nlink)
2597 SIVAL(pdata,16,sbuf.st_nlink - 1);
2599 SIVAL(pdata,16,sbuf.st_nlink);
2601 SCVAL(pdata,21,(mode&aDIR)?1:0);
2604 case SMB_FILE_EA_INFORMATION:
2605 case SMB_QUERY_FILE_EA_INFO:
2607 unsigned int ea_size = estimate_ea_size(conn, fsp, fname);
2608 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_EA_INFORMATION\n"));
2610 SIVAL(pdata,0,ea_size);
2614 /* Get the 8.3 name - used if NT SMB was negotiated. */
2615 case SMB_QUERY_FILE_ALT_NAME_INFO:
2616 case SMB_FILE_ALTERNATE_NAME_INFORMATION:
2620 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_ALTERNATE_NAME_INFORMATION\n"));
2621 pstrcpy(short_name,base_name);
2622 /* Mangle if not already 8.3 */
2623 if(!mangle_is_8_3(short_name, True)) {
2624 mangle_map(short_name,True,True,SNUM(conn));
2626 len = srvstr_push(outbuf, pdata+4, short_name, -1, STR_UNICODE);
2627 data_size = 4 + len;
2632 case SMB_QUERY_FILE_NAME_INFO:
2634 this must be *exactly* right for ACLs on mapped drives to work
2636 len = srvstr_push(outbuf, pdata+4, dos_fname, -1, STR_UNICODE);
2637 DEBUG(10,("call_trans2qfilepathinfo: SMB_QUERY_FILE_NAME_INFO\n"));
2638 data_size = 4 + len;
2642 case SMB_FILE_ALLOCATION_INFORMATION:
2643 case SMB_QUERY_FILE_ALLOCATION_INFO:
2644 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_ALLOCATION_INFORMATION\n"));
2646 SOFF_T(pdata,0,allocation_size);
2649 case SMB_FILE_END_OF_FILE_INFORMATION:
2650 case SMB_QUERY_FILE_END_OF_FILEINFO:
2651 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_END_OF_FILE_INFORMATION\n"));
2653 SOFF_T(pdata,0,file_size);
2656 case SMB_QUERY_FILE_ALL_INFO:
2657 case SMB_FILE_ALL_INFORMATION:
2659 unsigned int ea_size = estimate_ea_size(conn, fsp, fname);
2660 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_ALL_INFORMATION\n"));
2661 put_long_date(pdata,c_time);
2662 put_long_date(pdata+8,sbuf.st_atime);
2663 put_long_date(pdata+16,sbuf.st_mtime); /* write time */
2664 put_long_date(pdata+24,sbuf.st_mtime); /* change time */
2665 SIVAL(pdata,32,mode);
2667 SOFF_T(pdata,0,allocation_size);
2668 SOFF_T(pdata,8,file_size);
2669 if (delete_pending && sbuf.st_nlink)
2670 SIVAL(pdata,16,sbuf.st_nlink - 1);
2672 SIVAL(pdata,16,sbuf.st_nlink);
2673 SCVAL(pdata,20,delete_pending);
2674 SCVAL(pdata,21,(mode&aDIR)?1:0);
2676 SIVAL(pdata,0,ea_size);
2677 pdata += 4; /* EA info */
2678 len = srvstr_push(outbuf, pdata+4, dos_fname, -1, STR_UNICODE);
2681 data_size = PTR_DIFF(pdata,(*ppdata));
2684 case SMB_FILE_INTERNAL_INFORMATION:
2685 /* This should be an index number - looks like
2688 I think this causes us to fail the IFSKIT
2689 BasicFileInformationTest. -tpot */
2691 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_INTERNAL_INFORMATION\n"));
2692 SIVAL(pdata,0,sbuf.st_dev);
2693 SIVAL(pdata,4,sbuf.st_ino);
2697 case SMB_FILE_ACCESS_INFORMATION:
2698 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_ACCESS_INFORMATION\n"));
2699 SIVAL(pdata,0,desired_access);
2703 case SMB_FILE_NAME_INFORMATION:
2704 /* Pathname with leading '\'. */
2707 byte_len = dos_PutUniCode(pdata+4,dos_fname,max_data_bytes,False);
2708 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_NAME_INFORMATION\n"));
2709 SIVAL(pdata,0,byte_len);
2710 data_size = 4 + byte_len;
2714 case SMB_FILE_DISPOSITION_INFORMATION:
2715 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_DISPOSITION_INFORMATION\n"));
2717 SCVAL(pdata,0,delete_pending);
2720 case SMB_FILE_POSITION_INFORMATION:
2721 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_POSITION_INFORMATION\n"));
2723 SOFF_T(pdata,0,pos);
2726 case SMB_FILE_MODE_INFORMATION:
2727 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_MODE_INFORMATION\n"));
2728 SIVAL(pdata,0,mode);
2732 case SMB_FILE_ALIGNMENT_INFORMATION:
2733 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_ALIGNMENT_INFORMATION\n"));
2734 SIVAL(pdata,0,0); /* No alignment needed. */
2740 * NT4 server just returns "invalid query" to this - if we try to answer
2741 * it then NTws gets a BSOD! (tridge).
2742 * W2K seems to want this. JRA.
2744 case SMB_QUERY_FILE_STREAM_INFO:
2746 case SMB_FILE_STREAM_INFORMATION:
2747 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_STREAM_INFORMATION\n"));
2751 size_t byte_len = dos_PutUniCode(pdata+24,"::$DATA", 0xE, False);
2752 SIVAL(pdata,0,0); /* ??? */
2753 SIVAL(pdata,4,byte_len); /* Byte length of unicode string ::$DATA */
2754 SOFF_T(pdata,8,file_size);
2755 SIVAL(pdata,16,allocation_size);
2756 SIVAL(pdata,20,0); /* ??? */
2757 data_size = 24 + byte_len;
2761 case SMB_QUERY_COMPRESSION_INFO:
2762 case SMB_FILE_COMPRESSION_INFORMATION:
2763 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_COMPRESSION_INFORMATION\n"));
2764 SOFF_T(pdata,0,file_size);
2765 SIVAL(pdata,8,0); /* ??? */
2766 SIVAL(pdata,12,0); /* ??? */
2770 case SMB_FILE_NETWORK_OPEN_INFORMATION:
2771 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_NETWORK_OPEN_INFORMATION\n"));
2772 put_long_date(pdata,c_time);
2773 put_long_date(pdata+8,sbuf.st_atime);
2774 put_long_date(pdata+16,sbuf.st_mtime); /* write time */
2775 put_long_date(pdata+24,sbuf.st_mtime); /* change time */
2776 SIVAL(pdata,32,allocation_size);
2777 SOFF_T(pdata,40,file_size);
2778 SIVAL(pdata,48,mode);
2779 SIVAL(pdata,52,0); /* ??? */
2783 case SMB_FILE_ATTRIBUTE_TAG_INFORMATION:
2784 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_ATTRIBUTE_TAG_INFORMATION\n"));
2785 SIVAL(pdata,0,mode);
2791 * CIFS UNIX Extensions.
2794 case SMB_QUERY_FILE_UNIX_BASIC:
2796 DEBUG(10,("call_trans2qfilepathinfo: SMB_QUERY_FILE_UNIX_BASIC\n"));
2797 DEBUG(4,("call_trans2qfilepathinfo: st_mode=%o\n",(int)sbuf.st_mode));
2799 SOFF_T(pdata,0,get_file_size(sbuf)); /* File size 64 Bit */
2802 SOFF_T(pdata,0,get_allocation_size(fsp,&sbuf)); /* Number of bytes used on disk - 64 Bit */
2805 put_long_date(pdata,sbuf.st_ctime); /* Creation Time 64 Bit */
2806 put_long_date(pdata+8,sbuf.st_atime); /* Last access time 64 Bit */
2807 put_long_date(pdata+16,sbuf.st_mtime); /* Last modification time 64 Bit */
2810 SIVAL(pdata,0,sbuf.st_uid); /* user id for the owner */
2814 SIVAL(pdata,0,sbuf.st_gid); /* group id of owner */
2818 SIVAL(pdata,0,unix_filetype(sbuf.st_mode));
2821 SIVAL(pdata,0,unix_dev_major(sbuf.st_rdev)); /* Major device number if type is device */
2825 SIVAL(pdata,0,unix_dev_minor(sbuf.st_rdev)); /* Minor device number if type is device */
2829 SINO_T(pdata,0,(SMB_INO_T)sbuf.st_ino); /* inode number */
2832 SIVAL(pdata,0, unix_perms_to_wire(sbuf.st_mode)); /* Standard UNIX file permissions */
2836 SIVAL(pdata,0,sbuf.st_nlink); /* number of hard links */
2839 data_size = PTR_DIFF(pdata,(*ppdata));
2843 DEBUG(4,("call_trans2qfilepathinfo: SMB_QUERY_FILE_UNIX_BASIC"));
2845 for (i=0; i<100; i++)
2846 DEBUG(4,("%d=%x, ",i, (*ppdata)[i]));
2852 case SMB_QUERY_FILE_UNIX_LINK:
2856 DEBUG(10,("call_trans2qfilepathinfo: SMB_QUERY_FILE_UNIX_LINK\n"));
2858 if(!S_ISLNK(sbuf.st_mode))
2859 return(UNIXERROR(ERRSRV,ERRbadlink));
2861 return(UNIXERROR(ERRDOS,ERRbadlink));
2863 len = SMB_VFS_READLINK(conn,fullpathname, buffer, sizeof(pstring)-1); /* read link */
2865 return(UNIXERROR(ERRDOS,ERRnoaccess));
2867 len = srvstr_push(outbuf, pdata, buffer, -1, STR_TERMINATE);
2869 data_size = PTR_DIFF(pdata,(*ppdata));
2874 case SMB_QUERY_POSIX_ACL:
2876 SMB_ACL_T file_acl = NULL;
2877 SMB_ACL_T def_acl = NULL;
2878 uint16 num_file_acls = 0;
2879 uint16 num_def_acls = 0;
2881 if (fsp && !fsp->is_directory && (fsp->fd != -1)) {
2882 file_acl = SMB_VFS_SYS_ACL_GET_FD(fsp, fsp->fd);
2884 file_acl = SMB_VFS_SYS_ACL_GET_FILE(conn, fname, SMB_ACL_TYPE_ACCESS);
2887 if (file_acl == NULL && no_acl_syscall_error(errno)) {
2888 DEBUG(5,("call_trans2qfilepathinfo: ACLs not implemented on filesystem containing %s\n",
2890 return ERROR_NT(NT_STATUS_NOT_IMPLEMENTED);
2893 if (S_ISDIR(sbuf.st_mode)) {
2894 if (fsp && fsp->is_directory) {
2895 def_acl = SMB_VFS_SYS_ACL_GET_FILE(conn, fsp->fsp_name, SMB_ACL_TYPE_DEFAULT);
2897 def_acl = SMB_VFS_SYS_ACL_GET_FILE(conn, fname, SMB_ACL_TYPE_DEFAULT);
2899 def_acl = free_empty_sys_acl(conn, def_acl);
2902 num_file_acls = count_acl_entries(conn, file_acl);
2903 num_def_acls = count_acl_entries(conn, def_acl);
2905 if ( data_size < (num_file_acls + num_def_acls)*SMB_POSIX_ACL_ENTRY_SIZE + SMB_POSIX_ACL_HEADER_SIZE) {
2906 DEBUG(5,("call_trans2qfilepathinfo: data_size too small (%u) need %u\n",
2908 (unsigned int)((num_file_acls + num_def_acls)*SMB_POSIX_ACL_ENTRY_SIZE +
2909 SMB_POSIX_ACL_HEADER_SIZE) ));
2911 SMB_VFS_SYS_ACL_FREE_ACL(conn, file_acl);
2914 SMB_VFS_SYS_ACL_FREE_ACL(conn, def_acl);
2916 return ERROR_NT(NT_STATUS_BUFFER_TOO_SMALL);
2919 SSVAL(pdata,0,SMB_POSIX_ACL_VERSION);
2920 SSVAL(pdata,2,num_file_acls);
2921 SSVAL(pdata,4,num_def_acls);
2922 if (!marshall_posix_acl(conn, pdata + SMB_POSIX_ACL_HEADER_SIZE, &sbuf, file_acl)) {
2924 SMB_VFS_SYS_ACL_FREE_ACL(conn, file_acl);
2927 SMB_VFS_SYS_ACL_FREE_ACL(conn, def_acl);
2929 return ERROR_NT(NT_STATUS_INTERNAL_ERROR);
2931 if (!marshall_posix_acl(conn, pdata + SMB_POSIX_ACL_HEADER_SIZE + (num_file_acls*SMB_POSIX_ACL_ENTRY_SIZE), &sbuf, def_acl)) {
2933 SMB_VFS_SYS_ACL_FREE_ACL(conn, file_acl);
2936 SMB_VFS_SYS_ACL_FREE_ACL(conn, def_acl);
2938 return ERROR_NT(NT_STATUS_INTERNAL_ERROR);
2942 SMB_VFS_SYS_ACL_FREE_ACL(conn, file_acl);
2945 SMB_VFS_SYS_ACL_FREE_ACL(conn, def_acl);
2947 data_size = (num_file_acls + num_def_acls)*SMB_POSIX_ACL_ENTRY_SIZE + SMB_POSIX_ACL_HEADER_SIZE;
2952 return ERROR_DOS(ERRDOS,ERRunknownlevel);
2955 send_trans2_replies(outbuf, bufsize, params, param_size, *ppdata, data_size);
2960 /****************************************************************************
2961 Deal with the internal needs of setting the delete on close flag. Note that
2962 as the tdb locking is recursive, it is safe to call this from within
2963 open_file_shared. JRA.
2964 ****************************************************************************/
2966 NTSTATUS set_delete_on_close_internal(files_struct *fsp, BOOL delete_on_close, uint32 dosmode)
2968 if (delete_on_close) {
2970 * Only allow delete on close for writable files.
2973 if (dosmode & aRONLY) {
2974 DEBUG(10,("set_delete_on_close_internal: file %s delete on close flag set but file attribute is readonly.\n",
2976 return NT_STATUS_CANNOT_DELETE;
2980 * Only allow delete on close for writable shares.
2983 if (!CAN_WRITE(fsp->conn)) {
2984 DEBUG(10,("set_delete_on_close_internal: file %s delete on close flag set but write access denied on share.\n",
2986 return NT_STATUS_ACCESS_DENIED;
2990 * Only allow delete on close for files/directories opened with delete intent.
2993 if (!(fsp->desired_access & DELETE_ACCESS)) {
2994 DEBUG(10,("set_delete_on_close_internal: file %s delete on close flag set but delete access denied.\n",
2996 return NT_STATUS_ACCESS_DENIED;
3000 if(fsp->is_directory) {
3001 fsp->directory_delete_on_close = delete_on_close;
3002 DEBUG(10, ("set_delete_on_close_internal: %s delete on close flag for fnum = %d, directory %s\n",
3003 delete_on_close ? "Added" : "Removed", fsp->fnum, fsp->fsp_name ));
3005 fsp->delete_on_close = delete_on_close;
3006 DEBUG(10, ("set_delete_on_close_internal: %s delete on close flag for fnum = %d, file %s\n",
3007 delete_on_close ? "Added" : "Removed", fsp->fnum, fsp->fsp_name ));
3010 return NT_STATUS_OK;
3013 /****************************************************************************
3014 Sets the delete on close flag over all share modes on this file.
3015 Modify the share mode entry for all files open
3016 on this device and inode to tell other smbds we have
3017 changed the delete on close flag. This will be noticed
3018 in the close code, the last closer will delete the file
3020 ****************************************************************************/
3022 NTSTATUS set_delete_on_close_over_all(files_struct *fsp, BOOL delete_on_close)
3024 DEBUG(10,("set_delete_on_close_over_all: %s delete on close flag for fnum = %d, file %s\n",
3025 delete_on_close ? "Adding" : "Removing", fsp->fnum, fsp->fsp_name ));
3027 if (fsp->is_directory || fsp->is_stat)
3028 return NT_STATUS_OK;
3030 if (lock_share_entry_fsp(fsp) == False)
3031 return NT_STATUS_ACCESS_DENIED;
3033 if (!modify_delete_flag(fsp->dev, fsp->inode, delete_on_close)) {
3034 DEBUG(0,("set_delete_on_close_over_all: failed to change delete on close flag for file %s\n",
3036 unlock_share_entry_fsp(fsp);
3037 return NT_STATUS_ACCESS_DENIED;
3040 unlock_share_entry_fsp(fsp);
3041 return NT_STATUS_OK;
3044 /****************************************************************************
3045 Set a hard link (called by UNIX extensions and by NT rename with HARD link
3047 ****************************************************************************/
3049 NTSTATUS hardlink_internals(connection_struct *conn, char *oldname, char *newname)
3051 BOOL bad_path_oldname = False;
3052 BOOL bad_path_newname = False;
3053 SMB_STRUCT_STAT sbuf1, sbuf2;
3054 pstring last_component_oldname;
3055 pstring last_component_newname;
3056 NTSTATUS status = NT_STATUS_OK;
3062 if (ms_has_wild(newname) || ms_has_wild(oldname)) {
3063 return NT_STATUS_OBJECT_PATH_SYNTAX_BAD;
3066 unix_convert(oldname,conn,last_component_oldname,&bad_path_oldname,&sbuf1);
3067 if (bad_path_oldname) {
3068 return NT_STATUS_OBJECT_PATH_NOT_FOUND;
3071 /* Quick check for "." and ".." */
3072 if (last_component_oldname[0] == '.') {
3073 if (!last_component_oldname[1] || (last_component_oldname[1] == '.' && !last_component_oldname[2])) {
3074 return NT_STATUS_OBJECT_NAME_INVALID;
3078 /* source must already exist. */
3079 if (!VALID_STAT(sbuf1)) {
3080 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3083 if (!check_name(oldname,conn)) {
3084 return NT_STATUS_ACCESS_DENIED;
3087 unix_convert(newname,conn,last_component_newname,&bad_path_newname,&sbuf2);
3088 if (bad_path_newname) {
3089 return NT_STATUS_OBJECT_PATH_NOT_FOUND;
3092 /* Quick check for "." and ".." */
3093 if (last_component_newname[0] == '.') {
3094 if (!last_component_newname[1] || (last_component_newname[1] == '.' && !last_component_newname[2])) {
3095 return NT_STATUS_OBJECT_NAME_INVALID;
3099 /* Disallow if newname already exists. */
3100 if (VALID_STAT(sbuf2)) {
3101 return NT_STATUS_OBJECT_NAME_COLLISION;
3104 if (!check_name(newname,conn)) {
3105 return NT_STATUS_ACCESS_DENIED;
3108 /* No links from a directory. */
3109 if (S_ISDIR(sbuf1.st_mode)) {
3110 return NT_STATUS_FILE_IS_A_DIRECTORY;
3113 /* Ensure this is within the share. */
3114 if (!reduce_name(conn, oldname) != 0)
3115 return NT_STATUS_ACCESS_DENIED;
3117 DEBUG(10,("hardlink_internals: doing hard link %s -> %s\n", newname, oldname ));
3119 if (SMB_VFS_LINK(conn,oldname,newname) != 0) {
3120 status = map_nt_error_from_unix(errno);
3121 DEBUG(3,("hardlink_internals: Error %s hard link %s -> %s\n",
3122 nt_errstr(status), newname, oldname));
3128 /****************************************************************************
3129 Reply to a TRANS2_SETFILEINFO (set file info by fileid).
3130 ****************************************************************************/
3132 static int call_trans2setfilepathinfo(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize,
3133 char **pparams, int total_params, char **ppdata, int total_data,
3134 unsigned int max_data_bytes)
3136 char *params = *pparams;
3137 char *pdata = *ppdata;
3138 uint16 tran_call = SVAL(inbuf, smb_setup0);
3143 SMB_STRUCT_STAT sbuf;
3146 BOOL bad_path = False;
3147 files_struct *fsp = NULL;
3148 uid_t set_owner = (uid_t)SMB_UID_NO_CHANGE;
3149 gid_t set_grp = (uid_t)SMB_GID_NO_CHANGE;
3150 mode_t unixmode = 0;
3151 NTSTATUS status = NT_STATUS_OK;
3154 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
3158 if (tran_call == TRANSACT2_SETFILEINFO) {
3159 if (total_params < 4)
3160 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
3162 fsp = file_fsp(params,0);
3163 info_level = SVAL(params,2);
3165 if(fsp && (fsp->is_directory || fsp->fd == -1)) {
3167 * This is actually a SETFILEINFO on a directory
3168 * handle (returned from an NT SMB). NT5.0 seems
3169 * to do this call. JRA.
3171 pstrcpy(fname, fsp->fsp_name);
3172 if (SMB_VFS_STAT(conn,fname,&sbuf) != 0) {
3173 DEBUG(3,("call_trans2setfilepathinfo: fileinfo of %s failed (%s)\n",fname,strerror(errno)));
3174 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRbadpath);
3176 } else if (fsp && fsp->print_file) {
3178 * Doing a DELETE_ON_CLOSE should cancel a print job.
3180 if ((info_level == SMB_SET_FILE_DISPOSITION_INFO) && CVAL(pdata,0)) {
3181 fsp->share_mode = FILE_DELETE_ON_CLOSE;
3183 DEBUG(3,("call_trans2setfilepathinfo: Cancelling print job (%s)\n", fsp->fsp_name ));
3186 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
3189 return (UNIXERROR(ERRDOS,ERRbadpath));
3192 * Original code - this is an open file.
3194 CHECK_FSP(fsp,conn);
3196 pstrcpy(fname, fsp->fsp_name);
3199 if (SMB_VFS_FSTAT(fsp,fd,&sbuf) != 0) {
3200 DEBUG(3,("call_trans2setfilepathinfo: fstat of fnum %d failed (%s)\n",fsp->fnum, strerror(errno)));
3201 return(UNIXERROR(ERRDOS,ERRbadfid));
3206 if (total_params < 6)
3207 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
3209 info_level = SVAL(params,0);
3210 srvstr_get_path(inbuf, fname, ¶ms[6], sizeof(fname), -1, STR_TERMINATE, &status, False);
3211 if (!NT_STATUS_IS_OK(status)) {
3212 return ERROR_NT(status);
3214 unix_convert(fname,conn,0,&bad_path,&sbuf);
3216 return ERROR_NT(NT_STATUS_OBJECT_PATH_NOT_FOUND);
3220 * For CIFS UNIX extensions the target name may not exist.
3223 if(!VALID_STAT(sbuf) && !INFO_LEVEL_IS_UNIX(info_level)) {
3224 DEBUG(3,("call_trans2setfilepathinfo: stat of %s failed (%s)\n", fname, strerror(errno)));
3225 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRbadpath);
3228 if(!check_name(fname, conn)) {
3229 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRbadpath);
3234 if (!CAN_WRITE(conn))
3235 return ERROR_DOS(ERRSRV,ERRaccess);
3237 if (INFO_LEVEL_IS_UNIX(info_level) && !lp_unix_extensions())
3238 return ERROR_DOS(ERRDOS,ERRunknownlevel);
3240 if (VALID_STAT(sbuf))
3241 unixmode = sbuf.st_mode;
3243 DEBUG(3,("call_trans2setfilepathinfo(%d) %s (fnum %d) info_level=%d totdata=%d\n",
3244 tran_call,fname, fsp ? fsp->fnum : -1, info_level,total_data));
3246 /* Realloc the parameter and data sizes */
3247 params = SMB_REALLOC(*pparams,2);
3249 return ERROR_DOS(ERRDOS,ERRnomem);
3254 if (fsp && fsp->pending_modtime) {
3255 /* the pending modtime overrides the current modtime */
3256 sbuf.st_mtime = fsp->pending_modtime;
3259 size = get_file_size(sbuf);
3260 tvs.modtime = sbuf.st_mtime;
3261 tvs.actime = sbuf.st_atime;
3262 dosmode = dos_mode(conn,fname,&sbuf);
3263 unixmode = sbuf.st_mode;
3265 set_owner = VALID_STAT(sbuf) ? sbuf.st_uid : (uid_t)SMB_UID_NO_CHANGE;
3266 set_grp = VALID_STAT(sbuf) ? sbuf.st_gid : (gid_t)SMB_GID_NO_CHANGE;
3268 switch (info_level) {
3269 case SMB_INFO_STANDARD:
3271 if (total_data < 12)
3272 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
3275 tvs.actime = make_unix_date2(pdata+l1_fdateLastAccess);
3277 tvs.modtime = make_unix_date2(pdata+l1_fdateLastWrite);
3281 case SMB_INFO_SET_EA:
3282 status = set_ea(conn, fsp, fname, pdata, total_data);
3283 if (NT_STATUS_V(status) != NT_STATUS_V(NT_STATUS_OK))
3284 return ERROR_NT(status);
3287 /* XXXX um, i don't think this is right.
3288 it's also not in the cifs6.txt spec.
3290 case SMB_INFO_QUERY_EAS_FROM_LIST:
3291 if (total_data < 28)
3292 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
3294 tvs.actime = make_unix_date2(pdata+8);
3295 tvs.modtime = make_unix_date2(pdata+12);
3296 size = IVAL(pdata,16);
3297 dosmode = IVAL(pdata,24);
3300 /* XXXX nor this. not in cifs6.txt, either. */
3301 case SMB_INFO_QUERY_ALL_EAS:
3302 if (total_data < 28)
3303 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
3305 tvs.actime = make_unix_date2(pdata+8);
3306 tvs.modtime = make_unix_date2(pdata+12);
3307 size = IVAL(pdata,16);
3308 dosmode = IVAL(pdata,24);
3311 case SMB_SET_FILE_BASIC_INFO:
3312 case SMB_FILE_BASIC_INFORMATION:
3314 /* Patch to do this correctly from Paul Eggert <eggert@twinsun.com>. */
3316 time_t changed_time;
3318 if (total_data < 36)
3319 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
3321 /* Ignore create time at offset pdata. */
3324 tvs.actime = interpret_long_date(pdata+8);
3326 write_time = interpret_long_date(pdata+16);
3327 changed_time = interpret_long_date(pdata+24);
3329 tvs.modtime = MIN(write_time, changed_time);
3331 if (write_time > tvs.modtime && write_time != 0xffffffff) {
3332 tvs.modtime = write_time;
3334 /* Prefer a defined time to an undefined one. */
3335 if (tvs.modtime == (time_t)0 || tvs.modtime == (time_t)-1)
3336 tvs.modtime = (write_time == (time_t)0 || write_time == (time_t)-1
3337 ? changed_time : write_time);
3340 dosmode = IVAL(pdata,32);
3344 case SMB_FILE_ALLOCATION_INFORMATION:
3345 case SMB_SET_FILE_ALLOCATION_INFO:
3348 SMB_BIG_UINT allocation_size;
3351 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
3353 allocation_size = (SMB_BIG_UINT)IVAL(pdata,0);
3354 #ifdef LARGE_SMB_OFF_T
3355 allocation_size |= (((SMB_BIG_UINT)IVAL(pdata,4)) << 32);
3356 #else /* LARGE_SMB_OFF_T */
3357 if (IVAL(pdata,4) != 0) /* more than 32 bits? */
3358 return ERROR_DOS(ERRDOS,ERRunknownlevel);
3359 #endif /* LARGE_SMB_OFF_T */
3360 DEBUG(10,("call_trans2setfilepathinfo: Set file allocation info for file %s to %.0f\n",
3361 fname, (double)allocation_size ));
3363 if (allocation_size)
3364 allocation_size = smb_roundup(allocation_size);
3366 if(allocation_size != get_file_size(sbuf)) {
3367 SMB_STRUCT_STAT new_sbuf;
3369 DEBUG(10,("call_trans2setfilepathinfo: file %s : setting new allocation size to %.0f\n",
3370 fname, (double)allocation_size ));
3373 files_struct *new_fsp = NULL;
3374 int access_mode = 0;
3377 if(global_oplock_break) {
3378 /* Queue this file modify as we are the process of an oplock break. */
3380 DEBUG(2,("call_trans2setfilepathinfo: queueing message due to being "));
3381 DEBUGADD(2,( "in oplock break state.\n"));
3383 push_oplock_pending_smb_message(inbuf, length);
3387 new_fsp = open_file_shared1(conn, fname, &sbuf,FILE_WRITE_DATA,
3388 SET_OPEN_MODE(DOS_OPEN_RDWR),
3389 (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN),
3390 FILE_ATTRIBUTE_NORMAL,
3391 INTERNAL_OPEN_ONLY, &access_mode, &action);
3393 if (new_fsp == NULL)
3394 return(UNIXERROR(ERRDOS,ERRbadpath));
3395 ret = vfs_allocate_file_space(new_fsp, allocation_size);
3396 if (SMB_VFS_FSTAT(new_fsp,new_fsp->fd,&new_sbuf) != 0) {
3397 DEBUG(3,("call_trans2setfilepathinfo: fstat of fnum %d failed (%s)\n",
3398 new_fsp->fnum, strerror(errno)));
3401 close_file(new_fsp,True);
3403 ret = vfs_allocate_file_space(fsp, allocation_size);
3404 if (SMB_VFS_FSTAT(fsp,fd,&new_sbuf) != 0) {
3405 DEBUG(3,("call_trans2setfilepathinfo: fstat of fnum %d failed (%s)\n",
3406 fsp->fnum, strerror(errno)));
3411 return ERROR_NT(NT_STATUS_DISK_FULL);
3413 /* Allocate can truncate size... */
3414 size = get_file_size(new_sbuf);
3420 case SMB_FILE_END_OF_FILE_INFORMATION:
3421 case SMB_SET_FILE_END_OF_FILE_INFO:
3424 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
3426 size = IVAL(pdata,0);
3427 #ifdef LARGE_SMB_OFF_T
3428 size |= (((SMB_OFF_T)IVAL(pdata,4)) << 32);
3429 #else /* LARGE_SMB_OFF_T */
3430 if (IVAL(pdata,4) != 0) /* more than 32 bits? */
3431 return ERROR_DOS(ERRDOS,ERRunknownlevel);
3432 #endif /* LARGE_SMB_OFF_T */
3433 DEBUG(10,("call_trans2setfilepathinfo: Set end of file info for file %s to %.0f\n", fname, (double)size ));
3437 case SMB_FILE_DISPOSITION_INFORMATION:
3438 case SMB_SET_FILE_DISPOSITION_INFO: /* Set delete on close for open file. */
3440 BOOL delete_on_close;
3443 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
3445 delete_on_close = (CVAL(pdata,0) ? True : False);
3447 /* Just ignore this set on a path. */
3448 if (tran_call != TRANSACT2_SETFILEINFO)
3452 return(UNIXERROR(ERRDOS,ERRbadfid));
3454 status = set_delete_on_close_internal(fsp, delete_on_close, dosmode);
3456 if (NT_STATUS_V(status) != NT_STATUS_V(NT_STATUS_OK))
3457 return ERROR_NT(status);
3459 /* The set is across all open files on this dev/inode pair. */
3460 status =set_delete_on_close_over_all(fsp, delete_on_close);
3461 if (NT_STATUS_V(status) != NT_STATUS_V(NT_STATUS_OK))
3462 return ERROR_NT(status);
3467 case SMB_FILE_POSITION_INFORMATION:
3469 SMB_BIG_UINT position_information;
3472 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
3474 position_information = (SMB_BIG_UINT)IVAL(pdata,0);
3475 #ifdef LARGE_SMB_OFF_T
3476 position_information |= (((SMB_BIG_UINT)IVAL(pdata,4)) << 32);
3477 #else /* LARGE_SMB_OFF_T */
3478 if (IVAL(pdata,4) != 0) /* more than 32 bits? */
3479 return ERROR_DOS(ERRDOS,ERRunknownlevel);
3480 #endif /* LARGE_SMB_OFF_T */
3481 DEBUG(10,("call_trans2setfilepathinfo: Set file position information for file %s to %.0f\n",
3482 fname, (double)position_information ));
3484 fsp->position_information = position_information;
3489 * CIFS UNIX extensions.
3492 case SMB_SET_FILE_UNIX_BASIC:
3494 uint32 raw_unixmode;
3496 if (total_data < 100)
3497 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
3499 if(IVAL(pdata, 0) != SMB_SIZE_NO_CHANGE_LO &&
3500 IVAL(pdata, 4) != SMB_SIZE_NO_CHANGE_HI) {
3501 size=IVAL(pdata,0); /* first 8 Bytes are size */
3502 #ifdef LARGE_SMB_OFF_T
3503 size |= (((SMB_OFF_T)IVAL(pdata,4)) << 32);
3504 #else /* LARGE_SMB_OFF_T */
3505 if (IVAL(pdata,4) != 0) /* more than 32 bits? */
3506 return ERROR_DOS(ERRDOS,ERRunknownlevel);
3507 #endif /* LARGE_SMB_OFF_T */
3509 pdata+=24; /* ctime & st_blocks are not changed */
3510 tvs.actime = interpret_long_unix_date(pdata); /* access_time */
3511 tvs.modtime = interpret_long_unix_date(pdata+8); /* modification_time */
3513 set_owner = (uid_t)IVAL(pdata,0);
3515 set_grp = (gid_t)IVAL(pdata,0);
3517 raw_unixmode = IVAL(pdata,28);
3518 unixmode = unix_perms_from_wire(conn, &sbuf, raw_unixmode);
3519 dosmode = 0; /* Ensure dos mode change doesn't override this. */
3521 DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_BASIC: name = %s \
3522 size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n",
3523 fname, (double)size, (unsigned int)set_owner, (unsigned int)set_grp, (int)raw_unixmode));
3525 if (!VALID_STAT(sbuf)) {
3528 * The only valid use of this is to create character and block
3529 * devices, and named pipes. This is deprecated (IMHO) and
3530 * a new info level should be used for mknod. JRA.
3533 uint32 file_type = IVAL(pdata,0);
3534 #if defined(HAVE_MAKEDEV)
3535 uint32 dev_major = IVAL(pdata,4);
3536 uint32 dev_minor = IVAL(pdata,12);
3539 uid_t myuid = geteuid();
3540 gid_t mygid = getegid();
3541 SMB_DEV_T dev = (SMB_DEV_T)0;
3543 if (tran_call == TRANSACT2_SETFILEINFO)
3544 return(ERROR_DOS(ERRDOS,ERRnoaccess));
3546 if (raw_unixmode == SMB_MODE_NO_CHANGE)
3547 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
3549 #if defined(HAVE_MAKEDEV)
3550 dev = makedev(dev_major, dev_minor);
3553 /* We can only create as the owner/group we are. */
3555 if ((set_owner != myuid) && (set_owner != (uid_t)SMB_UID_NO_CHANGE))
3556 return(ERROR_DOS(ERRDOS,ERRnoaccess));
3557 if ((set_grp != mygid) && (set_grp != (gid_t)SMB_GID_NO_CHANGE))
3558 return(ERROR_DOS(ERRDOS,ERRnoaccess));
3560 switch (file_type) {
3561 #if defined(S_IFIFO)
3562 case UNIX_TYPE_FIFO:
3563 unixmode |= S_IFIFO;
3566 #if defined(S_IFSOCK)
3567 case UNIX_TYPE_SOCKET:
3568 unixmode |= S_IFSOCK;
3571 #if defined(S_IFCHR)
3572 case UNIX_TYPE_CHARDEV:
3573 unixmode |= S_IFCHR;
3576 #if defined(S_IFBLK)
3577 case UNIX_TYPE_BLKDEV:
3578 unixmode |= S_IFBLK;
3582 return(ERROR_DOS(ERRDOS,ERRnoaccess));
3585 DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_BASIC doing mknod dev %.0f mode \
3586 0%o for file %s\n", (double)dev, unixmode, fname ));
3588 /* Ok - do the mknod. */
3589 if (SMB_VFS_MKNOD(conn,fname, unixmode, dev) != 0)
3590 return(UNIXERROR(ERRDOS,ERRnoaccess));
3592 inherit_access_acl(conn, fname, unixmode);
3595 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
3600 * Deal with the UNIX specific mode set.
3603 if (raw_unixmode != SMB_MODE_NO_CHANGE) {
3604 DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_BASIC setting mode 0%o for file %s\n",
3605 (unsigned int)unixmode, fname ));
3606 if (SMB_VFS_CHMOD(conn,fname,unixmode) != 0)
3607 return(UNIXERROR(ERRDOS,ERRnoaccess));
3611 * Deal with the UNIX specific uid set.
3614 if ((set_owner != (uid_t)SMB_UID_NO_CHANGE) && (sbuf.st_uid != set_owner)) {
3615 DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_BASIC changing owner %u for file %s\n",
3616 (unsigned int)set_owner, fname ));
3617 if (SMB_VFS_CHOWN(conn,fname,set_owner, (gid_t)-1) != 0)
3618 return(UNIXERROR(ERRDOS,ERRnoaccess));
3622 * Deal with the UNIX specific gid set.
3625 if ((set_grp != (uid_t)SMB_GID_NO_CHANGE) && (sbuf.st_gid != set_grp)) {
3626 DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_BASIC changing group %u for file %s\n",
3627 (unsigned int)set_owner, fname ));
3628 if (SMB_VFS_CHOWN(conn,fname,(uid_t)-1, set_grp) != 0)
3629 return(UNIXERROR(ERRDOS,ERRnoaccess));
3634 case SMB_SET_FILE_UNIX_LINK:
3636 pstring link_target;
3637 char *newname = fname;
3639 /* Set a symbolic link. */
3640 /* Don't allow this if follow links is false. */
3642 if (!lp_symlinks(SNUM(conn)))
3643 return(ERROR_DOS(ERRDOS,ERRnoaccess));
3645 srvstr_pull(inbuf, link_target, pdata, sizeof(link_target), -1, STR_TERMINATE);
3647 /* !widelinks forces the target path to be within the share. */
3648 /* This means we can interpret the target as a pathname. */
3649 if (!lp_widelinks(SNUM(conn))) {
3651 char *last_dirp = NULL;
3653 unix_format(link_target);
3654 if (*link_target == '/') {
3655 /* No absolute paths allowed. */
3656 return(UNIXERROR(ERRDOS,ERRnoaccess));
3658 pstrcpy(rel_name, newname);
3659 last_dirp = strrchr_m(rel_name, '/');
3661 last_dirp[1] = '\0';
3663 pstrcpy(rel_name, "./");
3665 pstrcat(rel_name, link_target);
3667 if (!check_name(rel_name, conn)) {
3668 return(UNIXERROR(ERRDOS,ERRnoaccess));
3672 DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_LINK doing symlink %s -> %s\n",
3673 fname, link_target ));
3675 if (SMB_VFS_SYMLINK(conn,link_target,newname) != 0)
3676 return(UNIXERROR(ERRDOS,ERRnoaccess));
3678 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
3682 case SMB_SET_FILE_UNIX_HLINK:
3685 char *newname = fname;
3687 /* Set a hard link. */
3688 srvstr_get_path(inbuf, oldname, pdata, sizeof(oldname), -1, STR_TERMINATE, &status, False);
3689 if (!NT_STATUS_IS_OK(status)) {
3690 return ERROR_NT(status);
3693 DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_LINK doing hard link %s -> %s\n",
3696 status = hardlink_internals(conn, oldname, newname);
3697 if (!NT_STATUS_IS_OK(status)) {
3698 return ERROR_NT(status);
3702 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
3706 case SMB_FILE_RENAME_INFORMATION:
3715 if (total_data < 12)
3716 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
3718 overwrite = (CVAL(pdata,0) ? True : False);
3719 root_fid = IVAL(pdata,4);
3720 len = IVAL(pdata,8);
3721 srvstr_get_path(inbuf, newname, &pdata[12], sizeof(newname), len, 0, &status, False);
3722 if (!NT_STATUS_IS_OK(status)) {
3723 return ERROR_NT(status);
3726 /* Check the new name has no '/' characters. */
3727 if (strchr_m(newname, '/'))
3728 return ERROR_NT(NT_STATUS_NOT_SUPPORTED);
3730 RESOLVE_DFSPATH(newname, conn, inbuf, outbuf);
3732 /* Create the base directory. */
3733 pstrcpy(base_name, fname);
3734 p = strrchr_m(base_name, '/');
3737 /* Append the new name. */
3738 pstrcat(base_name, "/");
3739 pstrcat(base_name, newname);
3742 DEBUG(10,("call_trans2setfilepathinfo: SMB_FILE_RENAME_INFORMATION (fnum %d) %s -> %s\n",
3743 fsp->fnum, fsp->fsp_name, base_name ));
3744 status = rename_internals_fsp(conn, fsp, base_name, 0, overwrite);
3746 DEBUG(10,("call_trans2setfilepathinfo: SMB_FILE_RENAME_INFORMATION %s -> %s\n",
3748 status = rename_internals(conn, fname, base_name, 0, overwrite);
3750 if (!NT_STATUS_IS_OK(status)) {
3751 return ERROR_NT(status);
3753 process_pending_change_notify_queue((time_t)0);
3755 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
3759 case SMB_SET_POSIX_ACL:
3761 uint16 posix_acl_version;
3762 uint16 num_file_acls;
3763 uint16 num_def_acls;
3764 BOOL valid_file_acls = True;
3765 BOOL valid_def_acls = True;
3767 if (total_data < SMB_POSIX_ACL_HEADER_SIZE) {
3768 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
3770 posix_acl_version = SVAL(pdata,0);
3771 num_file_acls = SVAL(pdata,2);
3772 num_def_acls = SVAL(pdata,4);
3774 if (num_file_acls == SMB_POSIX_IGNORE_ACE_ENTRIES) {
3775 valid_file_acls = False;
3779 if (num_def_acls == SMB_POSIX_IGNORE_ACE_ENTRIES) {
3780 valid_def_acls = False;
3784 if (posix_acl_version != SMB_POSIX_ACL_VERSION) {
3785 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
3788 if (total_data < SMB_POSIX_ACL_HEADER_SIZE +
3789 (num_file_acls+num_def_acls)*SMB_POSIX_ACL_ENTRY_SIZE) {
3790 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
3793 if (valid_file_acls && !set_unix_posix_acl(conn, fsp, fname, num_file_acls,
3794 pdata + SMB_POSIX_ACL_HEADER_SIZE)) {
3795 return(UNIXERROR(ERRDOS,ERRnoaccess));
3798 if (valid_def_acls && !set_unix_posix_default_acl(conn, fname, &sbuf, num_def_acls,
3799 pdata + SMB_POSIX_ACL_HEADER_SIZE +
3800 (num_file_acls*SMB_POSIX_ACL_ENTRY_SIZE))) {
3801 return(UNIXERROR(ERRDOS,ERRnoaccess));
3805 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
3810 return ERROR_DOS(ERRDOS,ERRunknownlevel);
3813 /* get some defaults (no modifications) if any info is zero or -1. */
3814 if (tvs.actime == (time_t)0 || tvs.actime == (time_t)-1)
3815 tvs.actime = sbuf.st_atime;
3817 if (tvs.modtime == (time_t)0 || tvs.modtime == (time_t)-1)
3818 tvs.modtime = sbuf.st_mtime;
3820 DEBUG(6,("actime: %s " , ctime(&tvs.actime)));
3821 DEBUG(6,("modtime: %s ", ctime(&tvs.modtime)));
3822 DEBUG(6,("size: %.0f ", (double)size));
3825 if (S_ISDIR(sbuf.st_mode))
3831 DEBUG(6,("dosmode: %x\n" , dosmode));
3833 if(!((info_level == SMB_SET_FILE_END_OF_FILE_INFO) ||
3834 (info_level == SMB_SET_FILE_ALLOCATION_INFO) ||
3835 (info_level == SMB_FILE_ALLOCATION_INFORMATION) ||
3836 (info_level == SMB_FILE_END_OF_FILE_INFORMATION))) {
3839 * Only do this test if we are not explicitly
3840 * changing the size of a file.
3843 size = get_file_size(sbuf);
3847 * Try and set the times, size and mode of this file -
3848 * if they are different from the current values
3850 if (sbuf.st_mtime != tvs.modtime || sbuf.st_atime != tvs.actime) {
3853 * This was a setfileinfo on an open file.
3854 * NT does this a lot. We also need to
3855 * set the time here, as it can be read by
3856 * FindFirst/FindNext and with the patch for bug #2045
3857 * in smbd/fileio.c it ensures that this timestamp is
3858 * kept sticky even after a write. We save the request
3859 * away and will set it on file close and after a write. JRA.
3862 if (tvs.modtime != (time_t)0 && tvs.modtime != (time_t)-1) {
3863 DEBUG(10,("call_trans2setfilepathinfo: setting pending modtime to %s\n", ctime(&tvs.modtime) ));
3864 fsp->pending_modtime = tvs.modtime;
3867 DEBUG(10,("call_trans2setfilepathinfo: setting utimes to modified values.\n"));
3869 if(file_utime(conn, fname, &tvs)!=0) {
3870 return(UNIXERROR(ERRDOS,ERRnoaccess));
3875 /* check the mode isn't different, before changing it */
3876 if ((dosmode != 0) && (dosmode != dos_mode(conn, fname, &sbuf))) {
3878 DEBUG(10,("call_trans2setfilepathinfo: file %s : setting dos mode %x\n", fname, dosmode ));
3880 if(file_set_dosmode(conn, fname, dosmode, &sbuf, False)) {
3881 DEBUG(2,("file_set_dosmode of %s failed (%s)\n", fname, strerror(errno)));
3882 return(UNIXERROR(ERRDOS,ERRnoaccess));
3886 if (size != get_file_size(sbuf)) {
3890 DEBUG(10,("call_trans2setfilepathinfo: file %s : setting new size to %.0f\n",
3891 fname, (double)size ));
3894 files_struct *new_fsp = NULL;
3895 int access_mode = 0;
3898 if(global_oplock_break) {
3899 /* Queue this file modify as we are the process of an oplock break. */
3901 DEBUG(2,("call_trans2setfilepathinfo: queueing message due to being "));
3902 DEBUGADD(2,( "in oplock break state.\n"));
3904 push_oplock_pending_smb_message(inbuf, length);
3908 new_fsp = open_file_shared(conn, fname, &sbuf,
3909 SET_OPEN_MODE(DOS_OPEN_RDWR),
3910 (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN),
3911 FILE_ATTRIBUTE_NORMAL,
3912 INTERNAL_OPEN_ONLY, &access_mode, &action);
3914 if (new_fsp == NULL)
3915 return(UNIXERROR(ERRDOS,ERRbadpath));
3916 ret = vfs_set_filelen(new_fsp, size);
3917 close_file(new_fsp,True);
3919 ret = vfs_set_filelen(fsp, size);
3923 return (UNIXERROR(ERRHRD,ERRdiskfull));
3927 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
3932 /****************************************************************************
3933 Reply to a TRANS2_MKDIR (make directory with extended attributes).
3934 ****************************************************************************/
3936 static int call_trans2mkdir(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize,
3937 char **pparams, int total_params, char **ppdata, int total_data,
3938 unsigned int max_data_bytes)
3940 char *params = *pparams;
3943 SMB_STRUCT_STAT sbuf;
3944 BOOL bad_path = False;
3945 NTSTATUS status = NT_STATUS_OK;
3947 if (!CAN_WRITE(conn))
3948 return ERROR_DOS(ERRSRV,ERRaccess);
3950 if (total_params < 4)
3951 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
3953 srvstr_get_path(inbuf, directory, ¶ms[4], sizeof(directory), -1, STR_TERMINATE, &status, False);
3954 if (!NT_STATUS_IS_OK(status)) {
3955 return ERROR_NT(status);
3958 DEBUG(3,("call_trans2mkdir : name = %s\n", directory));
3960 unix_convert(directory,conn,0,&bad_path,&sbuf);
3962 return ERROR_NT(NT_STATUS_OBJECT_PATH_NOT_FOUND);
3964 if (check_name(directory,conn))
3965 ret = vfs_MkDir(conn,directory,unix_mode(conn,aDIR,directory,True));
3968 DEBUG(5,("call_trans2mkdir error (%s)\n", strerror(errno)));
3969 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRnoaccess);
3972 /* Realloc the parameter and data sizes */
3973 params = SMB_REALLOC(*pparams,2);
3975 return ERROR_DOS(ERRDOS,ERRnomem);
3980 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
3985 /****************************************************************************
3986 Reply to a TRANS2_FINDNOTIFYFIRST (start monitoring a directory for changes).
3987 We don't actually do this - we just send a null response.
3988 ****************************************************************************/
3990 static int call_trans2findnotifyfirst(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize,
3991 char **pparams, int total_params, char **ppdata, int total_data,
3992 unsigned int max_data_bytes)
3994 static uint16 fnf_handle = 257;
3995 char *params = *pparams;
3998 if (total_params < 6)
3999 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
4001 info_level = SVAL(params,4);
4002 DEBUG(3,("call_trans2findnotifyfirst - info_level %d\n", info_level));
4004 switch (info_level) {
4009 return ERROR_DOS(ERRDOS,ERRunknownlevel);
4012 /* Realloc the parameter and data sizes */
4013 params = SMB_REALLOC(*pparams,6);
4015 return ERROR_DOS(ERRDOS,ERRnomem);
4018 SSVAL(params,0,fnf_handle);
4019 SSVAL(params,2,0); /* No changes */
4020 SSVAL(params,4,0); /* No EA errors */
4027 send_trans2_replies(outbuf, bufsize, params, 6, *ppdata, 0);
4032 /****************************************************************************
4033 Reply to a TRANS2_FINDNOTIFYNEXT (continue monitoring a directory for
4034 changes). Currently this does nothing.
4035 ****************************************************************************/
4037 static int call_trans2findnotifynext(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize,
4038 char **pparams, int total_params, char **ppdata, int total_data,
4039 unsigned int max_data_bytes)
4041 char *params = *pparams;
4043 DEBUG(3,("call_trans2findnotifynext\n"));
4045 /* Realloc the parameter and data sizes */
4046 params = SMB_REALLOC(*pparams,4);
4048 return ERROR_DOS(ERRDOS,ERRnomem);
4051 SSVAL(params,0,0); /* No changes */
4052 SSVAL(params,2,0); /* No EA errors */
4054 send_trans2_replies(outbuf, bufsize, params, 4, *ppdata, 0);
4059 /****************************************************************************
4060 Reply to a TRANS2_GET_DFS_REFERRAL - Shirish Kalele <kalele@veritas.com>.
4061 ****************************************************************************/
4063 static int call_trans2getdfsreferral(connection_struct *conn, char* inbuf, char* outbuf, int length, int bufsize,
4064 char **pparams, int total_params, char **ppdata, int total_data,
4065 unsigned int max_data_bytes)
4067 char *params = *pparams;
4070 int max_referral_level;
4072 DEBUG(10,("call_trans2getdfsreferral\n"));
4074 if (total_params < 2)
4075 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
4077 max_referral_level = SVAL(params,0);
4079 if(!lp_host_msdfs())
4080 return ERROR_DOS(ERRDOS,ERRbadfunc);
4082 srvstr_pull(inbuf, pathname, ¶ms[2], sizeof(pathname), -1, STR_TERMINATE);
4083 if((reply_size = setup_dfs_referral(conn, pathname,max_referral_level,ppdata)) < 0)
4084 return UNIXERROR(ERRDOS,ERRbadfile);
4086 SSVAL(outbuf,smb_flg2,SVAL(outbuf,smb_flg2) | FLAGS2_DFS_PATHNAMES);
4087 send_trans2_replies(outbuf,bufsize,0,0,*ppdata,reply_size);
4092 #define LMCAT_SPL 0x53
4093 #define LMFUNC_GETJOBID 0x60
4095 /****************************************************************************
4096 Reply to a TRANS2_IOCTL - used for OS/2 printing.
4097 ****************************************************************************/
4099 static int call_trans2ioctl(connection_struct *conn, char* inbuf, char* outbuf, int length, int bufsize,
4100 char **pparams, int total_params, char **ppdata, int total_data,
4101 unsigned int max_data_bytes)
4103 char *pdata = *ppdata;
4104 files_struct *fsp = file_fsp(inbuf,smb_vwv15);
4106 /* check for an invalid fid before proceeding */
4109 return(ERROR_DOS(ERRDOS,ERRbadfid));
4111 if ((SVAL(inbuf,(smb_setup+4)) == LMCAT_SPL) &&
4112 (SVAL(inbuf,(smb_setup+6)) == LMFUNC_GETJOBID)) {
4113 pdata = SMB_REALLOC(*ppdata, 32);
4115 return ERROR_DOS(ERRDOS,ERRnomem);
4118 /* NOTE - THIS IS ASCII ONLY AT THE MOMENT - NOT SURE IF OS/2
4119 CAN ACCEPT THIS IN UNICODE. JRA. */
4121 SSVAL(pdata,0,fsp->rap_print_jobid); /* Job number */
4122 srvstr_push( outbuf, pdata + 2, global_myname(), 15, STR_ASCII|STR_TERMINATE); /* Our NetBIOS name */
4123 srvstr_push( outbuf, pdata+18, lp_servicename(SNUM(conn)), 13, STR_ASCII|STR_TERMINATE); /* Service name */
4124 send_trans2_replies(outbuf,bufsize,*pparams,0,*ppdata,32);
4127 DEBUG(2,("Unknown TRANS2_IOCTL\n"));
4128 return ERROR_DOS(ERRSRV,ERRerror);
4132 /****************************************************************************
4133 Reply to a SMBfindclose (stop trans2 directory search).
4134 ****************************************************************************/
4136 int reply_findclose(connection_struct *conn,
4137 char *inbuf,char *outbuf,int length,int bufsize)
4140 int dptr_num=SVALS(inbuf,smb_vwv0);
4141 START_PROFILE(SMBfindclose);
4143 DEBUG(3,("reply_findclose, dptr_num = %d\n", dptr_num));
4145 dptr_close(&dptr_num);
4147 outsize = set_message(outbuf,0,0,True);
4149 DEBUG(3,("SMBfindclose dptr_num = %d\n", dptr_num));
4151 END_PROFILE(SMBfindclose);
4155 /****************************************************************************
4156 Reply to a SMBfindnclose (stop FINDNOTIFYFIRST directory search).
4157 ****************************************************************************/
4159 int reply_findnclose(connection_struct *conn,
4160 char *inbuf,char *outbuf,int length,int bufsize)
4164 START_PROFILE(SMBfindnclose);
4166 dptr_num = SVAL(inbuf,smb_vwv0);
4168 DEBUG(3,("reply_findnclose, dptr_num = %d\n", dptr_num));
4170 /* We never give out valid handles for a
4171 findnotifyfirst - so any dptr_num is ok here.
4174 outsize = set_message(outbuf,0,0,True);
4176 DEBUG(3,("SMB_findnclose dptr_num = %d\n", dptr_num));
4178 END_PROFILE(SMBfindnclose);
4182 /****************************************************************************
4183 Reply to a SMBtranss2 - just ignore it!
4184 ****************************************************************************/
4186 int reply_transs2(connection_struct *conn,
4187 char *inbuf,char *outbuf,int length,int bufsize)
4189 START_PROFILE(SMBtranss2);
4190 DEBUG(4,("Ignoring transs2 of length %d\n",length));
4191 END_PROFILE(SMBtranss2);
4195 /****************************************************************************
4196 Reply to a SMBtrans2.
4197 ****************************************************************************/
4199 int reply_trans2(connection_struct *conn,
4200 char *inbuf,char *outbuf,int length,int bufsize)
4203 unsigned int total_params = SVAL(inbuf, smb_tpscnt);
4204 unsigned int total_data =SVAL(inbuf, smb_tdscnt);
4205 unsigned int max_data_bytes = SVAL(inbuf, smb_mdrcnt);
4207 unsigned int max_param_reply = SVAL(inbuf, smb_mprcnt);
4208 unsigned int max_setup_fields = SVAL(inbuf, smb_msrcnt);
4209 BOOL close_tid = BITSETW(inbuf+smb_flags,0);
4210 BOOL no_final_response = BITSETW(inbuf+smb_flags,1);
4211 int32 timeout = IVALS(inbuf,smb_timeout);
4213 unsigned int suwcnt = SVAL(inbuf, smb_suwcnt);
4214 unsigned int tran_call = SVAL(inbuf, smb_setup0);
4215 char *params = NULL, *data = NULL;
4216 unsigned int num_params, num_params_sofar, num_data, num_data_sofar;
4217 START_PROFILE(SMBtrans2);
4219 if(global_oplock_break && (tran_call == TRANSACT2_OPEN)) {
4220 /* Queue this open message as we are the process of an
4223 DEBUG(2,("reply_trans2: queueing message trans2open due to being "));
4224 DEBUGADD(2,( "in oplock break state.\n"));
4226 push_oplock_pending_smb_message(inbuf, length);
4227 END_PROFILE(SMBtrans2);
4231 if (IS_IPC(conn) && (tran_call != TRANSACT2_OPEN)
4232 && (tran_call != TRANSACT2_GET_DFS_REFERRAL)) {
4233 END_PROFILE(SMBtrans2);
4234 return ERROR_DOS(ERRSRV,ERRaccess);
4237 outsize = set_message(outbuf,0,0,True);
4239 /* All trans2 messages we handle have smb_sucnt == 1 - ensure this
4240 is so as a sanity check */
4243 * Need to have rc=0 for ioctl to get job id for OS/2.
4244 * Network printing will fail if function is not successful.
4245 * Similar function in reply.c will be used if protocol
4246 * is LANMAN1.0 instead of LM1.2X002.
4247 * Until DosPrintSetJobInfo with PRJINFO3 is supported,
4248 * outbuf doesn't have to be set(only job id is used).
4250 if ( (suwcnt == 4) && (tran_call == TRANSACT2_IOCTL) &&
4251 (SVAL(inbuf,(smb_setup+4)) == LMCAT_SPL) &&
4252 (SVAL(inbuf,(smb_setup+6)) == LMFUNC_GETJOBID)) {
4253 DEBUG(2,("Got Trans2 DevIOctl jobid\n"));
4255 DEBUG(2,("Invalid smb_sucnt in trans2 call(%u)\n",suwcnt));
4256 DEBUG(2,("Transaction is %d\n",tran_call));
4257 END_PROFILE(SMBtrans2);
4258 ERROR_DOS(ERRDOS,ERRinvalidparam);
4262 /* Allocate the space for the maximum needed parameters and data */
4263 if (total_params > 0)
4264 params = (char *)SMB_MALLOC(total_params);
4266 data = (char *)SMB_MALLOC(total_data);
4268 if ((total_params && !params) || (total_data && !data)) {
4269 DEBUG(2,("Out of memory in reply_trans2\n"));
4272 END_PROFILE(SMBtrans2);
4273 return ERROR_DOS(ERRDOS,ERRnomem);
4276 /* Copy the param and data bytes sent with this request into
4277 the params buffer */
4278 num_params = num_params_sofar = SVAL(inbuf,smb_pscnt);
4279 num_data = num_data_sofar = SVAL(inbuf, smb_dscnt);
4281 if (num_params > total_params || num_data > total_data)
4282 exit_server("invalid params in reply_trans2");
4285 unsigned int psoff = SVAL(inbuf, smb_psoff);
4286 if ((psoff + num_params < psoff) || (psoff + num_params < num_params))
4288 if ((smb_base(inbuf) + psoff + num_params > inbuf + length) ||
4289 (smb_base(inbuf) + psoff + num_params < smb_base(inbuf)))
4291 memcpy( params, smb_base(inbuf) + psoff, num_params);
4294 unsigned int dsoff = SVAL(inbuf, smb_dsoff);
4295 if ((dsoff + num_data < dsoff) || (dsoff + num_data < num_data))
4297 if ((smb_base(inbuf) + dsoff + num_data > inbuf + length) ||
4298 (smb_base(inbuf) + dsoff + num_data < smb_base(inbuf)))
4300 memcpy( data, smb_base(inbuf) + dsoff, num_data);
4303 srv_signing_trans_start(SVAL(inbuf,smb_mid));
4305 if(num_data_sofar < total_data || num_params_sofar < total_params) {
4306 /* We need to send an interim response then receive the rest
4307 of the parameter/data bytes */
4308 outsize = set_message(outbuf,0,0,True);
4309 srv_signing_trans_stop();
4310 if (!send_smb(smbd_server_fd(),outbuf))
4311 exit_server("reply_trans2: send_smb failed.");
4313 while (num_data_sofar < total_data ||
4314 num_params_sofar < total_params) {
4316 unsigned int param_disp;
4317 unsigned int param_off;
4318 unsigned int data_disp;
4319 unsigned int data_off;
4321 ret = receive_next_smb(inbuf,bufsize,SMB_SECONDARY_WAIT);
4324 * The sequence number for the trans reply is always
4325 * based on the last secondary received.
4328 srv_signing_trans_start(SVAL(inbuf,smb_mid));
4331 (CVAL(inbuf, smb_com) != SMBtranss2)) || !ret) {
4332 outsize = set_message(outbuf,0,0,True);
4334 DEBUG(0,("reply_trans2: Invalid secondary trans2 packet\n"));
4336 DEBUG(0,("reply_trans2: %s in getting secondary trans2 response.\n",
4337 (smb_read_error == READ_ERROR) ? "error" : "timeout" ));
4341 /* Revise total_params and total_data in case
4342 they have changed downwards */
4343 if (SVAL(inbuf, smb_tpscnt) < total_params)
4344 total_params = SVAL(inbuf, smb_tpscnt);
4345 if (SVAL(inbuf, smb_tdscnt) < total_data)
4346 total_data = SVAL(inbuf, smb_tdscnt);
4348 num_params = SVAL(inbuf,smb_spscnt);
4349 param_off = SVAL(inbuf, smb_spsoff);
4350 param_disp = SVAL(inbuf, smb_spsdisp);
4351 num_params_sofar += num_params;
4353 num_data = SVAL(inbuf, smb_sdscnt);
4354 data_off = SVAL(inbuf, smb_sdsoff);
4355 data_disp = SVAL(inbuf, smb_sdsdisp);
4356 num_data_sofar += num_data;
4358 if (num_params_sofar > total_params || num_data_sofar > total_data)
4362 if (param_disp + num_params > total_params)
4364 if ((param_disp + num_params < param_disp) ||
4365 (param_disp + num_params < num_params))
4367 if (param_disp > total_params)
4369 if ((smb_base(inbuf) + param_off + num_params >= inbuf + bufsize) ||
4370 (smb_base(inbuf) + param_off + num_params < smb_base(inbuf)))
4372 if (params + param_disp < params)
4375 memcpy( ¶ms[param_disp], smb_base(inbuf) + param_off, num_params);
4378 if (data_disp + num_data > total_data)
4380 if ((data_disp + num_data < data_disp) ||
4381 (data_disp + num_data < num_data))
4383 if (data_disp > total_data)
4385 if ((smb_base(inbuf) + data_off + num_data >= inbuf + bufsize) ||
4386 (smb_base(inbuf) + data_off + num_data < smb_base(inbuf)))
4388 if (data + data_disp < data)
4391 memcpy( &data[data_disp], smb_base(inbuf) + data_off, num_data);
4396 if (Protocol >= PROTOCOL_NT1) {
4397 SSVAL(outbuf,smb_flg2,SVAL(outbuf,smb_flg2) | 0x40); /* IS_LONG_NAME */
4400 /* Now we must call the relevant TRANS2 function */
4402 case TRANSACT2_OPEN:
4403 START_PROFILE_NESTED(Trans2_open);
4404 outsize = call_trans2open(conn, inbuf, outbuf, bufsize,
4405 ¶ms, total_params, &data, total_data, max_data_bytes);
4406 END_PROFILE_NESTED(Trans2_open);
4409 case TRANSACT2_FINDFIRST:
4410 START_PROFILE_NESTED(Trans2_findfirst);
4411 outsize = call_trans2findfirst(conn, inbuf, outbuf, bufsize,
4412 ¶ms, total_params, &data, total_data, max_data_bytes);
4413 END_PROFILE_NESTED(Trans2_findfirst);
4416 case TRANSACT2_FINDNEXT:
4417 START_PROFILE_NESTED(Trans2_findnext);
4418 outsize = call_trans2findnext(conn, inbuf, outbuf, length, bufsize,
4419 ¶ms, total_params, &data, total_data, max_data_bytes);
4420 END_PROFILE_NESTED(Trans2_findnext);
4423 case TRANSACT2_QFSINFO:
4424 START_PROFILE_NESTED(Trans2_qfsinfo);
4425 outsize = call_trans2qfsinfo(conn, inbuf, outbuf, length, bufsize,
4426 ¶ms, total_params, &data, total_data, max_data_bytes);
4427 END_PROFILE_NESTED(Trans2_qfsinfo);
4430 #ifdef HAVE_SYS_QUOTAS
4431 case TRANSACT2_SETFSINFO:
4432 START_PROFILE_NESTED(Trans2_setfsinfo);
4433 outsize = call_trans2setfsinfo(conn, inbuf, outbuf, length, bufsize,
4434 ¶ms, total_params, &data, total_data, max_data_bytes);
4435 END_PROFILE_NESTED(Trans2_setfsinfo);
4438 case TRANSACT2_QPATHINFO:
4439 case TRANSACT2_QFILEINFO:
4440 START_PROFILE_NESTED(Trans2_qpathinfo);
4441 outsize = call_trans2qfilepathinfo(conn, inbuf, outbuf, length, bufsize,
4442 ¶ms, total_params, &data, total_data, max_data_bytes);
4443 END_PROFILE_NESTED(Trans2_qpathinfo);
4445 case TRANSACT2_SETPATHINFO:
4446 case TRANSACT2_SETFILEINFO:
4447 START_PROFILE_NESTED(Trans2_setpathinfo);
4448 outsize = call_trans2setfilepathinfo(conn, inbuf, outbuf, length, bufsize,
4449 ¶ms, total_params, &data, total_data, max_data_bytes);
4450 END_PROFILE_NESTED(Trans2_setpathinfo);
4453 case TRANSACT2_FINDNOTIFYFIRST:
4454 START_PROFILE_NESTED(Trans2_findnotifyfirst);
4455 outsize = call_trans2findnotifyfirst(conn, inbuf, outbuf, length, bufsize,
4456 ¶ms, total_params, &data, total_data, max_data_bytes);
4457 END_PROFILE_NESTED(Trans2_findnotifyfirst);
4460 case TRANSACT2_FINDNOTIFYNEXT:
4461 START_PROFILE_NESTED(Trans2_findnotifynext);
4462 outsize = call_trans2findnotifynext(conn, inbuf, outbuf, length, bufsize,
4463 ¶ms, total_params, &data, total_data, max_data_bytes);
4464 END_PROFILE_NESTED(Trans2_findnotifynext);
4466 case TRANSACT2_MKDIR:
4467 START_PROFILE_NESTED(Trans2_mkdir);
4468 outsize = call_trans2mkdir(conn, inbuf, outbuf, length, bufsize,
4469 ¶ms, total_params, &data, total_data, max_data_bytes);
4470 END_PROFILE_NESTED(Trans2_mkdir);
4473 case TRANSACT2_GET_DFS_REFERRAL:
4474 START_PROFILE_NESTED(Trans2_get_dfs_referral);
4475 outsize = call_trans2getdfsreferral(conn,inbuf,outbuf,length, bufsize,
4476 ¶ms, total_params, &data, total_data, max_data_bytes);
4477 END_PROFILE_NESTED(Trans2_get_dfs_referral);
4479 case TRANSACT2_IOCTL:
4480 START_PROFILE_NESTED(Trans2_ioctl);
4481 outsize = call_trans2ioctl(conn,inbuf,outbuf,length, bufsize,
4482 ¶ms, total_params, &data, total_data, max_data_bytes);
4483 END_PROFILE_NESTED(Trans2_ioctl);
4486 /* Error in request */
4487 DEBUG(2,("Unknown request %d in trans2 call\n", tran_call));
4490 END_PROFILE(SMBtrans2);
4491 srv_signing_trans_stop();
4492 return ERROR_DOS(ERRSRV,ERRerror);
4495 /* As we do not know how many data packets will need to be
4496 returned here the various call_trans2xxxx calls
4497 must send their own. Thus a call_trans2xxx routine only
4498 returns a value other than -1 when it wants to send
4502 srv_signing_trans_stop();
4506 END_PROFILE(SMBtrans2);
4507 return outsize; /* If a correct response was needed the
4508 call_trans2xxx calls have already sent
4509 it. If outsize != -1 then it is returning */
4513 srv_signing_trans_stop();
4516 END_PROFILE(SMBtrans2);
4517 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);