2 Unix SMB/CIFS implementation.
3 SMB transaction2 handling
4 Copyright (C) Jeremy Allison 1994-2003
5 Copyright (C) Stefan (metze) Metzmacher 2003
7 Extensively modified by Andrew Tridgell, 1995
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26 extern enum protocol_types Protocol;
27 extern int smb_read_error;
28 extern int global_oplock_break;
29 extern uint32 global_client_caps;
30 extern struct current_user current_user;
32 #define get_file_size(sbuf) ((sbuf).st_size)
33 #define DIR_ENTRY_SAFETY_MARGIN 4096
35 /********************************************************************
36 Roundup a value to the nearest allocation roundup size boundary.
37 Only do this for Windows clients.
38 ********************************************************************/
40 SMB_BIG_UINT smb_roundup(connection_struct *conn, SMB_BIG_UINT val)
42 SMB_BIG_UINT rval = lp_allocation_roundup_size(SNUM(conn));
44 /* Only roundup for Windows clients. */
45 enum remote_arch_types ra_type = get_remote_arch();
46 if (rval && (ra_type != RA_SAMBA) && (ra_type != RA_CIFSFS)) {
47 val = SMB_ROUNDUP(val,rval);
52 /********************************************************************
53 Given a stat buffer return the allocated size on disk, taking into
55 ********************************************************************/
57 SMB_BIG_UINT get_allocation_size(connection_struct *conn, files_struct *fsp, SMB_STRUCT_STAT *sbuf)
61 #if defined(HAVE_STAT_ST_BLOCKS) && defined(STAT_ST_BLOCKSIZE)
62 ret = (SMB_BIG_UINT)STAT_ST_BLOCKSIZE * (SMB_BIG_UINT)sbuf->st_blocks;
64 ret = (SMB_BIG_UINT)get_file_size(*sbuf);
67 if (!ret && fsp && fsp->initial_allocation_size)
68 ret = fsp->initial_allocation_size;
70 return smb_roundup(conn, ret);
73 /****************************************************************************
74 Utility functions for dealing with extended attributes.
75 ****************************************************************************/
77 static const char *prohibited_ea_names[] = {
78 SAMBA_POSIX_INHERITANCE_EA_NAME,
79 SAMBA_XATTR_DOS_ATTRIB,
83 /****************************************************************************
84 Refuse to allow clients to overwrite our private xattrs.
85 ****************************************************************************/
87 static BOOL samba_private_attr_name(const char *unix_ea_name)
91 for (i = 0; prohibited_ea_names[i]; i++) {
92 if (strequal( prohibited_ea_names[i], unix_ea_name))
99 struct ea_list *next, *prev;
103 /****************************************************************************
104 Get one EA value. Fill in a struct ea_struct.
105 ****************************************************************************/
107 static BOOL get_ea_value(TALLOC_CTX *mem_ctx, connection_struct *conn, files_struct *fsp,
108 const char *fname, char *ea_name, struct ea_struct *pea)
110 /* Get the value of this xattr. Max size is 64k. */
111 size_t attr_size = 256;
117 val = TALLOC_REALLOC_ARRAY(mem_ctx, val, char, attr_size);
122 if (fsp && fsp->fd != -1) {
123 sizeret = SMB_VFS_FGETXATTR(fsp, fsp->fd, ea_name, val, attr_size);
125 sizeret = SMB_VFS_GETXATTR(conn, fname, ea_name, val, attr_size);
128 if (sizeret == -1 && errno == ERANGE && attr_size != 65536) {
137 DEBUG(10,("get_ea_value: EA %s is of length %d: ", ea_name, sizeret));
138 dump_data(10, val, sizeret);
141 if (strnequal(ea_name, "user.", 5)) {
142 pea->name = &ea_name[5];
146 pea->value.data = val;
147 pea->value.length = (size_t)sizeret;
151 /****************************************************************************
152 Return a linked list of the total EA's. Plus the total size
153 ****************************************************************************/
155 static struct ea_list *get_ea_list(TALLOC_CTX *mem_ctx, connection_struct *conn, files_struct *fsp, const char *fname, size_t *pea_total_len)
157 /* Get a list of all xattrs. Max namesize is 64k. */
158 size_t ea_namelist_size = 1024;
163 struct ea_list *ea_list_head = NULL;
167 if (!lp_ea_support(SNUM(conn))) {
171 for (i = 0, ea_namelist = TALLOC(mem_ctx, ea_namelist_size); i < 6;
172 ea_namelist = TALLOC_REALLOC_ARRAY(mem_ctx, ea_namelist, char, ea_namelist_size), i++) {
173 if (fsp && fsp->fd != -1) {
174 sizeret = SMB_VFS_FLISTXATTR(fsp, fsp->fd, ea_namelist, ea_namelist_size);
176 sizeret = SMB_VFS_LISTXATTR(conn, fname, ea_namelist, ea_namelist_size);
179 if (sizeret == -1 && errno == ERANGE) {
180 ea_namelist_size *= 2;
189 DEBUG(10,("get_ea_list: ea_namelist size = %d\n", sizeret ));
192 for (p = ea_namelist; p - ea_namelist < sizeret; p += strlen(p) + 1) {
193 struct ea_list *listp, *tmp;
195 if (strnequal(p, "system.", 7) || samba_private_attr_name(p))
198 listp = TALLOC_P(mem_ctx, struct ea_list);
202 if (!get_ea_value(mem_ctx, conn, fsp, fname, p, &listp->ea)) {
208 push_ascii_fstring(dos_ea_name, listp->ea.name);
209 *pea_total_len += 4 + strlen(dos_ea_name) + 1 + listp->ea.value.length;
210 DEBUG(10,("get_ea_list: total_len = %u, %s, val len = %u\n",
211 *pea_total_len, dos_ea_name,
212 (unsigned int)listp->ea.value.length ));
214 DLIST_ADD_END(ea_list_head, listp, tmp);
216 /* Add on 4 for total length. */
217 if (*pea_total_len) {
222 DEBUG(10,("get_ea_list: total_len = %u\n", *pea_total_len));
226 /****************************************************************************
227 Fill a qfilepathinfo buffer with EA's. Returns the length of the buffer
229 ****************************************************************************/
231 static unsigned int fill_ea_buffer(char *pdata, unsigned int total_data_size,
232 connection_struct *conn, files_struct *fsp, const char *fname)
234 unsigned int ret_data_size = 4;
238 struct ea_list *ea_list;
240 SMB_ASSERT(total_data_size >= 4);
243 if (!lp_ea_support(SNUM(conn))) {
246 mem_ctx = talloc_init("fill_ea_buffer");
251 ea_list = get_ea_list(mem_ctx, conn, fsp, fname, &total_ea_len);
253 talloc_destroy(mem_ctx);
257 if (total_ea_len > total_data_size) {
258 talloc_destroy(mem_ctx);
262 for (p = pdata + 4; ea_list; ea_list = ea_list->next) {
265 push_ascii_fstring(dos_ea_name, ea_list->ea.name);
266 dos_namelen = strlen(dos_ea_name);
267 if (dos_namelen > 255 || dos_namelen == 0) {
270 if (ea_list->ea.value.length > 65535) {
273 if (4 + dos_namelen + 1 + ea_list->ea.value.length > total_data_size) {
277 /* We know we have room. */
278 SCVAL(p,0,ea_list->ea.flags);
279 SCVAL(p,1,dos_namelen);
280 SSVAL(p,2,ea_list->ea.value.length);
281 fstrcpy(p+4, dos_ea_name);
282 memcpy( p + 4 + dos_namelen + 1, ea_list->ea.value.data, ea_list->ea.value.length);
284 total_data_size -= 4 + dos_namelen + 1 + ea_list->ea.value.length;
285 p += 4 + dos_namelen + 1 + ea_list->ea.value.length;
288 ret_data_size = PTR_DIFF(p, pdata);
289 DEBUG(10,("fill_ea_buffer: data_size = %u, total_ea_len = %u\n",
290 ret_data_size, total_ea_len ));
291 talloc_destroy(mem_ctx);
292 SIVAL(pdata,0,ret_data_size);
293 return ret_data_size;
296 static unsigned int estimate_ea_size(connection_struct *conn, files_struct *fsp, const char *fname)
298 size_t total_ea_len = 0;
299 TALLOC_CTX *mem_ctx = NULL;
301 if (!lp_ea_support(SNUM(conn))) {
304 mem_ctx = talloc_init("estimate_ea_size");
305 (void)get_ea_list(mem_ctx, conn, fsp, fname, &total_ea_len);
306 talloc_destroy(mem_ctx);
310 /****************************************************************************
311 Ensure the EA name is case insensitive by matching any existing EA name.
312 ****************************************************************************/
314 static void canonicalize_ea_name(connection_struct *conn, files_struct *fsp, const char *fname, fstring unix_ea_name)
317 TALLOC_CTX *mem_ctx = talloc_init("canonicalize_ea_name");
318 struct ea_list *ea_list = get_ea_list(mem_ctx, conn, fsp, fname, &total_ea_len);
320 for (; ea_list; ea_list = ea_list->next) {
321 if (strequal(&unix_ea_name[5], ea_list->ea.name)) {
322 DEBUG(10,("canonicalize_ea_name: %s -> %s\n",
323 &unix_ea_name[5], ea_list->ea.name));
324 safe_strcpy(&unix_ea_name[5], ea_list->ea.name, sizeof(fstring)-6);
328 talloc_destroy(mem_ctx);
331 /****************************************************************************
332 Set or delete an extended attribute.
333 ****************************************************************************/
335 static NTSTATUS set_ea(connection_struct *conn, files_struct *fsp, const char *fname,
336 char *pdata, int total_data)
338 unsigned int namelen;
341 fstring unix_ea_name;
343 if (!lp_ea_support(SNUM(conn))) {
344 return NT_STATUS_EAS_NOT_SUPPORTED;
347 if (total_data < 8) {
348 return NT_STATUS_INVALID_PARAMETER;
351 if (IVAL(pdata,0) > total_data) {
352 DEBUG(10,("set_ea: bad total data size (%u) > %u\n", IVAL(pdata,0), (unsigned int)total_data));
353 return NT_STATUS_INVALID_PARAMETER;
357 namelen = CVAL(pdata,1);
358 ealen = SVAL(pdata,2);
360 if (total_data < 8 + namelen + 1 + ealen) {
361 DEBUG(10,("set_ea: bad total data size (%u) < 8 + namelen (%u) + 1 + ealen (%u)\n",
362 (unsigned int)total_data, namelen, ealen));
363 return NT_STATUS_INVALID_PARAMETER;
366 if (pdata[namelen] != '\0') {
367 DEBUG(10,("set_ea: ea name not null terminated\n"));
368 return NT_STATUS_INVALID_PARAMETER;
371 fstrcpy(unix_ea_name, "user."); /* All EA's must start with user. */
372 pull_ascii(&unix_ea_name[5], pdata, sizeof(fstring) - 5, -1, STR_TERMINATE);
373 pdata += (namelen + 1);
375 canonicalize_ea_name(conn, fsp, fname, unix_ea_name);
377 DEBUG(10,("set_ea: ea_name %s ealen = %u\n", unix_ea_name, ealen));
379 DEBUG(10,("set_ea: data :\n"));
380 dump_data(10, pdata, ealen);
383 if (samba_private_attr_name(unix_ea_name)) {
384 DEBUG(10,("set_ea: ea name %s is a private Samba name.\n", unix_ea_name));
385 return NT_STATUS_ACCESS_DENIED;
389 /* Remove the attribute. */
390 if (fsp && (fsp->fd != -1)) {
391 DEBUG(10,("set_ea: deleting ea name %s on file %s by file descriptor.\n",
392 unix_ea_name, fsp->fsp_name));
393 ret = SMB_VFS_FREMOVEXATTR(fsp, fsp->fd, unix_ea_name);
395 DEBUG(10,("set_ea: deleting ea name %s on file %s.\n",
396 unix_ea_name, fname));
397 ret = SMB_VFS_REMOVEXATTR(conn, fname, unix_ea_name);
400 /* Removing a non existent attribute always succeeds. */
401 if (ret == -1 && errno == ENOATTR) {
402 DEBUG(10,("set_ea: deleting ea name %s didn't exist - succeeding by default.\n", unix_ea_name));
407 if (fsp && (fsp->fd != -1)) {
408 DEBUG(10,("set_ea: setting ea name %s on file %s by file descriptor.\n",
409 unix_ea_name, fsp->fsp_name));
410 ret = SMB_VFS_FSETXATTR(fsp, fsp->fd, unix_ea_name, pdata, ealen, 0);
412 DEBUG(10,("set_ea: setting ea name %s on file %s.\n",
413 unix_ea_name, fname));
414 ret = SMB_VFS_SETXATTR(conn, fname, unix_ea_name, pdata, ealen, 0);
420 if (errno == ENOTSUP) {
421 return NT_STATUS_EAS_NOT_SUPPORTED;
424 return map_nt_error_from_unix(errno);
430 /****************************************************************************
431 Send the required number of replies back.
432 We assume all fields other than the data fields are
433 set correctly for the type of call.
434 HACK ! Always assumes smb_setup field is zero.
435 ****************************************************************************/
437 static int send_trans2_replies(char *outbuf,
444 /* As we are using a protocol > LANMAN1 then the max_send
445 variable must have been set in the sessetupX call.
446 This takes precedence over the max_xmit field in the
447 global struct. These different max_xmit variables should
448 be merged as this is now too confusing */
451 int data_to_send = datasize;
452 int params_to_send = paramsize;
456 int params_sent_thistime, data_sent_thistime, total_sent_thistime;
457 int alignment_offset = 1; /* JRA. This used to be 3. Set to 1 to make netmon parse ok. */
458 int data_alignment_offset = 0;
460 /* Initially set the wcnt area to be 10 - this is true for all trans2 replies */
462 set_message(outbuf,10,0,True);
464 /* If there genuinely are no parameters or data to send just send the empty packet */
466 if(params_to_send == 0 && data_to_send == 0) {
467 if (!send_smb(smbd_server_fd(),outbuf))
468 exit_server("send_trans2_replies: send_smb failed.");
472 /* When sending params and data ensure that both are nicely aligned */
473 /* Only do this alignment when there is also data to send - else
474 can cause NT redirector problems. */
476 if (((params_to_send % 4) != 0) && (data_to_send != 0))
477 data_alignment_offset = 4 - (params_to_send % 4);
479 /* Space is bufsize minus Netbios over TCP header minus SMB header */
480 /* The alignment_offset is to align the param bytes on an even byte
481 boundary. NT 4.0 Beta needs this to work correctly. */
483 useable_space = bufsize - ((smb_buf(outbuf)+ alignment_offset+data_alignment_offset) - outbuf);
485 /* useable_space can never be more than max_send minus the alignment offset. */
487 useable_space = MIN(useable_space, max_send - (alignment_offset+data_alignment_offset));
489 while (params_to_send || data_to_send) {
490 /* Calculate whether we will totally or partially fill this packet */
492 total_sent_thistime = params_to_send + data_to_send + alignment_offset + data_alignment_offset;
494 /* We can never send more than useable_space */
496 * Note that 'useable_space' does not include the alignment offsets,
497 * but we must include the alignment offsets in the calculation of
498 * the length of the data we send over the wire, as the alignment offsets
499 * are sent here. Fix from Marc_Jacobsen@hp.com.
502 total_sent_thistime = MIN(total_sent_thistime, useable_space+ alignment_offset + data_alignment_offset);
504 set_message(outbuf, 10, total_sent_thistime, True);
506 /* Set total params and data to be sent */
507 SSVAL(outbuf,smb_tprcnt,paramsize);
508 SSVAL(outbuf,smb_tdrcnt,datasize);
510 /* Calculate how many parameters and data we can fit into
511 * this packet. Parameters get precedence
514 params_sent_thistime = MIN(params_to_send,useable_space);
515 data_sent_thistime = useable_space - params_sent_thistime;
516 data_sent_thistime = MIN(data_sent_thistime,data_to_send);
518 SSVAL(outbuf,smb_prcnt, params_sent_thistime);
520 /* smb_proff is the offset from the start of the SMB header to the
521 parameter bytes, however the first 4 bytes of outbuf are
522 the Netbios over TCP header. Thus use smb_base() to subtract
523 them from the calculation */
525 SSVAL(outbuf,smb_proff,((smb_buf(outbuf)+alignment_offset) - smb_base(outbuf)));
527 if(params_sent_thistime == 0)
528 SSVAL(outbuf,smb_prdisp,0);
530 /* Absolute displacement of param bytes sent in this packet */
531 SSVAL(outbuf,smb_prdisp,pp - params);
533 SSVAL(outbuf,smb_drcnt, data_sent_thistime);
534 if(data_sent_thistime == 0) {
535 SSVAL(outbuf,smb_droff,0);
536 SSVAL(outbuf,smb_drdisp, 0);
538 /* The offset of the data bytes is the offset of the
539 parameter bytes plus the number of parameters being sent this time */
540 SSVAL(outbuf,smb_droff,((smb_buf(outbuf)+alignment_offset) -
541 smb_base(outbuf)) + params_sent_thistime + data_alignment_offset);
542 SSVAL(outbuf,smb_drdisp, pd - pdata);
545 /* Copy the param bytes into the packet */
547 if(params_sent_thistime)
548 memcpy((smb_buf(outbuf)+alignment_offset),pp,params_sent_thistime);
550 /* Copy in the data bytes */
551 if(data_sent_thistime)
552 memcpy(smb_buf(outbuf)+alignment_offset+params_sent_thistime+
553 data_alignment_offset,pd,data_sent_thistime);
555 DEBUG(9,("t2_rep: params_sent_thistime = %d, data_sent_thistime = %d, useable_space = %d\n",
556 params_sent_thistime, data_sent_thistime, useable_space));
557 DEBUG(9,("t2_rep: params_to_send = %d, data_to_send = %d, paramsize = %d, datasize = %d\n",
558 params_to_send, data_to_send, paramsize, datasize));
560 /* Send the packet */
561 if (!send_smb(smbd_server_fd(),outbuf))
562 exit_server("send_trans2_replies: send_smb failed.");
564 pp += params_sent_thistime;
565 pd += data_sent_thistime;
567 params_to_send -= params_sent_thistime;
568 data_to_send -= data_sent_thistime;
571 if(params_to_send < 0 || data_to_send < 0) {
572 DEBUG(0,("send_trans2_replies failed sanity check pts = %d, dts = %d\n!!!",
573 params_to_send, data_to_send));
581 /****************************************************************************
582 Reply to a TRANSACT2_OPEN.
583 ****************************************************************************/
585 static int call_trans2open(connection_struct *conn, char *inbuf, char *outbuf, int bufsize,
586 char **pparams, int total_params, char **ppdata, int total_data,
587 unsigned int max_data_bytes)
589 char *params = *pparams;
594 BOOL return_additional_info;
603 int fmode=0,mtime=0,rmode;
605 SMB_STRUCT_STAT sbuf;
607 BOOL bad_path = False;
612 * Ensure we have enough parameters to perform the operation.
615 if (total_params < 29)
616 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
618 open_mode = SVAL(params, 2);
619 open_attr = SVAL(params,6);
620 oplock_request = (((SVAL(params,0)|(1<<1))>>1) | ((SVAL(params,0)|(1<<2))>>1));
622 return_additional_info = BITSETW(params,0);
623 open_sattr = SVAL(params, 4);
624 open_time = make_unix_date3(params+8);
626 open_ofun = SVAL(params,12);
627 open_size = IVAL(params,14);
631 return(ERROR_DOS(ERRSRV,ERRaccess));
633 srvstr_get_path(inbuf, fname, pname, sizeof(fname), -1, STR_TERMINATE, &status, False);
634 if (!NT_STATUS_IS_OK(status)) {
635 return ERROR_NT(status);
638 DEBUG(3,("trans2open %s mode=%d attr=%d ofun=%d size=%d\n",
639 fname,open_mode, open_attr, open_ofun, open_size));
641 /* XXXX we need to handle passed times, sattr and flags */
643 unix_convert(fname,conn,0,&bad_path,&sbuf);
645 return ERROR_NT(NT_STATUS_OBJECT_PATH_NOT_FOUND);
648 if (!check_name(fname,conn)) {
649 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRnoaccess);
652 fsp = open_file_shared(conn,fname,&sbuf,open_mode,open_ofun,(uint32)open_attr,
653 oplock_request, &rmode,&smb_action);
656 if (open_was_deferred(SVAL(inbuf,smb_mid))) {
657 /* We have re-scheduled this call. */
658 clear_cached_errors();
661 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRnoaccess);
664 size = get_file_size(sbuf);
665 fmode = dos_mode(conn,fname,&sbuf);
666 mtime = sbuf.st_mtime;
669 close_file(fsp,False);
670 return(ERROR_DOS(ERRDOS,ERRnoaccess));
673 /* Realloc the size of parameters and data we will return */
674 params = SMB_REALLOC(*pparams, 28);
676 return(ERROR_DOS(ERRDOS,ERRnomem));
679 memset((char *)params,'\0',28);
680 SSVAL(params,0,fsp->fnum);
681 SSVAL(params,2,fmode);
682 put_dos_date2(params,4, mtime);
683 SIVAL(params,8, (uint32)size);
684 SSVAL(params,12,rmode);
686 if (oplock_request && lp_fake_oplocks(SNUM(conn)))
687 smb_action |= EXTENDED_OPLOCK_GRANTED;
689 SSVAL(params,18,smb_action);
692 * WARNING - this may need to be changed if SMB_INO_T <> 4 bytes.
694 SIVAL(params,20,inode);
696 /* Send the required number of replies */
697 send_trans2_replies(outbuf, bufsize, params, 28, *ppdata, 0);
702 /*********************************************************
703 Routine to check if a given string matches exactly.
704 as a special case a mask of "." does NOT match. That
705 is required for correct wildcard semantics
706 Case can be significant or not.
707 **********************************************************/
709 static BOOL exact_match(char *str,char *mask, BOOL case_sig)
711 if (mask[0] == '.' && mask[1] == 0)
714 return strcmp(str,mask)==0;
715 if (StrCaseCmp(str,mask) != 0) {
718 if (ms_has_wild(str)) {
724 /****************************************************************************
725 Return the filetype for UNIX extensions.
726 ****************************************************************************/
728 static uint32 unix_filetype(mode_t mode)
731 return UNIX_TYPE_FILE;
732 else if(S_ISDIR(mode))
733 return UNIX_TYPE_DIR;
735 else if(S_ISLNK(mode))
736 return UNIX_TYPE_SYMLINK;
739 else if(S_ISCHR(mode))
740 return UNIX_TYPE_CHARDEV;
743 else if(S_ISBLK(mode))
744 return UNIX_TYPE_BLKDEV;
747 else if(S_ISFIFO(mode))
748 return UNIX_TYPE_FIFO;
751 else if(S_ISSOCK(mode))
752 return UNIX_TYPE_SOCKET;
755 DEBUG(0,("unix_filetype: unknown filetype %u", (unsigned)mode));
756 return UNIX_TYPE_UNKNOWN;
759 /****************************************************************************
760 Map wire perms onto standard UNIX permissions. Obey share restrictions.
761 ****************************************************************************/
763 static mode_t unix_perms_from_wire( connection_struct *conn, SMB_STRUCT_STAT *pst, uint32 perms)
767 if (perms == SMB_MODE_NO_CHANGE)
770 ret |= ((perms & UNIX_X_OTH ) ? S_IXOTH : 0);
771 ret |= ((perms & UNIX_W_OTH ) ? S_IWOTH : 0);
772 ret |= ((perms & UNIX_R_OTH ) ? S_IROTH : 0);
773 ret |= ((perms & UNIX_X_GRP ) ? S_IXGRP : 0);
774 ret |= ((perms & UNIX_W_GRP ) ? S_IWGRP : 0);
775 ret |= ((perms & UNIX_R_GRP ) ? S_IRGRP : 0);
776 ret |= ((perms & UNIX_X_USR ) ? S_IXUSR : 0);
777 ret |= ((perms & UNIX_W_USR ) ? S_IWUSR : 0);
778 ret |= ((perms & UNIX_R_USR ) ? S_IRUSR : 0);
780 ret |= ((perms & UNIX_STICKY ) ? S_ISVTX : 0);
783 ret |= ((perms & UNIX_SET_GID ) ? S_ISGID : 0);
786 ret |= ((perms & UNIX_SET_UID ) ? S_ISUID : 0);
789 if (VALID_STAT(*pst) && S_ISDIR(pst->st_mode)) {
790 ret &= lp_dir_mask(SNUM(conn));
791 /* Add in force bits */
792 ret |= lp_force_dir_mode(SNUM(conn));
794 /* Apply mode mask */
795 ret &= lp_create_mask(SNUM(conn));
796 /* Add in force bits */
797 ret |= lp_force_create_mode(SNUM(conn));
803 /****************************************************************************
804 Get a level dependent lanman2 dir entry.
805 ****************************************************************************/
807 static BOOL get_lanman2_dir_entry(connection_struct *conn,
808 void *inbuf, void *outbuf,
809 char *path_mask,int dirtype,int info_level,
810 int requires_resume_key,
811 BOOL dont_descend,char **ppdata,
812 char *base_data, int space_remaining,
813 BOOL *out_of_space, BOOL *got_exact_match,
818 SMB_STRUCT_STAT sbuf;
822 char *p, *q, *pdata = *ppdata;
826 SMB_OFF_T file_size = 0;
827 SMB_BIG_UINT allocation_size = 0;
829 time_t mdate=0, adate=0, cdate=0;
831 char *last_entry_ptr;
833 int nt_extmode; /* Used for NT connections instead of mode */
834 BOOL needslash = ( conn->dirpath[strlen(conn->dirpath) -1] != '/');
837 *out_of_space = False;
838 *got_exact_match = False;
843 p = strrchr_m(path_mask,'/');
850 pstrcpy(mask, path_mask);
855 /* Needed if we run out of space */
856 long curr_dirpos = prev_dirpos = dptr_TellDir(conn->dirptr);
857 dname = dptr_ReadDirName(conn->dirptr,&curr_dirpos,&sbuf);
860 * Due to bugs in NT client redirectors we are not using
861 * resume keys any more - set them to zero.
862 * Check out the related comments in findfirst/findnext.
868 DEBUG(8,("get_lanman2_dir_entry:readdir on dirptr 0x%lx now at offset %ld\n",
869 (long)conn->dirptr,curr_dirpos));
874 pstrcpy(fname,dname);
876 if(!(got_match = *got_exact_match = exact_match(fname, mask, conn->case_sensitive)))
877 got_match = mask_match(fname, mask, conn->case_sensitive);
879 if(!got_match && !mangle_is_8_3(fname, False)) {
882 * It turns out that NT matches wildcards against
883 * both long *and* short names. This may explain some
884 * of the wildcard wierdness from old DOS clients
885 * that some people have been seeing.... JRA.
889 pstrcpy( newname, fname);
890 mangle_map( newname, True, False, SNUM(conn));
891 if(!(got_match = *got_exact_match = exact_match(newname, mask, conn->case_sensitive)))
892 got_match = mask_match(newname, mask, conn->case_sensitive);
896 BOOL isdots = (strequal(fname,"..") || strequal(fname,"."));
897 if (dont_descend && !isdots)
900 pstrcpy(pathreal,conn->dirpath);
902 pstrcat(pathreal,"/");
903 pstrcat(pathreal,dname);
905 if (INFO_LEVEL_IS_UNIX(info_level)) {
906 if (SMB_VFS_LSTAT(conn,pathreal,&sbuf) != 0) {
907 DEBUG(5,("get_lanman2_dir_entry:Couldn't lstat [%s] (%s)\n",
908 pathreal,strerror(errno)));
911 } else if (!VALID_STAT(sbuf) && SMB_VFS_STAT(conn,pathreal,&sbuf) != 0) {
913 /* Needed to show the msdfs symlinks as
916 if(lp_host_msdfs() &&
917 lp_msdfs_root(SNUM(conn)) &&
918 is_msdfs_link(conn, pathreal, NULL, NULL,
921 DEBUG(5,("get_lanman2_dir_entry: Masquerading msdfs link %s as a directory\n", pathreal));
922 sbuf.st_mode = (sbuf.st_mode & 0xFFF) | S_IFDIR;
926 DEBUG(5,("get_lanman2_dir_entry:Couldn't stat [%s] (%s)\n",
927 pathreal,strerror(errno)));
932 mode = dos_mode(conn,pathreal,&sbuf);
934 if (!dir_check_ftype(conn,mode,dirtype)) {
935 DEBUG(5,("[%s] attribs didn't match %x\n",fname,dirtype));
939 file_size = get_file_size(sbuf);
940 allocation_size = get_allocation_size(conn,NULL,&sbuf);
941 mdate = sbuf.st_mtime;
942 adate = sbuf.st_atime;
943 cdate = get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(conn)));
945 if (lp_dos_filetime_resolution(SNUM(conn))) {
952 /* This is necessary, as otherwise the
953 * desktop.ini file in this folder is
955 mode |= (lp_profile_acls(SNUM(conn)) ? aRONLY : 0);
959 DEBUG(5,("get_lanman2_dir_entry found %s fname=%s\n",pathreal,fname));
965 mangle_map(fname,False,True,SNUM(conn));
970 nt_extmode = mode ? mode : FILE_ATTRIBUTE_NORMAL;
972 switch (info_level) {
973 case SMB_INFO_STANDARD:
974 DEBUG(10,("get_lanman2_dir_entry: SMB_INFO_STANDARD\n"));
975 if(requires_resume_key) {
979 put_dos_date2(p,l1_fdateCreation,cdate);
980 put_dos_date2(p,l1_fdateLastAccess,adate);
981 put_dos_date2(p,l1_fdateLastWrite,mdate);
982 SIVAL(p,l1_cbFile,(uint32)file_size);
983 SIVAL(p,l1_cbFileAlloc,(uint32)allocation_size);
984 SSVAL(p,l1_attrFile,mode);
987 p += align_string(outbuf, p, 0);
988 len = srvstr_push(outbuf, p, fname, -1, STR_TERMINATE);
989 if (SVAL(outbuf, smb_flg2) & FLAGS2_UNICODE_STRINGS) {
991 SCVAL(nameptr, -1, len - 2);
993 SCVAL(nameptr, -1, 0);
997 SCVAL(nameptr, -1, len - 1);
999 SCVAL(nameptr, -1, 0);
1005 case SMB_INFO_QUERY_EA_SIZE:
1006 DEBUG(10,("get_lanman2_dir_entry: SMB_INFO_QUERY_EA_SIZE\n"));
1007 if(requires_resume_key) {
1011 put_dos_date2(p,l2_fdateCreation,cdate);
1012 put_dos_date2(p,l2_fdateLastAccess,adate);
1013 put_dos_date2(p,l2_fdateLastWrite,mdate);
1014 SIVAL(p,l2_cbFile,(uint32)file_size);
1015 SIVAL(p,l2_cbFileAlloc,(uint32)allocation_size);
1016 SSVAL(p,l2_attrFile,mode);
1018 unsigned int ea_size = estimate_ea_size(conn, NULL, pathreal);
1019 SIVAL(p,l2_cbList,ea_size); /* Extended attributes */
1023 len = srvstr_push(outbuf, p, fname, -1, STR_TERMINATE | STR_NOALIGN);
1024 if (SVAL(outbuf, smb_flg2) & FLAGS2_UNICODE_STRINGS) {
1037 SCVAL(nameptr,0,len);
1039 SCVAL(p,0,0); p += 1; /* Extra zero byte ? - why.. */
1042 case SMB_FIND_FILE_BOTH_DIRECTORY_INFO:
1043 DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_FILE_BOTH_DIRECTORY_INFO\n"));
1044 was_8_3 = mangle_is_8_3(fname, True);
1046 SIVAL(p,0,reskey); p += 4;
1047 put_long_date(p,cdate); p += 8;
1048 put_long_date(p,adate); p += 8;
1049 put_long_date(p,mdate); p += 8;
1050 put_long_date(p,mdate); p += 8;
1051 SOFF_T(p,0,file_size); p += 8;
1052 SOFF_T(p,0,allocation_size); p += 8;
1053 SIVAL(p,0,nt_extmode); p += 4;
1054 q = p; p += 4; /* q is placeholder for name length. */
1056 unsigned int ea_size = estimate_ea_size(conn, NULL, pathreal);
1057 SIVAL(p,0,ea_size); /* Extended attributes */
1060 /* Clear the short name buffer. This is
1061 * IMPORTANT as not doing so will trigger
1062 * a Win2k client bug. JRA.
1065 if (!was_8_3 && lp_manglednames(SNUM(conn))) {
1066 pstring mangled_name;
1067 pstrcpy(mangled_name, fname);
1068 mangle_map(mangled_name,True,True,SNUM(conn));
1069 mangled_name[12] = 0;
1070 len = srvstr_push(outbuf, p+2, mangled_name, 24, STR_UPPER|STR_UNICODE);
1077 len = srvstr_push(outbuf, p, fname, -1, STR_TERMINATE_ASCII);
1080 len = PTR_DIFF(p, pdata);
1081 len = (len + 3) & ~3;
1086 case SMB_FIND_FILE_DIRECTORY_INFO:
1087 DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_FILE_DIRECTORY_INFO\n"));
1089 SIVAL(p,0,reskey); p += 4;
1090 put_long_date(p,cdate); p += 8;
1091 put_long_date(p,adate); p += 8;
1092 put_long_date(p,mdate); p += 8;
1093 put_long_date(p,mdate); p += 8;
1094 SOFF_T(p,0,file_size); p += 8;
1095 SOFF_T(p,0,allocation_size); p += 8;
1096 SIVAL(p,0,nt_extmode); p += 4;
1097 len = srvstr_push(outbuf, p + 4, fname, -1, STR_TERMINATE_ASCII);
1100 len = PTR_DIFF(p, pdata);
1101 len = (len + 3) & ~3;
1106 case SMB_FIND_FILE_FULL_DIRECTORY_INFO:
1107 DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_FILE_FULL_DIRECTORY_INFO\n"));
1109 SIVAL(p,0,reskey); p += 4;
1110 put_long_date(p,cdate); p += 8;
1111 put_long_date(p,adate); p += 8;
1112 put_long_date(p,mdate); p += 8;
1113 put_long_date(p,mdate); p += 8;
1114 SOFF_T(p,0,file_size); p += 8;
1115 SOFF_T(p,0,allocation_size); p += 8;
1116 SIVAL(p,0,nt_extmode); p += 4;
1117 q = p; p += 4; /* q is placeholder for name length. */
1119 unsigned int ea_size = estimate_ea_size(conn, NULL, pathreal);
1120 SIVAL(p,0,ea_size); /* Extended attributes */
1123 len = srvstr_push(outbuf, p, fname, -1, STR_TERMINATE_ASCII);
1127 len = PTR_DIFF(p, pdata);
1128 len = (len + 3) & ~3;
1133 case SMB_FIND_FILE_NAMES_INFO:
1134 DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_FILE_NAMES_INFO\n"));
1136 SIVAL(p,0,reskey); p += 4;
1138 /* this must *not* be null terminated or w2k gets in a loop trying to set an
1139 acl on a dir (tridge) */
1140 len = srvstr_push(outbuf, p, fname, -1, STR_TERMINATE_ASCII);
1143 len = PTR_DIFF(p, pdata);
1144 len = (len + 3) & ~3;
1149 case SMB_FIND_ID_FULL_DIRECTORY_INFO:
1150 DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_ID_FULL_DIRECTORY_INFO\n"));
1152 SIVAL(p,0,reskey); p += 4;
1153 put_long_date(p,cdate); p += 8;
1154 put_long_date(p,adate); p += 8;
1155 put_long_date(p,mdate); p += 8;
1156 put_long_date(p,mdate); p += 8;
1157 SOFF_T(p,0,file_size); p += 8;
1158 SOFF_T(p,0,allocation_size); p += 8;
1159 SIVAL(p,0,nt_extmode); p += 4;
1160 q = p; p += 4; /* q is placeholder for name length. */
1162 unsigned int ea_size = estimate_ea_size(conn, NULL, pathreal);
1163 SIVAL(p,0,ea_size); /* Extended attributes */
1166 SIVAL(p,0,0); p += 4; /* Unknown - reserved ? */
1167 SIVAL(p,0,sbuf.st_dev); p += 4;
1168 SIVAL(p,0,sbuf.st_ino); p += 4;
1169 len = srvstr_push(outbuf, p, fname, -1, STR_TERMINATE_ASCII);
1172 len = PTR_DIFF(p, pdata);
1173 len = (len + 3) & ~3;
1178 case SMB_FIND_ID_BOTH_DIRECTORY_INFO:
1179 DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_ID_BOTH_DIRECTORY_INFO\n"));
1180 was_8_3 = mangle_is_8_3(fname, True);
1182 SIVAL(p,0,reskey); p += 4;
1183 put_long_date(p,cdate); p += 8;
1184 put_long_date(p,adate); p += 8;
1185 put_long_date(p,mdate); p += 8;
1186 put_long_date(p,mdate); p += 8;
1187 SOFF_T(p,0,file_size); p += 8;
1188 SOFF_T(p,0,allocation_size); p += 8;
1189 SIVAL(p,0,nt_extmode); p += 4;
1190 q = p; p += 4; /* q is placeholder for name length */
1192 unsigned int ea_size = estimate_ea_size(conn, NULL, pathreal);
1193 SIVAL(p,0,ea_size); /* Extended attributes */
1196 /* Clear the short name buffer. This is
1197 * IMPORTANT as not doing so will trigger
1198 * a Win2k client bug. JRA.
1201 if (!was_8_3 && lp_manglednames(SNUM(conn))) {
1202 pstring mangled_name;
1203 pstrcpy(mangled_name, fname);
1204 mangle_map(mangled_name,True,True,SNUM(conn));
1205 mangled_name[12] = 0;
1206 len = srvstr_push(outbuf, p+2, mangled_name, 24, STR_UPPER|STR_UNICODE);
1213 SSVAL(p,0,0); p += 2; /* Reserved ? */
1214 SIVAL(p,0,sbuf.st_dev); p += 4;
1215 SIVAL(p,0,sbuf.st_ino); p += 4;
1216 len = srvstr_push(outbuf, p, fname, -1, STR_TERMINATE_ASCII);
1219 len = PTR_DIFF(p, pdata);
1220 len = (len + 3) & ~3;
1225 /* CIFS UNIX Extension. */
1227 case SMB_FIND_FILE_UNIX:
1228 DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_FILE_UNIX\n"));
1230 SIVAL(p,0,reskey); p+= 4; /* Used for continuing search. */
1232 /* Begin of SMB_QUERY_FILE_UNIX_BASIC */
1233 SOFF_T(p,0,get_file_size(sbuf)); /* File size 64 Bit */
1236 SOFF_T(p,0,get_allocation_size(conn,NULL,&sbuf)); /* Number of bytes used on disk - 64 Bit */
1239 put_long_date(p,sbuf.st_ctime); /* Inode change Time 64 Bit */
1240 put_long_date(p+8,sbuf.st_atime); /* Last access time 64 Bit */
1241 put_long_date(p+16,sbuf.st_mtime); /* Last modification time 64 Bit */
1244 SIVAL(p,0,sbuf.st_uid); /* user id for the owner */
1248 SIVAL(p,0,sbuf.st_gid); /* group id of owner */
1252 SIVAL(p,0,unix_filetype(sbuf.st_mode));
1255 SIVAL(p,0,unix_dev_major(sbuf.st_rdev)); /* Major device number if type is device */
1259 SIVAL(p,0,unix_dev_minor(sbuf.st_rdev)); /* Minor device number if type is device */
1263 SINO_T(p,0,(SMB_INO_T)sbuf.st_ino); /* inode number */
1266 SIVAL(p,0, unix_perms_to_wire(sbuf.st_mode)); /* Standard UNIX file permissions */
1270 SIVAL(p,0,sbuf.st_nlink); /* number of hard links */
1274 len = srvstr_push(outbuf, p, fname, -1, STR_TERMINATE);
1277 len = PTR_DIFF(p, pdata);
1278 len = (len + 3) & ~3;
1279 SIVAL(pdata,0,len); /* Offset from this structure to the beginning of the next one */
1281 /* End of SMB_QUERY_FILE_UNIX_BASIC */
1290 if (PTR_DIFF(p,pdata) > space_remaining) {
1291 /* Move the dirptr back to prev_dirpos */
1292 dptr_SeekDir(conn->dirptr, prev_dirpos);
1293 *out_of_space = True;
1294 DEBUG(9,("get_lanman2_dir_entry: out of space\n"));
1295 return False; /* Not finished - just out of space */
1298 /* Setup the last entry pointer, as an offset from base_data */
1299 *last_entry_off = PTR_DIFF(last_entry_ptr,base_data);
1300 /* Advance the data pointer to the next slot */
1306 /****************************************************************************
1307 Reply to a TRANS2_FINDFIRST.
1308 ****************************************************************************/
1310 static int call_trans2findfirst(connection_struct *conn, char *inbuf, char *outbuf, int bufsize,
1311 char **pparams, int total_params, char **ppdata, int total_data,
1312 unsigned int max_data_bytes)
1314 /* We must be careful here that we don't return more than the
1315 allowed number of data bytes. If this means returning fewer than
1316 maxentries then so be it. We assume that the redirector has
1317 enough room for the fixed number of parameter bytes it has
1319 char *params = *pparams;
1320 char *pdata = *ppdata;
1321 int dirtype = SVAL(params,0);
1322 int maxentries = SVAL(params,2);
1323 uint16 findfirst_flags = SVAL(params,4);
1324 BOOL close_after_first = (findfirst_flags & FLAG_TRANS2_FIND_CLOSE);
1325 BOOL close_if_end = (findfirst_flags & FLAG_TRANS2_FIND_CLOSE_IF_END);
1326 BOOL requires_resume_key = (findfirst_flags & FLAG_TRANS2_FIND_REQUIRE_RESUME);
1327 int info_level = SVAL(params,6);
1331 int last_entry_off=0;
1335 BOOL finished = False;
1336 BOOL dont_descend = False;
1337 BOOL out_of_space = False;
1338 int space_remaining;
1339 BOOL bad_path = False;
1340 SMB_STRUCT_STAT sbuf;
1341 NTSTATUS ntstatus = NT_STATUS_OK;
1343 if (total_params < 12)
1344 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
1346 *directory = *mask = 0;
1348 DEBUG(3,("call_trans2findfirst: dirtype = %d, maxentries = %d, close_after_first=%d, \
1349 close_if_end = %d requires_resume_key = %d level = 0x%x, max_data_bytes = %d\n",
1350 dirtype, maxentries, close_after_first, close_if_end, requires_resume_key,
1351 info_level, max_data_bytes));
1354 /* W2K3 seems to treat zero as 1. */
1358 switch (info_level) {
1359 case SMB_INFO_STANDARD:
1360 case SMB_INFO_QUERY_EA_SIZE:
1361 case SMB_FIND_FILE_DIRECTORY_INFO:
1362 case SMB_FIND_FILE_FULL_DIRECTORY_INFO:
1363 case SMB_FIND_FILE_NAMES_INFO:
1364 case SMB_FIND_FILE_BOTH_DIRECTORY_INFO:
1365 case SMB_FIND_ID_FULL_DIRECTORY_INFO:
1366 case SMB_FIND_ID_BOTH_DIRECTORY_INFO:
1368 case SMB_FIND_FILE_UNIX:
1369 if (!lp_unix_extensions())
1370 return(ERROR_DOS(ERRDOS,ERRunknownlevel));
1373 return(ERROR_DOS(ERRDOS,ERRunknownlevel));
1376 srvstr_get_path(inbuf, directory, params+12, sizeof(directory), -1, STR_TERMINATE, &ntstatus, True);
1377 if (!NT_STATUS_IS_OK(ntstatus)) {
1378 return ERROR_NT(ntstatus);
1381 RESOLVE_FINDFIRST_DFSPATH(directory, conn, inbuf, outbuf);
1383 unix_convert(directory,conn,0,&bad_path,&sbuf);
1385 return ERROR_NT(NT_STATUS_OBJECT_PATH_NOT_FOUND);
1387 if(!check_name(directory,conn)) {
1388 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRbadpath);
1391 p = strrchr_m(directory,'/');
1393 /* Windows and OS/2 systems treat search on the root '\' as if it were '\*' */
1394 if((directory[0] == '.') && (directory[1] == '\0'))
1397 pstrcpy(mask,directory);
1398 pstrcpy(directory,"./");
1404 DEBUG(5,("dir=%s, mask = %s\n",directory, mask));
1406 pdata = SMB_REALLOC(*ppdata, max_data_bytes + DIR_ENTRY_SAFETY_MARGIN);
1408 return(ERROR_DOS(ERRDOS,ERRnomem));
1411 memset((char *)pdata,'\0',max_data_bytes + DIR_ENTRY_SAFETY_MARGIN);
1413 /* Realloc the params space */
1414 params = SMB_REALLOC(*pparams, 10);
1416 return ERROR_DOS(ERRDOS,ERRnomem);
1419 dptr_num = dptr_create(conn,directory, False, True ,SVAL(inbuf,smb_pid));
1421 return(UNIXERROR(ERRDOS,ERRbadfile));
1423 /* Save the wildcard match and attribs we are using on this directory -
1424 needed as lanman2 assumes these are being saved between calls */
1426 if (!dptr_set_wcard_and_attributes(dptr_num, mask, dirtype)) {
1427 dptr_close(&dptr_num);
1428 return ERROR_DOS(ERRDOS,ERRnomem);
1431 DEBUG(4,("dptr_num is %d, wcard = %s, attr = %d\n",dptr_num, mask, dirtype));
1433 /* We don't need to check for VOL here as this is returned by
1434 a different TRANS2 call. */
1436 DEBUG(8,("dirpath=<%s> dontdescend=<%s>\n", conn->dirpath,lp_dontdescend(SNUM(conn))));
1437 if (in_list(conn->dirpath,lp_dontdescend(SNUM(conn)),conn->case_sensitive))
1438 dont_descend = True;
1441 space_remaining = max_data_bytes;
1442 out_of_space = False;
1444 for (i=0;(i<maxentries) && !finished && !out_of_space;i++) {
1445 BOOL got_exact_match = False;
1447 /* this is a heuristic to avoid seeking the dirptr except when
1448 absolutely necessary. It allows for a filename of about 40 chars */
1449 if (space_remaining < DIRLEN_GUESS && numentries > 0) {
1450 out_of_space = True;
1453 finished = !get_lanman2_dir_entry(conn,
1455 mask,dirtype,info_level,
1456 requires_resume_key,dont_descend,
1457 &p,pdata,space_remaining, &out_of_space, &got_exact_match,
1461 if (finished && out_of_space)
1464 if (!finished && !out_of_space)
1468 * As an optimisation if we know we aren't looking
1469 * for a wildcard name (ie. the name matches the wildcard exactly)
1470 * then we can finish on any (first) match.
1471 * This speeds up large directory searches. JRA.
1477 space_remaining = max_data_bytes - PTR_DIFF(p,pdata);
1480 /* Check if we can close the dirptr */
1481 if(close_after_first || (finished && close_if_end)) {
1482 DEBUG(5,("call_trans2findfirst - (2) closing dptr_num %d\n", dptr_num));
1483 dptr_close(&dptr_num);
1487 * If there are no matching entries we must return ERRDOS/ERRbadfile -
1488 * from observation of NT.
1491 if(numentries == 0) {
1492 dptr_close(&dptr_num);
1493 return ERROR_DOS(ERRDOS,ERRbadfile);
1496 /* At this point pdata points to numentries directory entries. */
1498 /* Set up the return parameter block */
1499 SSVAL(params,0,dptr_num);
1500 SSVAL(params,2,numentries);
1501 SSVAL(params,4,finished);
1502 SSVAL(params,6,0); /* Never an EA error */
1503 SSVAL(params,8,last_entry_off);
1505 send_trans2_replies( outbuf, bufsize, params, 10, pdata, PTR_DIFF(p,pdata));
1507 if ((! *directory) && dptr_path(dptr_num))
1508 slprintf(directory,sizeof(directory)-1, "(%s)",dptr_path(dptr_num));
1510 DEBUG( 4, ( "%s mask=%s directory=%s dirtype=%d numentries=%d\n",
1511 smb_fn_name(CVAL(inbuf,smb_com)),
1512 mask, directory, dirtype, numentries ) );
1515 * Force a name mangle here to ensure that the
1516 * mask as an 8.3 name is top of the mangled cache.
1517 * The reasons for this are subtle. Don't remove
1518 * this code unless you know what you are doing
1519 * (see PR#13758). JRA.
1522 if(!mangle_is_8_3_wildcards( mask, False))
1523 mangle_map(mask, True, True, SNUM(conn));
1528 /****************************************************************************
1529 Reply to a TRANS2_FINDNEXT.
1530 ****************************************************************************/
1532 static int call_trans2findnext(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize,
1533 char **pparams, int total_params, char **ppdata, int total_data,
1534 unsigned int max_data_bytes)
1536 /* We must be careful here that we don't return more than the
1537 allowed number of data bytes. If this means returning fewer than
1538 maxentries then so be it. We assume that the redirector has
1539 enough room for the fixed number of parameter bytes it has
1541 char *params = *pparams;
1542 char *pdata = *ppdata;
1543 int dptr_num = SVAL(params,0);
1544 int maxentries = SVAL(params,2);
1545 uint16 info_level = SVAL(params,4);
1546 uint32 resume_key = IVAL(params,6);
1547 uint16 findnext_flags = SVAL(params,10);
1548 BOOL close_after_request = (findnext_flags & FLAG_TRANS2_FIND_CLOSE);
1549 BOOL close_if_end = (findnext_flags & FLAG_TRANS2_FIND_CLOSE_IF_END);
1550 BOOL requires_resume_key = (findnext_flags & FLAG_TRANS2_FIND_REQUIRE_RESUME);
1551 BOOL continue_bit = (findnext_flags & FLAG_TRANS2_FIND_CONTINUE);
1552 pstring resume_name;
1558 int i, last_entry_off=0;
1559 BOOL finished = False;
1560 BOOL dont_descend = False;
1561 BOOL out_of_space = False;
1562 int space_remaining;
1563 NTSTATUS ntstatus = NT_STATUS_OK;
1565 if (total_params < 12)
1566 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
1568 *mask = *directory = *resume_name = 0;
1570 srvstr_get_path(inbuf, resume_name, params+12, sizeof(resume_name), -1, STR_TERMINATE, &ntstatus, True);
1571 if (!NT_STATUS_IS_OK(ntstatus)) {
1572 return ERROR_NT(ntstatus);
1575 DEBUG(3,("call_trans2findnext: dirhandle = %d, max_data_bytes = %d, maxentries = %d, \
1576 close_after_request=%d, close_if_end = %d requires_resume_key = %d \
1577 resume_key = %d resume name = %s continue=%d level = %d\n",
1578 dptr_num, max_data_bytes, maxentries, close_after_request, close_if_end,
1579 requires_resume_key, resume_key, resume_name, continue_bit, info_level));
1582 /* W2K3 seems to treat zero as 1. */
1586 switch (info_level) {
1587 case SMB_INFO_STANDARD:
1588 case SMB_INFO_QUERY_EA_SIZE:
1589 case SMB_FIND_FILE_DIRECTORY_INFO:
1590 case SMB_FIND_FILE_FULL_DIRECTORY_INFO:
1591 case SMB_FIND_FILE_NAMES_INFO:
1592 case SMB_FIND_FILE_BOTH_DIRECTORY_INFO:
1594 case SMB_FIND_FILE_UNIX:
1595 if (!lp_unix_extensions())
1596 return(ERROR_DOS(ERRDOS,ERRunknownlevel));
1599 return ERROR_DOS(ERRDOS,ERRunknownlevel);
1602 pdata = SMB_REALLOC( *ppdata, max_data_bytes + DIR_ENTRY_SAFETY_MARGIN);
1604 return ERROR_DOS(ERRDOS,ERRnomem);
1607 memset((char *)pdata,'\0',max_data_bytes + DIR_ENTRY_SAFETY_MARGIN);
1609 /* Realloc the params space */
1610 params = SMB_REALLOC(*pparams, 6*SIZEOFWORD);
1611 if( params == NULL )
1612 return ERROR_DOS(ERRDOS,ERRnomem);
1616 /* Check that the dptr is valid */
1617 if(!(conn->dirptr = dptr_fetch_lanman2(dptr_num)))
1618 return ERROR_DOS(ERRDOS,ERRnofiles);
1620 string_set(&conn->dirpath,dptr_path(dptr_num));
1622 /* Get the wildcard mask from the dptr */
1623 if((p = dptr_wcard(dptr_num))== NULL) {
1624 DEBUG(2,("dptr_num %d has no wildcard\n", dptr_num));
1625 return ERROR_DOS(ERRDOS,ERRnofiles);
1629 pstrcpy(directory,conn->dirpath);
1631 /* Get the attr mask from the dptr */
1632 dirtype = dptr_attr(dptr_num);
1634 DEBUG(3,("dptr_num is %d, mask = %s, attr = %x, dirptr=(0x%lX,%ld)\n",
1635 dptr_num, mask, dirtype,
1637 dptr_TellDir(conn->dirptr)));
1639 /* We don't need to check for VOL here as this is returned by
1640 a different TRANS2 call. */
1642 DEBUG(8,("dirpath=<%s> dontdescend=<%s>\n",conn->dirpath,lp_dontdescend(SNUM(conn))));
1643 if (in_list(conn->dirpath,lp_dontdescend(SNUM(conn)),conn->case_sensitive))
1644 dont_descend = True;
1647 space_remaining = max_data_bytes;
1648 out_of_space = False;
1651 * Seek to the correct position. We no longer use the resume key but
1652 * depend on the last file name instead.
1655 if(*resume_name && !continue_bit) {
1658 long current_pos = 0;
1660 * Remember, mangle_map is called by
1661 * get_lanman2_dir_entry(), so the resume name
1662 * could be mangled. Ensure we check the unmangled name.
1665 if (mangle_is_mangled(resume_name)) {
1666 mangle_check_cache(resume_name, sizeof(resume_name)-1);
1670 * Fix for NT redirector problem triggered by resume key indexes
1671 * changing between directory scans. We now return a resume key of 0
1672 * and instead look for the filename to continue from (also given
1673 * to us by NT/95/smbfs/smbclient). If no other scans have been done between the
1674 * findfirst/findnext (as is usual) then the directory pointer
1675 * should already be at the correct place.
1678 finished = !dptr_SearchDir(conn->dirptr, resume_name, ¤t_pos, &st);
1679 } /* end if resume_name && !continue_bit */
1681 for (i=0;(i<(int)maxentries) && !finished && !out_of_space ;i++) {
1682 BOOL got_exact_match = False;
1684 /* this is a heuristic to avoid seeking the dirptr except when
1685 absolutely necessary. It allows for a filename of about 40 chars */
1686 if (space_remaining < DIRLEN_GUESS && numentries > 0) {
1687 out_of_space = True;
1690 finished = !get_lanman2_dir_entry(conn,
1692 mask,dirtype,info_level,
1693 requires_resume_key,dont_descend,
1694 &p,pdata,space_remaining, &out_of_space, &got_exact_match,
1698 if (finished && out_of_space)
1701 if (!finished && !out_of_space)
1705 * As an optimisation if we know we aren't looking
1706 * for a wildcard name (ie. the name matches the wildcard exactly)
1707 * then we can finish on any (first) match.
1708 * This speeds up large directory searches. JRA.
1714 space_remaining = max_data_bytes - PTR_DIFF(p,pdata);
1717 /* Check if we can close the dirptr */
1718 if(close_after_request || (finished && close_if_end)) {
1719 DEBUG(5,("call_trans2findnext: closing dptr_num = %d\n", dptr_num));
1720 dptr_close(&dptr_num); /* This frees up the saved mask */
1723 /* Set up the return parameter block */
1724 SSVAL(params,0,numentries);
1725 SSVAL(params,2,finished);
1726 SSVAL(params,4,0); /* Never an EA error */
1727 SSVAL(params,6,last_entry_off);
1729 send_trans2_replies( outbuf, bufsize, params, 8, pdata, PTR_DIFF(p,pdata));
1731 if ((! *directory) && dptr_path(dptr_num))
1732 slprintf(directory,sizeof(directory)-1, "(%s)",dptr_path(dptr_num));
1734 DEBUG( 3, ( "%s mask=%s directory=%s dirtype=%d numentries=%d\n",
1735 smb_fn_name(CVAL(inbuf,smb_com)),
1736 mask, directory, dirtype, numentries ) );
1741 /****************************************************************************
1742 Reply to a TRANS2_QFSINFO (query filesystem info).
1743 ****************************************************************************/
1745 static int call_trans2qfsinfo(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize,
1746 char **pparams, int total_params, char **ppdata, int total_data,
1747 unsigned int max_data_bytes)
1749 char *pdata = *ppdata;
1750 char *params = *pparams;
1751 uint16 info_level = SVAL(params,0);
1754 char *vname = volume_label(SNUM(conn));
1755 int snum = SNUM(conn);
1756 char *fstype = lp_fstype(SNUM(conn));
1759 DEBUG(3,("call_trans2qfsinfo: level = %d\n", info_level));
1761 if(SMB_VFS_STAT(conn,".",&st)!=0) {
1762 DEBUG(2,("call_trans2qfsinfo: stat of . failed (%s)\n", strerror(errno)));
1763 return ERROR_DOS(ERRSRV,ERRinvdevice);
1766 pdata = SMB_REALLOC(*ppdata, max_data_bytes + DIR_ENTRY_SAFETY_MARGIN);
1767 if ( pdata == NULL )
1768 return ERROR_DOS(ERRDOS,ERRnomem);
1771 memset((char *)pdata,'\0',max_data_bytes + DIR_ENTRY_SAFETY_MARGIN);
1773 switch (info_level) {
1774 case SMB_INFO_ALLOCATION:
1776 SMB_BIG_UINT dfree,dsize,bsize,block_size,sectors_per_unit,bytes_per_sector;
1778 SMB_VFS_DISK_FREE(conn,".",False,&bsize,&dfree,&dsize);
1779 block_size = lp_block_size(snum);
1780 if (bsize < block_size) {
1781 SMB_BIG_UINT factor = block_size/bsize;
1786 if (bsize > block_size) {
1787 SMB_BIG_UINT factor = bsize/block_size;
1792 bytes_per_sector = 512;
1793 sectors_per_unit = bsize/bytes_per_sector;
1795 DEBUG(5,("call_trans2qfsinfo : SMB_INFO_ALLOCATION id=%x, bsize=%u, cSectorUnit=%u, \
1796 cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)st.st_dev, (unsigned int)bsize, (unsigned int)sectors_per_unit,
1797 (unsigned int)bytes_per_sector, (unsigned int)dsize, (unsigned int)dfree));
1799 SIVAL(pdata,l1_idFileSystem,st.st_dev);
1800 SIVAL(pdata,l1_cSectorUnit,sectors_per_unit);
1801 SIVAL(pdata,l1_cUnit,dsize);
1802 SIVAL(pdata,l1_cUnitAvail,dfree);
1803 SSVAL(pdata,l1_cbSector,bytes_per_sector);
1807 case SMB_INFO_VOLUME:
1808 /* Return volume name */
1810 * Add volume serial number - hash of a combination of
1811 * the called hostname and the service name.
1813 SIVAL(pdata,0,str_checksum(lp_servicename(snum)) ^ (str_checksum(get_local_machine_name())<<16) );
1814 len = srvstr_push(outbuf, pdata+l2_vol_szVolLabel, vname, -1, STR_NOALIGN);
1815 SCVAL(pdata,l2_vol_cch,len);
1816 data_len = l2_vol_szVolLabel + len;
1817 DEBUG(5,("call_trans2qfsinfo : time = %x, namelen = %d, name = %s\n",
1818 (unsigned)st.st_ctime, len, vname));
1821 case SMB_QUERY_FS_ATTRIBUTE_INFO:
1822 case SMB_FS_ATTRIBUTE_INFORMATION:
1825 #if defined(HAVE_SYS_QUOTAS)
1826 quota_flag = FILE_VOLUME_QUOTAS;
1829 SIVAL(pdata,0,FILE_CASE_PRESERVED_NAMES|FILE_CASE_SENSITIVE_SEARCH|
1830 (lp_nt_acl_support(SNUM(conn)) ? FILE_PERSISTENT_ACLS : 0)|
1831 quota_flag); /* FS ATTRIBUTES */
1833 SIVAL(pdata,4,255); /* Max filename component length */
1834 /* NOTE! the fstype must *not* be null terminated or win98 won't recognise it
1835 and will think we can't do long filenames */
1836 len = srvstr_push(outbuf, pdata+12, fstype, -1, STR_UNICODE);
1838 data_len = 12 + len;
1841 case SMB_QUERY_FS_LABEL_INFO:
1842 case SMB_FS_LABEL_INFORMATION:
1843 len = srvstr_push(outbuf, pdata+4, vname, -1, 0);
1848 case SMB_QUERY_FS_VOLUME_INFO:
1849 case SMB_FS_VOLUME_INFORMATION:
1852 * Add volume serial number - hash of a combination of
1853 * the called hostname and the service name.
1855 SIVAL(pdata,8,str_checksum(lp_servicename(snum)) ^
1856 (str_checksum(get_local_machine_name())<<16));
1858 len = srvstr_push(outbuf, pdata+18, vname, -1, STR_UNICODE);
1859 SIVAL(pdata,12,len);
1861 DEBUG(5,("call_trans2qfsinfo : SMB_QUERY_FS_VOLUME_INFO namelen = %d, vol=%s serv=%s\n",
1862 (int)strlen(vname),vname, lp_servicename(snum)));
1865 case SMB_QUERY_FS_SIZE_INFO:
1866 case SMB_FS_SIZE_INFORMATION:
1868 SMB_BIG_UINT dfree,dsize,bsize,block_size,sectors_per_unit,bytes_per_sector;
1870 SMB_VFS_DISK_FREE(conn,".",False,&bsize,&dfree,&dsize);
1871 block_size = lp_block_size(snum);
1872 if (bsize < block_size) {
1873 SMB_BIG_UINT factor = block_size/bsize;
1878 if (bsize > block_size) {
1879 SMB_BIG_UINT factor = bsize/block_size;
1884 bytes_per_sector = 512;
1885 sectors_per_unit = bsize/bytes_per_sector;
1886 DEBUG(5,("call_trans2qfsinfo : SMB_QUERY_FS_SIZE_INFO bsize=%u, cSectorUnit=%u, \
1887 cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize, (unsigned int)sectors_per_unit,
1888 (unsigned int)bytes_per_sector, (unsigned int)dsize, (unsigned int)dfree));
1889 SBIG_UINT(pdata,0,dsize);
1890 SBIG_UINT(pdata,8,dfree);
1891 SIVAL(pdata,16,sectors_per_unit);
1892 SIVAL(pdata,20,bytes_per_sector);
1896 case SMB_FS_FULL_SIZE_INFORMATION:
1898 SMB_BIG_UINT dfree,dsize,bsize,block_size,sectors_per_unit,bytes_per_sector;
1900 SMB_VFS_DISK_FREE(conn,".",False,&bsize,&dfree,&dsize);
1901 block_size = lp_block_size(snum);
1902 if (bsize < block_size) {
1903 SMB_BIG_UINT factor = block_size/bsize;
1908 if (bsize > block_size) {
1909 SMB_BIG_UINT factor = bsize/block_size;
1914 bytes_per_sector = 512;
1915 sectors_per_unit = bsize/bytes_per_sector;
1916 DEBUG(5,("call_trans2qfsinfo : SMB_QUERY_FS_FULL_SIZE_INFO bsize=%u, cSectorUnit=%u, \
1917 cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize, (unsigned int)sectors_per_unit,
1918 (unsigned int)bytes_per_sector, (unsigned int)dsize, (unsigned int)dfree));
1919 SBIG_UINT(pdata,0,dsize); /* Total Allocation units. */
1920 SBIG_UINT(pdata,8,dfree); /* Caller available allocation units. */
1921 SBIG_UINT(pdata,16,dfree); /* Actual available allocation units. */
1922 SIVAL(pdata,24,sectors_per_unit); /* Sectors per allocation unit. */
1923 SIVAL(pdata,28,bytes_per_sector); /* Bytes per sector. */
1927 case SMB_QUERY_FS_DEVICE_INFO:
1928 case SMB_FS_DEVICE_INFORMATION:
1930 SIVAL(pdata,0,0); /* dev type */
1931 SIVAL(pdata,4,0); /* characteristics */
1934 #ifdef HAVE_SYS_QUOTAS
1935 case SMB_FS_QUOTA_INFORMATION:
1937 * what we have to send --metze:
1939 * Unknown1: 24 NULL bytes
1940 * Soft Quota Treshold: 8 bytes seems like SMB_BIG_UINT or so
1941 * Hard Quota Limit: 8 bytes seems like SMB_BIG_UINT or so
1942 * Quota Flags: 2 byte :
1943 * Unknown3: 6 NULL bytes
1947 * details for Quota Flags:
1949 * 0x0020 Log Limit: log if the user exceeds his Hard Quota
1950 * 0x0010 Log Warn: log if the user exceeds his Soft Quota
1951 * 0x0002 Deny Disk: deny disk access when the user exceeds his Hard Quota
1952 * 0x0001 Enable Quotas: enable quota for this fs
1956 /* we need to fake up a fsp here,
1957 * because its not send in this call
1960 SMB_NTQUOTA_STRUCT quotas;
1963 ZERO_STRUCT(quotas);
1970 if (current_user.uid != 0) {
1971 DEBUG(0,("set_user_quota: access_denied service [%s] user [%s]\n",
1972 lp_servicename(SNUM(conn)),conn->user));
1973 return ERROR_DOS(ERRDOS,ERRnoaccess);
1976 if (vfs_get_ntquota(&fsp, SMB_USER_FS_QUOTA_TYPE, NULL, "as)!=0) {
1977 DEBUG(0,("vfs_get_ntquota() failed for service [%s]\n",lp_servicename(SNUM(conn))));
1978 return ERROR_DOS(ERRSRV,ERRerror);
1983 DEBUG(10,("SMB_FS_QUOTA_INFORMATION: for service [%s]\n",lp_servicename(SNUM(conn))));
1985 /* Unknown1 24 NULL bytes*/
1986 SBIG_UINT(pdata,0,(SMB_BIG_UINT)0);
1987 SBIG_UINT(pdata,8,(SMB_BIG_UINT)0);
1988 SBIG_UINT(pdata,16,(SMB_BIG_UINT)0);
1990 /* Default Soft Quota 8 bytes */
1991 SBIG_UINT(pdata,24,quotas.softlim);
1993 /* Default Hard Quota 8 bytes */
1994 SBIG_UINT(pdata,32,quotas.hardlim);
1996 /* Quota flag 2 bytes */
1997 SSVAL(pdata,40,quotas.qflags);
1999 /* Unknown3 6 NULL bytes */
2005 #endif /* HAVE_SYS_QUOTAS */
2006 case SMB_FS_OBJECTID_INFORMATION:
2011 * Query the version and capabilities of the CIFS UNIX extensions
2015 case SMB_QUERY_CIFS_UNIX_INFO:
2016 if (!lp_unix_extensions())
2017 return ERROR_DOS(ERRDOS,ERRunknownlevel);
2019 SSVAL(pdata,0,CIFS_UNIX_MAJOR_VERSION);
2020 SSVAL(pdata,2,CIFS_UNIX_MINOR_VERSION);
2021 SBIG_UINT(pdata,4,((SMB_BIG_UINT)CIFS_UNIX_POSIX_ACLS_CAP)); /* We have POSIX ACLs. */
2024 case SMB_MAC_QUERY_FS_INFO:
2026 * Thursby MAC extension... ONLY on NTFS filesystems
2027 * once we do streams then we don't need this
2029 if (strequal(lp_fstype(SNUM(conn)),"NTFS")) {
2031 SIVAL(pdata,84,0x100); /* Don't support mac... */
2036 return ERROR_DOS(ERRDOS,ERRunknownlevel);
2040 send_trans2_replies( outbuf, bufsize, params, 0, pdata, data_len);
2042 DEBUG( 4, ( "%s info_level = %d\n", smb_fn_name(CVAL(inbuf,smb_com)), info_level) );
2047 #ifdef HAVE_SYS_QUOTAS
2048 /****************************************************************************
2049 Reply to a TRANS2_SETFSINFO (set filesystem info).
2050 ****************************************************************************/
2052 static int call_trans2setfsinfo(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize,
2053 char **pparams, int total_params, char **ppdata, int total_data,
2054 unsigned int max_data_bytes)
2056 char *pdata = *ppdata;
2057 char *params = *pparams;
2058 files_struct *fsp = NULL;
2061 SMB_NTQUOTA_STRUCT quotas;
2063 ZERO_STRUCT(quotas);
2065 DEBUG(10,("call_trans2setfsinfo: SET_FS_QUOTA: for service [%s]\n",lp_servicename(SNUM(conn))));
2068 if ((current_user.uid != 0)||!CAN_WRITE(conn)) {
2069 DEBUG(0,("set_user_quota: access_denied service [%s] user [%s]\n",
2070 lp_servicename(SNUM(conn)),conn->user));
2071 return ERROR_DOS(ERRSRV,ERRaccess);
2075 if (total_params < 4) {
2076 DEBUG(0,("call_trans2setfsinfo: requires total_params(%d) >= 4 bytes!\n",
2078 return ERROR_DOS(ERRDOS,ERRinvalidparam);
2081 fsp = file_fsp(params,0);
2083 if (!CHECK_NTQUOTA_HANDLE_OK(fsp,conn)) {
2084 DEBUG(3,("TRANSACT_GET_USER_QUOTA: no valid QUOTA HANDLE\n"));
2085 return ERROR_NT(NT_STATUS_INVALID_HANDLE);
2088 info_level = SVAL(params,2);
2090 switch(info_level) {
2091 case SMB_FS_QUOTA_INFORMATION:
2092 /* note: normaly there're 48 bytes,
2093 * but we didn't use the last 6 bytes for now
2096 if (total_data < 42) {
2097 DEBUG(0,("call_trans2setfsinfo: SET_FS_QUOTA: requires total_data(%d) >= 42 bytes!\n",
2099 return ERROR_DOS(ERRDOS,ERRunknownlevel);
2102 /* unknown_1 24 NULL bytes in pdata*/
2104 /* the soft quotas 8 bytes (SMB_BIG_UINT)*/
2105 quotas.softlim = (SMB_BIG_UINT)IVAL(pdata,24);
2106 #ifdef LARGE_SMB_OFF_T
2107 quotas.softlim |= (((SMB_BIG_UINT)IVAL(pdata,28)) << 32);
2108 #else /* LARGE_SMB_OFF_T */
2109 if ((IVAL(pdata,28) != 0)&&
2110 ((quotas.softlim != 0xFFFFFFFF)||
2111 (IVAL(pdata,28)!=0xFFFFFFFF))) {
2112 /* more than 32 bits? */
2113 return ERROR_DOS(ERRDOS,ERRunknownlevel);
2115 #endif /* LARGE_SMB_OFF_T */
2117 /* the hard quotas 8 bytes (SMB_BIG_UINT)*/
2118 quotas.hardlim = (SMB_BIG_UINT)IVAL(pdata,32);
2119 #ifdef LARGE_SMB_OFF_T
2120 quotas.hardlim |= (((SMB_BIG_UINT)IVAL(pdata,36)) << 32);
2121 #else /* LARGE_SMB_OFF_T */
2122 if ((IVAL(pdata,36) != 0)&&
2123 ((quotas.hardlim != 0xFFFFFFFF)||
2124 (IVAL(pdata,36)!=0xFFFFFFFF))) {
2125 /* more than 32 bits? */
2126 return ERROR_DOS(ERRDOS,ERRunknownlevel);
2128 #endif /* LARGE_SMB_OFF_T */
2130 /* quota_flags 2 bytes **/
2131 quotas.qflags = SVAL(pdata,40);
2133 /* unknown_2 6 NULL bytes follow*/
2135 /* now set the quotas */
2136 if (vfs_set_ntquota(fsp, SMB_USER_FS_QUOTA_TYPE, NULL, "as)!=0) {
2137 DEBUG(0,("vfs_set_ntquota() failed for service [%s]\n",lp_servicename(SNUM(conn))));
2138 return ERROR_DOS(ERRSRV,ERRerror);
2143 DEBUG(3,("call_trans2setfsinfo: unknown level (0x%X) not implemented yet.\n",
2145 return ERROR_DOS(ERRDOS,ERRunknownlevel);
2150 * sending this reply works fine,
2151 * but I'm not sure it's the same
2152 * like windows do...
2155 outsize = set_message(outbuf,10,0,True);
2159 #endif /* HAVE_SYS_QUOTAS */
2161 /****************************************************************************
2162 Utility function to set bad path error.
2163 ****************************************************************************/
2165 int set_bad_path_error(int err, BOOL bad_path, char *outbuf, int def_class, uint32 def_code)
2167 DEBUG(10,("set_bad_path_error: err = %d bad_path = %d\n",
2168 err, (int)bad_path ));
2172 return ERROR_NT(NT_STATUS_OBJECT_PATH_NOT_FOUND);
2174 return ERROR_NT(NT_STATUS_OBJECT_NAME_NOT_FOUND);
2177 return UNIXERROR(def_class,def_code);
2180 #if defined(HAVE_POSIX_ACLS)
2181 /****************************************************************************
2182 Utility function to count the number of entries in a POSIX acl.
2183 ****************************************************************************/
2185 static unsigned int count_acl_entries(connection_struct *conn, SMB_ACL_T posix_acl)
2187 unsigned int ace_count = 0;
2188 int entry_id = SMB_ACL_FIRST_ENTRY;
2189 SMB_ACL_ENTRY_T entry;
2191 while ( posix_acl && (SMB_VFS_SYS_ACL_GET_ENTRY(conn, posix_acl, entry_id, &entry) == 1)) {
2193 if (entry_id == SMB_ACL_FIRST_ENTRY) {
2194 entry_id = SMB_ACL_NEXT_ENTRY;
2201 /****************************************************************************
2202 Utility function to marshall a POSIX acl into wire format.
2203 ****************************************************************************/
2205 static BOOL marshall_posix_acl(connection_struct *conn, char *pdata, SMB_STRUCT_STAT *pst, SMB_ACL_T posix_acl)
2207 int entry_id = SMB_ACL_FIRST_ENTRY;
2208 SMB_ACL_ENTRY_T entry;
2210 while ( posix_acl && (SMB_VFS_SYS_ACL_GET_ENTRY(conn, posix_acl, entry_id, &entry) == 1)) {
2211 SMB_ACL_TAG_T tagtype;
2212 SMB_ACL_PERMSET_T permset;
2213 unsigned char perms = 0;
2214 unsigned int own_grp;
2217 if (entry_id == SMB_ACL_FIRST_ENTRY) {
2218 entry_id = SMB_ACL_NEXT_ENTRY;
2221 if (SMB_VFS_SYS_ACL_GET_TAG_TYPE(conn, entry, &tagtype) == -1) {
2222 DEBUG(0,("marshall_posix_acl: SMB_VFS_SYS_ACL_GET_TAG_TYPE failed.\n"));
2226 if (SMB_VFS_SYS_ACL_GET_PERMSET(conn, entry, &permset) == -1) {
2227 DEBUG(0,("marshall_posix_acl: SMB_VFS_SYS_ACL_GET_PERMSET failed.\n"));
2231 perms |= (SMB_VFS_SYS_ACL_GET_PERM(conn, permset, SMB_ACL_READ) ? SMB_POSIX_ACL_READ : 0);
2232 perms |= (SMB_VFS_SYS_ACL_GET_PERM(conn, permset, SMB_ACL_WRITE) ? SMB_POSIX_ACL_WRITE : 0);
2233 perms |= (SMB_VFS_SYS_ACL_GET_PERM(conn, permset, SMB_ACL_EXECUTE) ? SMB_POSIX_ACL_EXECUTE : 0);
2235 SCVAL(pdata,1,perms);
2238 case SMB_ACL_USER_OBJ:
2239 SCVAL(pdata,0,SMB_POSIX_ACL_USER_OBJ);
2240 own_grp = (unsigned int)pst->st_uid;
2241 SIVAL(pdata,2,own_grp);
2246 uid_t *puid = (uid_t *)SMB_VFS_SYS_ACL_GET_QUALIFIER(conn, entry);
2248 DEBUG(0,("marshall_posix_acl: SMB_VFS_SYS_ACL_GET_QUALIFIER failed.\n"));
2250 own_grp = (unsigned int)*puid;
2251 SMB_VFS_SYS_ACL_FREE_QUALIFIER(conn, (void *)puid,tagtype);
2252 SCVAL(pdata,0,SMB_POSIX_ACL_USER);
2253 SIVAL(pdata,2,own_grp);
2257 case SMB_ACL_GROUP_OBJ:
2258 SCVAL(pdata,0,SMB_POSIX_ACL_GROUP_OBJ);
2259 own_grp = (unsigned int)pst->st_gid;
2260 SIVAL(pdata,2,own_grp);
2265 gid_t *pgid= (gid_t *)SMB_VFS_SYS_ACL_GET_QUALIFIER(conn, entry);
2267 DEBUG(0,("marshall_posix_acl: SMB_VFS_SYS_ACL_GET_QUALIFIER failed.\n"));
2269 own_grp = (unsigned int)*pgid;
2270 SMB_VFS_SYS_ACL_FREE_QUALIFIER(conn, (void *)pgid,tagtype);
2271 SCVAL(pdata,0,SMB_POSIX_ACL_GROUP);
2272 SIVAL(pdata,2,own_grp);
2277 SCVAL(pdata,0,SMB_POSIX_ACL_MASK);
2278 SIVAL(pdata,2,0xFFFFFFFF);
2279 SIVAL(pdata,6,0xFFFFFFFF);
2282 SCVAL(pdata,0,SMB_POSIX_ACL_OTHER);
2283 SIVAL(pdata,2,0xFFFFFFFF);
2284 SIVAL(pdata,6,0xFFFFFFFF);
2287 DEBUG(0,("marshall_posix_acl: unknown tagtype.\n"));
2290 pdata += SMB_POSIX_ACL_ENTRY_SIZE;
2297 /****************************************************************************
2298 Reply to a TRANS2_QFILEPATHINFO or TRANSACT2_QFILEINFO (query file info by
2299 file name or file id).
2300 ****************************************************************************/
2302 static int call_trans2qfilepathinfo(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize,
2303 char **pparams, int total_params, char **ppdata, int total_data,
2304 unsigned int max_data_bytes)
2306 char *params = *pparams;
2307 char *pdata = *ppdata;
2308 uint16 tran_call = SVAL(inbuf, smb_setup0);
2311 SMB_OFF_T file_size=0;
2312 SMB_BIG_UINT allocation_size=0;
2313 unsigned int data_size;
2314 unsigned int param_size = 2;
2315 SMB_STRUCT_STAT sbuf;
2316 pstring fname, dos_fname;
2321 BOOL bad_path = False;
2322 BOOL delete_pending = False;
2325 files_struct *fsp = NULL;
2326 uint32 desired_access = 0x12019F; /* Default - GENERIC_EXECUTE mapping from Windows */
2329 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
2333 if (tran_call == TRANSACT2_QFILEINFO) {
2334 if (total_params < 4)
2335 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
2337 fsp = file_fsp(params,0);
2338 info_level = SVAL(params,2);
2340 DEBUG(3,("call_trans2qfilepathinfo: TRANSACT2_QFILEINFO: level = %d\n", info_level));
2342 if(fsp && (fsp->fake_file_handle)) {
2344 * This is actually for the QUOTA_FAKE_FILE --metze
2347 pstrcpy(fname, fsp->fsp_name);
2348 /* We know this name is ok, it's already passed the checks. */
2350 } else if(fsp && (fsp->is_directory || fsp->fd == -1)) {
2352 * This is actually a QFILEINFO on a directory
2353 * handle (returned from an NT SMB). NT5.0 seems
2354 * to do this call. JRA.
2356 /* We know this name is ok, it's already passed the checks. */
2357 pstrcpy(fname, fsp->fsp_name);
2359 if (INFO_LEVEL_IS_UNIX(info_level)) {
2360 /* Always do lstat for UNIX calls. */
2361 if (SMB_VFS_LSTAT(conn,fname,&sbuf)) {
2362 DEBUG(3,("call_trans2qfilepathinfo: SMB_VFS_LSTAT of %s failed (%s)\n",fname,strerror(errno)));
2363 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRbadpath);
2365 } else if (SMB_VFS_STAT(conn,fname,&sbuf)) {
2366 DEBUG(3,("call_trans2qfilepathinfo: SMB_VFS_STAT of %s failed (%s)\n",fname,strerror(errno)));
2367 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRbadpath);
2370 delete_pending = fsp->is_directory ? fsp->directory_delete_on_close : 0;
2373 * Original code - this is an open file.
2375 CHECK_FSP(fsp,conn);
2377 pstrcpy(fname, fsp->fsp_name);
2378 if (SMB_VFS_FSTAT(fsp,fsp->fd,&sbuf) != 0) {
2379 DEBUG(3,("fstat of fnum %d failed (%s)\n", fsp->fnum, strerror(errno)));
2380 return(UNIXERROR(ERRDOS,ERRbadfid));
2382 pos = fsp->position_information;
2383 delete_pending = fsp->delete_on_close;
2384 desired_access = fsp->desired_access;
2387 NTSTATUS status = NT_STATUS_OK;
2390 if (total_params < 6)
2391 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
2393 info_level = SVAL(params,0);
2395 DEBUG(3,("call_trans2qfilepathinfo: TRANSACT2_QPATHINFO: level = %d\n", info_level));
2397 srvstr_get_path(inbuf, fname, ¶ms[6], sizeof(fname), -1, STR_TERMINATE, &status, False);
2398 if (!NT_STATUS_IS_OK(status)) {
2399 return ERROR_NT(status);
2402 RESOLVE_DFSPATH(fname, conn, inbuf, outbuf);
2404 unix_convert(fname,conn,0,&bad_path,&sbuf);
2406 return ERROR_NT(NT_STATUS_OBJECT_PATH_NOT_FOUND);
2408 if (!check_name(fname,conn)) {
2409 DEBUG(3,("call_trans2qfilepathinfo: fileinfo of %s failed (%s)\n",fname,strerror(errno)));
2410 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRbadpath);
2413 if (INFO_LEVEL_IS_UNIX(info_level)) {
2414 /* Always do lstat for UNIX calls. */
2415 if (SMB_VFS_LSTAT(conn,fname,&sbuf)) {
2416 DEBUG(3,("call_trans2qfilepathinfo: SMB_VFS_LSTAT of %s failed (%s)\n",fname,strerror(errno)));
2417 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRbadpath);
2419 } else if (!VALID_STAT(sbuf) && SMB_VFS_STAT(conn,fname,&sbuf) && (info_level != SMB_INFO_IS_NAME_VALID)) {
2420 DEBUG(3,("call_trans2qfilepathinfo: SMB_VFS_STAT of %s failed (%s)\n",fname,strerror(errno)));
2421 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRbadpath);
2425 if (INFO_LEVEL_IS_UNIX(info_level) && !lp_unix_extensions())
2426 return ERROR_DOS(ERRDOS,ERRunknownlevel);
2428 DEBUG(3,("call_trans2qfilepathinfo %s (fnum = %d) level=%d call=%d total_data=%d\n",
2429 fname,fsp ? fsp->fnum : -1, info_level,tran_call,total_data));
2431 p = strrchr_m(fname,'/');
2437 mode = dos_mode(conn,fname,&sbuf);
2439 mode = FILE_ATTRIBUTE_NORMAL;
2441 fullpathname = fname;
2442 file_size = get_file_size(sbuf);
2443 allocation_size = get_allocation_size(conn,fsp,&sbuf);
2445 /* This is necessary, as otherwise the desktop.ini file in
2446 * this folder is ignored */
2447 mode |= (lp_profile_acls(SNUM(conn)) ? aRONLY : 0);
2451 params = SMB_REALLOC(*pparams,2);
2453 return ERROR_DOS(ERRDOS,ERRnomem);
2455 memset((char *)params,'\0',2);
2456 data_size = max_data_bytes + DIR_ENTRY_SAFETY_MARGIN;
2457 pdata = SMB_REALLOC(*ppdata, data_size);
2458 if ( pdata == NULL )
2459 return ERROR_DOS(ERRDOS,ERRnomem);
2462 if (total_data > 0 && IVAL(pdata,0) == total_data) {
2463 /* uggh, EAs for OS2 */
2464 DEBUG(4,("Rejecting EA request with total_data=%d\n",total_data));
2465 return ERROR_DOS(ERRDOS,ERReasnotsupported);
2468 memset((char *)pdata,'\0',data_size);
2470 c_time = get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(conn)));
2472 if (fsp && fsp->pending_modtime) {
2473 /* the pending modtime overrides the current modtime */
2474 sbuf.st_mtime = fsp->pending_modtime;
2477 if (lp_dos_filetime_resolution(SNUM(conn))) {
2479 sbuf.st_atime &= ~1;
2480 sbuf.st_ctime &= ~1;
2481 sbuf.st_mtime &= ~1;
2484 /* NT expects the name to be in an exact form of the *full*
2485 filename. See the trans2 torture test */
2486 if (strequal(base_name,".")) {
2487 pstrcpy(dos_fname, "\\");
2489 pstr_sprintf(dos_fname, "\\%s", fname);
2490 string_replace(dos_fname, '/', '\\');
2493 switch (info_level) {
2494 case SMB_INFO_STANDARD:
2495 DEBUG(10,("call_trans2qfilepathinfo: SMB_INFO_STANDARD\n"));
2497 put_dos_date2(pdata,l1_fdateCreation,c_time);
2498 put_dos_date2(pdata,l1_fdateLastAccess,sbuf.st_atime);
2499 put_dos_date2(pdata,l1_fdateLastWrite,sbuf.st_mtime); /* write time */
2500 SIVAL(pdata,l1_cbFile,(uint32)file_size);
2501 SIVAL(pdata,l1_cbFileAlloc,(uint32)allocation_size);
2502 SSVAL(pdata,l1_attrFile,mode);
2505 case SMB_INFO_QUERY_EA_SIZE:
2507 unsigned int ea_size = estimate_ea_size(conn, fsp, fname);
2508 DEBUG(10,("call_trans2qfilepathinfo: SMB_INFO_QUERY_EA_SIZE\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);
2516 SIVAL(pdata,l1_attrFile+2,ea_size);
2520 case SMB_INFO_IS_NAME_VALID:
2521 DEBUG(10,("call_trans2qfilepathinfo: SMB_INFO_IS_NAME_VALID\n"));
2522 if (tran_call == TRANSACT2_QFILEINFO) {
2523 /* os/2 needs this ? really ?*/
2524 return ERROR_DOS(ERRDOS,ERRbadfunc);
2530 case SMB_INFO_QUERY_EAS_FROM_LIST:
2531 DEBUG(10,("call_trans2qfilepathinfo: SMB_INFO_QUERY_EAS_FROM_LIST\n"));
2533 put_dos_date2(pdata,0,c_time);
2534 put_dos_date2(pdata,4,sbuf.st_atime);
2535 put_dos_date2(pdata,8,sbuf.st_mtime);
2536 SIVAL(pdata,12,(uint32)file_size);
2537 SIVAL(pdata,16,(uint32)allocation_size);
2538 SIVAL(pdata,20,mode);
2541 case SMB_INFO_QUERY_ALL_EAS:
2542 DEBUG(10,("call_trans2qfilepathinfo: SMB_INFO_QUERY_ALL_EAS\n"));
2543 /* We have data_size bytes to put EA's into. */
2544 data_size = fill_ea_buffer(pdata, data_size, conn, fsp, fname);
2547 case SMB_FILE_BASIC_INFORMATION:
2548 case SMB_QUERY_FILE_BASIC_INFO:
2550 if (info_level == SMB_QUERY_FILE_BASIC_INFO) {
2551 DEBUG(10,("call_trans2qfilepathinfo: SMB_QUERY_FILE_BASIC_INFO\n"));
2552 data_size = 36; /* w95 returns 40 bytes not 36 - why ?. */
2554 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_BASIC_INFORMATION\n"));
2558 put_long_date(pdata,c_time);
2559 put_long_date(pdata+8,sbuf.st_atime);
2560 put_long_date(pdata+16,sbuf.st_mtime); /* write time */
2561 put_long_date(pdata+24,sbuf.st_mtime); /* change time */
2562 SIVAL(pdata,32,mode);
2564 DEBUG(5,("SMB_QFBI - "));
2566 time_t create_time = c_time;
2567 DEBUG(5,("create: %s ", ctime(&create_time)));
2569 DEBUG(5,("access: %s ", ctime(&sbuf.st_atime)));
2570 DEBUG(5,("write: %s ", ctime(&sbuf.st_mtime)));
2571 DEBUG(5,("change: %s ", ctime(&sbuf.st_mtime)));
2572 DEBUG(5,("mode: %x\n", mode));
2576 case SMB_FILE_STANDARD_INFORMATION:
2577 case SMB_QUERY_FILE_STANDARD_INFO:
2579 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_STANDARD_INFORMATION\n"));
2581 SOFF_T(pdata,0,allocation_size);
2582 SOFF_T(pdata,8,file_size);
2583 if (delete_pending & sbuf.st_nlink)
2584 SIVAL(pdata,16,sbuf.st_nlink - 1);
2586 SIVAL(pdata,16,sbuf.st_nlink);
2588 SCVAL(pdata,21,(mode&aDIR)?1:0);
2591 case SMB_FILE_EA_INFORMATION:
2592 case SMB_QUERY_FILE_EA_INFO:
2594 unsigned int ea_size = estimate_ea_size(conn, fsp, fname);
2595 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_EA_INFORMATION\n"));
2597 SIVAL(pdata,0,ea_size);
2601 /* Get the 8.3 name - used if NT SMB was negotiated. */
2602 case SMB_QUERY_FILE_ALT_NAME_INFO:
2603 case SMB_FILE_ALTERNATE_NAME_INFORMATION:
2607 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_ALTERNATE_NAME_INFORMATION\n"));
2608 pstrcpy(short_name,base_name);
2609 /* Mangle if not already 8.3 */
2610 if(!mangle_is_8_3(short_name, True)) {
2611 mangle_map(short_name,True,True,SNUM(conn));
2613 len = srvstr_push(outbuf, pdata+4, short_name, -1, STR_UNICODE);
2614 data_size = 4 + len;
2619 case SMB_QUERY_FILE_NAME_INFO:
2621 this must be *exactly* right for ACLs on mapped drives to work
2623 len = srvstr_push(outbuf, pdata+4, dos_fname, -1, STR_UNICODE);
2624 DEBUG(10,("call_trans2qfilepathinfo: SMB_QUERY_FILE_NAME_INFO\n"));
2625 data_size = 4 + len;
2629 case SMB_FILE_ALLOCATION_INFORMATION:
2630 case SMB_QUERY_FILE_ALLOCATION_INFO:
2631 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_ALLOCATION_INFORMATION\n"));
2633 SOFF_T(pdata,0,allocation_size);
2636 case SMB_FILE_END_OF_FILE_INFORMATION:
2637 case SMB_QUERY_FILE_END_OF_FILEINFO:
2638 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_END_OF_FILE_INFORMATION\n"));
2640 SOFF_T(pdata,0,file_size);
2643 case SMB_QUERY_FILE_ALL_INFO:
2644 case SMB_FILE_ALL_INFORMATION:
2646 unsigned int ea_size = estimate_ea_size(conn, fsp, fname);
2647 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_ALL_INFORMATION\n"));
2648 put_long_date(pdata,c_time);
2649 put_long_date(pdata+8,sbuf.st_atime);
2650 put_long_date(pdata+16,sbuf.st_mtime); /* write time */
2651 put_long_date(pdata+24,sbuf.st_mtime); /* change time */
2652 SIVAL(pdata,32,mode);
2654 SOFF_T(pdata,0,allocation_size);
2655 SOFF_T(pdata,8,file_size);
2656 if (delete_pending && sbuf.st_nlink)
2657 SIVAL(pdata,16,sbuf.st_nlink - 1);
2659 SIVAL(pdata,16,sbuf.st_nlink);
2660 SCVAL(pdata,20,delete_pending);
2661 SCVAL(pdata,21,(mode&aDIR)?1:0);
2663 SIVAL(pdata,0,ea_size);
2664 pdata += 4; /* EA info */
2665 len = srvstr_push(outbuf, pdata+4, dos_fname, -1, STR_UNICODE);
2668 data_size = PTR_DIFF(pdata,(*ppdata));
2671 case SMB_FILE_INTERNAL_INFORMATION:
2672 /* This should be an index number - looks like
2675 I think this causes us to fail the IFSKIT
2676 BasicFileInformationTest. -tpot */
2678 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_INTERNAL_INFORMATION\n"));
2679 SIVAL(pdata,0,sbuf.st_dev);
2680 SIVAL(pdata,4,sbuf.st_ino);
2684 case SMB_FILE_ACCESS_INFORMATION:
2685 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_ACCESS_INFORMATION\n"));
2686 SIVAL(pdata,0,desired_access);
2690 case SMB_FILE_NAME_INFORMATION:
2691 /* Pathname with leading '\'. */
2694 byte_len = dos_PutUniCode(pdata+4,dos_fname,max_data_bytes,False);
2695 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_NAME_INFORMATION\n"));
2696 SIVAL(pdata,0,byte_len);
2697 data_size = 4 + byte_len;
2701 case SMB_FILE_DISPOSITION_INFORMATION:
2702 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_DISPOSITION_INFORMATION\n"));
2704 SCVAL(pdata,0,delete_pending);
2707 case SMB_FILE_POSITION_INFORMATION:
2708 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_POSITION_INFORMATION\n"));
2710 SOFF_T(pdata,0,pos);
2713 case SMB_FILE_MODE_INFORMATION:
2714 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_MODE_INFORMATION\n"));
2715 SIVAL(pdata,0,mode);
2719 case SMB_FILE_ALIGNMENT_INFORMATION:
2720 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_ALIGNMENT_INFORMATION\n"));
2721 SIVAL(pdata,0,0); /* No alignment needed. */
2727 * NT4 server just returns "invalid query" to this - if we try to answer
2728 * it then NTws gets a BSOD! (tridge).
2729 * W2K seems to want this. JRA.
2731 case SMB_QUERY_FILE_STREAM_INFO:
2733 case SMB_FILE_STREAM_INFORMATION:
2734 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_STREAM_INFORMATION\n"));
2738 size_t byte_len = dos_PutUniCode(pdata+24,"::$DATA", 0xE, False);
2739 SIVAL(pdata,0,0); /* ??? */
2740 SIVAL(pdata,4,byte_len); /* Byte length of unicode string ::$DATA */
2741 SOFF_T(pdata,8,file_size);
2742 SIVAL(pdata,16,allocation_size);
2743 SIVAL(pdata,20,0); /* ??? */
2744 data_size = 24 + byte_len;
2748 case SMB_QUERY_COMPRESSION_INFO:
2749 case SMB_FILE_COMPRESSION_INFORMATION:
2750 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_COMPRESSION_INFORMATION\n"));
2751 SOFF_T(pdata,0,file_size);
2752 SIVAL(pdata,8,0); /* ??? */
2753 SIVAL(pdata,12,0); /* ??? */
2757 case SMB_FILE_NETWORK_OPEN_INFORMATION:
2758 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_NETWORK_OPEN_INFORMATION\n"));
2759 put_long_date(pdata,c_time);
2760 put_long_date(pdata+8,sbuf.st_atime);
2761 put_long_date(pdata+16,sbuf.st_mtime); /* write time */
2762 put_long_date(pdata+24,sbuf.st_mtime); /* change time */
2763 SIVAL(pdata,32,allocation_size);
2764 SOFF_T(pdata,40,file_size);
2765 SIVAL(pdata,48,mode);
2766 SIVAL(pdata,52,0); /* ??? */
2770 case SMB_FILE_ATTRIBUTE_TAG_INFORMATION:
2771 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_ATTRIBUTE_TAG_INFORMATION\n"));
2772 SIVAL(pdata,0,mode);
2778 * CIFS UNIX Extensions.
2781 case SMB_QUERY_FILE_UNIX_BASIC:
2783 DEBUG(10,("call_trans2qfilepathinfo: SMB_QUERY_FILE_UNIX_BASIC\n"));
2784 DEBUG(4,("call_trans2qfilepathinfo: st_mode=%o\n",(int)sbuf.st_mode));
2786 SOFF_T(pdata,0,get_file_size(sbuf)); /* File size 64 Bit */
2789 SOFF_T(pdata,0,get_allocation_size(conn,fsp,&sbuf)); /* Number of bytes used on disk - 64 Bit */
2792 put_long_date(pdata,sbuf.st_ctime); /* Creation Time 64 Bit */
2793 put_long_date(pdata+8,sbuf.st_atime); /* Last access time 64 Bit */
2794 put_long_date(pdata+16,sbuf.st_mtime); /* Last modification time 64 Bit */
2797 SIVAL(pdata,0,sbuf.st_uid); /* user id for the owner */
2801 SIVAL(pdata,0,sbuf.st_gid); /* group id of owner */
2805 SIVAL(pdata,0,unix_filetype(sbuf.st_mode));
2808 SIVAL(pdata,0,unix_dev_major(sbuf.st_rdev)); /* Major device number if type is device */
2812 SIVAL(pdata,0,unix_dev_minor(sbuf.st_rdev)); /* Minor device number if type is device */
2816 SINO_T(pdata,0,(SMB_INO_T)sbuf.st_ino); /* inode number */
2819 SIVAL(pdata,0, unix_perms_to_wire(sbuf.st_mode)); /* Standard UNIX file permissions */
2823 SIVAL(pdata,0,sbuf.st_nlink); /* number of hard links */
2826 data_size = PTR_DIFF(pdata,(*ppdata));
2830 DEBUG(4,("call_trans2qfilepathinfo: SMB_QUERY_FILE_UNIX_BASIC"));
2832 for (i=0; i<100; i++)
2833 DEBUG(4,("%d=%x, ",i, (*ppdata)[i]));
2839 case SMB_QUERY_FILE_UNIX_LINK:
2843 DEBUG(10,("call_trans2qfilepathinfo: SMB_QUERY_FILE_UNIX_LINK\n"));
2845 if(!S_ISLNK(sbuf.st_mode))
2846 return(UNIXERROR(ERRSRV,ERRbadlink));
2848 return(UNIXERROR(ERRDOS,ERRbadlink));
2850 len = SMB_VFS_READLINK(conn,fullpathname, buffer, sizeof(pstring)-1); /* read link */
2852 return(UNIXERROR(ERRDOS,ERRnoaccess));
2854 len = srvstr_push(outbuf, pdata, buffer, -1, STR_TERMINATE);
2856 data_size = PTR_DIFF(pdata,(*ppdata));
2861 #if defined(HAVE_POSIX_ACLS)
2862 case SMB_QUERY_POSIX_ACL:
2864 SMB_ACL_T file_acl = NULL;
2865 SMB_ACL_T def_acl = NULL;
2866 uint16 num_file_acls = 0;
2867 uint16 num_def_acls = 0;
2869 if (fsp && !fsp->is_directory && (fsp->fd != -1)) {
2870 file_acl = SMB_VFS_SYS_ACL_GET_FD(fsp, fsp->fd);
2872 file_acl = SMB_VFS_SYS_ACL_GET_FILE(conn, fname, SMB_ACL_TYPE_ACCESS);
2875 if (file_acl == NULL && no_acl_syscall_error(errno)) {
2876 DEBUG(5,("call_trans2qfilepathinfo: ACLs not implemented on filesystem containing %s\n",
2878 return ERROR_NT(NT_STATUS_NOT_IMPLEMENTED);
2881 if (S_ISDIR(sbuf.st_mode)) {
2882 if (fsp && fsp->is_directory) {
2883 def_acl = SMB_VFS_SYS_ACL_GET_FILE(conn, fsp->fsp_name, SMB_ACL_TYPE_DEFAULT);
2885 def_acl = SMB_VFS_SYS_ACL_GET_FILE(conn, fname, SMB_ACL_TYPE_DEFAULT);
2887 def_acl = free_empty_sys_acl(conn, def_acl);
2890 num_file_acls = count_acl_entries(conn, file_acl);
2891 num_def_acls = count_acl_entries(conn, def_acl);
2893 if ( data_size < (num_file_acls + num_def_acls)*SMB_POSIX_ACL_ENTRY_SIZE + SMB_POSIX_ACL_HEADER_SIZE) {
2894 DEBUG(5,("call_trans2qfilepathinfo: data_size too small (%u) need %u\n",
2896 (unsigned int)((num_file_acls + num_def_acls)*SMB_POSIX_ACL_ENTRY_SIZE +
2897 SMB_POSIX_ACL_HEADER_SIZE) ));
2899 SMB_VFS_SYS_ACL_FREE_ACL(conn, file_acl);
2902 SMB_VFS_SYS_ACL_FREE_ACL(conn, def_acl);
2904 return ERROR_NT(NT_STATUS_BUFFER_TOO_SMALL);
2907 SSVAL(pdata,0,SMB_POSIX_ACL_VERSION);
2908 SSVAL(pdata,2,num_file_acls);
2909 SSVAL(pdata,4,num_def_acls);
2910 if (!marshall_posix_acl(conn, pdata + SMB_POSIX_ACL_HEADER_SIZE, &sbuf, file_acl)) {
2912 SMB_VFS_SYS_ACL_FREE_ACL(conn, file_acl);
2915 SMB_VFS_SYS_ACL_FREE_ACL(conn, def_acl);
2917 return ERROR_NT(NT_STATUS_INTERNAL_ERROR);
2919 if (!marshall_posix_acl(conn, pdata + SMB_POSIX_ACL_HEADER_SIZE + (num_file_acls*SMB_POSIX_ACL_ENTRY_SIZE), &sbuf, def_acl)) {
2921 SMB_VFS_SYS_ACL_FREE_ACL(conn, file_acl);
2924 SMB_VFS_SYS_ACL_FREE_ACL(conn, def_acl);
2926 return ERROR_NT(NT_STATUS_INTERNAL_ERROR);
2930 SMB_VFS_SYS_ACL_FREE_ACL(conn, file_acl);
2933 SMB_VFS_SYS_ACL_FREE_ACL(conn, def_acl);
2935 data_size = (num_file_acls + num_def_acls)*SMB_POSIX_ACL_ENTRY_SIZE + SMB_POSIX_ACL_HEADER_SIZE;
2941 return ERROR_DOS(ERRDOS,ERRunknownlevel);
2944 send_trans2_replies(outbuf, bufsize, params, param_size, *ppdata, data_size);
2949 /****************************************************************************
2950 Deal with the internal needs of setting the delete on close flag. Note that
2951 as the tdb locking is recursive, it is safe to call this from within
2952 open_file_shared. JRA.
2953 ****************************************************************************/
2955 NTSTATUS set_delete_on_close_internal(files_struct *fsp, BOOL delete_on_close, uint32 dosmode)
2957 if (delete_on_close) {
2959 * Only allow delete on close for writable files.
2962 if (!lp_delete_readonly(SNUM(fsp->conn))) {
2963 if (dosmode & aRONLY) {
2964 DEBUG(10,("set_delete_on_close_internal: file %s delete on close flag set but file attribute is readonly.\n",
2966 return NT_STATUS_CANNOT_DELETE;
2971 * Only allow delete on close for writable shares.
2974 if (!CAN_WRITE(fsp->conn)) {
2975 DEBUG(10,("set_delete_on_close_internal: file %s delete on close flag set but write access denied on share.\n",
2977 return NT_STATUS_ACCESS_DENIED;
2981 * Only allow delete on close for files/directories opened with delete intent.
2984 if (!(fsp->desired_access & DELETE_ACCESS)) {
2985 DEBUG(10,("set_delete_on_close_internal: file %s delete on close flag set but delete access denied.\n",
2987 return NT_STATUS_ACCESS_DENIED;
2991 if(fsp->is_directory) {
2992 fsp->directory_delete_on_close = delete_on_close;
2993 DEBUG(10, ("set_delete_on_close_internal: %s delete on close flag for fnum = %d, directory %s\n",
2994 delete_on_close ? "Added" : "Removed", fsp->fnum, fsp->fsp_name ));
2996 fsp->delete_on_close = delete_on_close;
2997 DEBUG(10, ("set_delete_on_close_internal: %s delete on close flag for fnum = %d, file %s\n",
2998 delete_on_close ? "Added" : "Removed", fsp->fnum, fsp->fsp_name ));
3001 return NT_STATUS_OK;
3004 /****************************************************************************
3005 Sets the delete on close flag over all share modes on this file.
3006 Modify the share mode entry for all files open
3007 on this device and inode to tell other smbds we have
3008 changed the delete on close flag. This will be noticed
3009 in the close code, the last closer will delete the file
3011 ****************************************************************************/
3013 NTSTATUS set_delete_on_close_over_all(files_struct *fsp, BOOL delete_on_close)
3015 DEBUG(10,("set_delete_on_close_over_all: %s delete on close flag for fnum = %d, file %s\n",
3016 delete_on_close ? "Adding" : "Removing", fsp->fnum, fsp->fsp_name ));
3018 if (fsp->is_directory || fsp->is_stat)
3019 return NT_STATUS_OK;
3021 if (lock_share_entry_fsp(fsp) == False)
3022 return NT_STATUS_ACCESS_DENIED;
3024 if (!modify_delete_flag(fsp->dev, fsp->inode, delete_on_close)) {
3025 DEBUG(0,("set_delete_on_close_over_all: failed to change delete on close flag for file %s\n",
3027 unlock_share_entry_fsp(fsp);
3028 return NT_STATUS_ACCESS_DENIED;
3031 unlock_share_entry_fsp(fsp);
3032 return NT_STATUS_OK;
3035 /****************************************************************************
3036 Set a hard link (called by UNIX extensions and by NT rename with HARD link
3038 ****************************************************************************/
3040 NTSTATUS hardlink_internals(connection_struct *conn, char *oldname, char *newname)
3042 BOOL bad_path_oldname = False;
3043 BOOL bad_path_newname = False;
3044 SMB_STRUCT_STAT sbuf1, sbuf2;
3045 pstring last_component_oldname;
3046 pstring last_component_newname;
3047 NTSTATUS status = NT_STATUS_OK;
3053 if (ms_has_wild(newname) || ms_has_wild(oldname)) {
3054 return NT_STATUS_OBJECT_PATH_SYNTAX_BAD;
3057 unix_convert(oldname,conn,last_component_oldname,&bad_path_oldname,&sbuf1);
3058 if (bad_path_oldname) {
3059 return NT_STATUS_OBJECT_PATH_NOT_FOUND;
3062 /* Quick check for "." and ".." */
3063 if (last_component_oldname[0] == '.') {
3064 if (!last_component_oldname[1] || (last_component_oldname[1] == '.' && !last_component_oldname[2])) {
3065 return NT_STATUS_OBJECT_NAME_INVALID;
3069 /* source must already exist. */
3070 if (!VALID_STAT(sbuf1)) {
3071 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3074 if (!check_name(oldname,conn)) {
3075 return NT_STATUS_ACCESS_DENIED;
3078 unix_convert(newname,conn,last_component_newname,&bad_path_newname,&sbuf2);
3079 if (bad_path_newname) {
3080 return NT_STATUS_OBJECT_PATH_NOT_FOUND;
3083 /* Quick check for "." and ".." */
3084 if (last_component_newname[0] == '.') {
3085 if (!last_component_newname[1] || (last_component_newname[1] == '.' && !last_component_newname[2])) {
3086 return NT_STATUS_OBJECT_NAME_INVALID;
3090 /* Disallow if newname already exists. */
3091 if (VALID_STAT(sbuf2)) {
3092 return NT_STATUS_OBJECT_NAME_COLLISION;
3095 if (!check_name(newname,conn)) {
3096 return NT_STATUS_ACCESS_DENIED;
3099 /* No links from a directory. */
3100 if (S_ISDIR(sbuf1.st_mode)) {
3101 return NT_STATUS_FILE_IS_A_DIRECTORY;
3104 /* Ensure this is within the share. */
3105 if (!reduce_name(conn, oldname) != 0)
3106 return NT_STATUS_ACCESS_DENIED;
3108 DEBUG(10,("hardlink_internals: doing hard link %s -> %s\n", newname, oldname ));
3110 if (SMB_VFS_LINK(conn,oldname,newname) != 0) {
3111 status = map_nt_error_from_unix(errno);
3112 DEBUG(3,("hardlink_internals: Error %s hard link %s -> %s\n",
3113 nt_errstr(status), newname, oldname));
3119 /****************************************************************************
3120 Reply to a TRANS2_SETFILEINFO (set file info by fileid).
3121 ****************************************************************************/
3123 static int call_trans2setfilepathinfo(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize,
3124 char **pparams, int total_params, char **ppdata, int total_data,
3125 unsigned int max_data_bytes)
3127 char *params = *pparams;
3128 char *pdata = *ppdata;
3129 uint16 tran_call = SVAL(inbuf, smb_setup0);
3134 SMB_STRUCT_STAT sbuf;
3137 BOOL bad_path = False;
3138 files_struct *fsp = NULL;
3139 uid_t set_owner = (uid_t)SMB_UID_NO_CHANGE;
3140 gid_t set_grp = (uid_t)SMB_GID_NO_CHANGE;
3141 mode_t unixmode = 0;
3142 NTSTATUS status = NT_STATUS_OK;
3145 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
3149 if (tran_call == TRANSACT2_SETFILEINFO) {
3150 if (total_params < 4)
3151 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
3153 fsp = file_fsp(params,0);
3154 info_level = SVAL(params,2);
3156 if(fsp && (fsp->is_directory || fsp->fd == -1)) {
3158 * This is actually a SETFILEINFO on a directory
3159 * handle (returned from an NT SMB). NT5.0 seems
3160 * to do this call. JRA.
3162 pstrcpy(fname, fsp->fsp_name);
3163 if (SMB_VFS_STAT(conn,fname,&sbuf) != 0) {
3164 DEBUG(3,("call_trans2setfilepathinfo: fileinfo of %s failed (%s)\n",fname,strerror(errno)));
3165 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRbadpath);
3167 } else if (fsp && fsp->print_file) {
3169 * Doing a DELETE_ON_CLOSE should cancel a print job.
3171 if ((info_level == SMB_SET_FILE_DISPOSITION_INFO) && CVAL(pdata,0)) {
3172 fsp->share_mode = FILE_DELETE_ON_CLOSE;
3174 DEBUG(3,("call_trans2setfilepathinfo: Cancelling print job (%s)\n", fsp->fsp_name ));
3177 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
3180 return (UNIXERROR(ERRDOS,ERRbadpath));
3183 * Original code - this is an open file.
3185 CHECK_FSP(fsp,conn);
3187 pstrcpy(fname, fsp->fsp_name);
3190 if (SMB_VFS_FSTAT(fsp,fd,&sbuf) != 0) {
3191 DEBUG(3,("call_trans2setfilepathinfo: fstat of fnum %d failed (%s)\n",fsp->fnum, strerror(errno)));
3192 return(UNIXERROR(ERRDOS,ERRbadfid));
3197 if (total_params < 6)
3198 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
3200 info_level = SVAL(params,0);
3201 srvstr_get_path(inbuf, fname, ¶ms[6], sizeof(fname), -1, STR_TERMINATE, &status, False);
3202 if (!NT_STATUS_IS_OK(status)) {
3203 return ERROR_NT(status);
3205 unix_convert(fname,conn,0,&bad_path,&sbuf);
3207 return ERROR_NT(NT_STATUS_OBJECT_PATH_NOT_FOUND);
3211 * For CIFS UNIX extensions the target name may not exist.
3214 if(!VALID_STAT(sbuf) && !INFO_LEVEL_IS_UNIX(info_level)) {
3215 DEBUG(3,("call_trans2setfilepathinfo: stat of %s failed (%s)\n", fname, strerror(errno)));
3216 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRbadpath);
3219 if(!check_name(fname, conn)) {
3220 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRbadpath);
3225 if (!CAN_WRITE(conn))
3226 return ERROR_DOS(ERRSRV,ERRaccess);
3228 if (INFO_LEVEL_IS_UNIX(info_level) && !lp_unix_extensions())
3229 return ERROR_DOS(ERRDOS,ERRunknownlevel);
3231 if (VALID_STAT(sbuf))
3232 unixmode = sbuf.st_mode;
3234 DEBUG(3,("call_trans2setfilepathinfo(%d) %s (fnum %d) info_level=%d totdata=%d\n",
3235 tran_call,fname, fsp ? fsp->fnum : -1, info_level,total_data));
3237 /* Realloc the parameter and data sizes */
3238 params = SMB_REALLOC(*pparams,2);
3240 return ERROR_DOS(ERRDOS,ERRnomem);
3245 if (fsp && fsp->pending_modtime) {
3246 /* the pending modtime overrides the current modtime */
3247 sbuf.st_mtime = fsp->pending_modtime;
3250 size = get_file_size(sbuf);
3251 tvs.modtime = sbuf.st_mtime;
3252 tvs.actime = sbuf.st_atime;
3253 dosmode = dos_mode(conn,fname,&sbuf);
3254 unixmode = sbuf.st_mode;
3256 set_owner = VALID_STAT(sbuf) ? sbuf.st_uid : (uid_t)SMB_UID_NO_CHANGE;
3257 set_grp = VALID_STAT(sbuf) ? sbuf.st_gid : (gid_t)SMB_GID_NO_CHANGE;
3259 switch (info_level) {
3260 case SMB_INFO_STANDARD:
3262 if (total_data < 12)
3263 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
3266 tvs.actime = make_unix_date2(pdata+l1_fdateLastAccess);
3268 tvs.modtime = make_unix_date2(pdata+l1_fdateLastWrite);
3272 case SMB_INFO_SET_EA:
3273 status = set_ea(conn, fsp, fname, pdata, total_data);
3274 if (NT_STATUS_V(status) != NT_STATUS_V(NT_STATUS_OK))
3275 return ERROR_NT(status);
3278 /* XXXX um, i don't think this is right.
3279 it's also not in the cifs6.txt spec.
3281 case SMB_INFO_QUERY_EAS_FROM_LIST:
3282 if (total_data < 28)
3283 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
3285 tvs.actime = make_unix_date2(pdata+8);
3286 tvs.modtime = make_unix_date2(pdata+12);
3287 size = IVAL(pdata,16);
3288 dosmode = IVAL(pdata,24);
3291 /* XXXX nor this. not in cifs6.txt, either. */
3292 case SMB_INFO_QUERY_ALL_EAS:
3293 if (total_data < 28)
3294 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
3296 tvs.actime = make_unix_date2(pdata+8);
3297 tvs.modtime = make_unix_date2(pdata+12);
3298 size = IVAL(pdata,16);
3299 dosmode = IVAL(pdata,24);
3302 case SMB_SET_FILE_BASIC_INFO:
3303 case SMB_FILE_BASIC_INFORMATION:
3305 /* Patch to do this correctly from Paul Eggert <eggert@twinsun.com>. */
3307 time_t changed_time;
3309 if (total_data < 36)
3310 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
3312 /* Ignore create time at offset pdata. */
3315 tvs.actime = interpret_long_date(pdata+8);
3317 write_time = interpret_long_date(pdata+16);
3318 changed_time = interpret_long_date(pdata+24);
3320 tvs.modtime = MIN(write_time, changed_time);
3322 if (write_time > tvs.modtime && write_time != (time_t)-1) {
3323 tvs.modtime = write_time;
3325 /* Prefer a defined time to an undefined one. */
3326 if (tvs.modtime == (time_t)0 || tvs.modtime == (time_t)-1)
3327 tvs.modtime = (write_time == (time_t)0 || write_time == (time_t)-1
3328 ? changed_time : write_time);
3331 dosmode = IVAL(pdata,32);
3335 case SMB_FILE_ALLOCATION_INFORMATION:
3336 case SMB_SET_FILE_ALLOCATION_INFO:
3339 SMB_BIG_UINT allocation_size;
3342 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
3344 allocation_size = (SMB_BIG_UINT)IVAL(pdata,0);
3345 #ifdef LARGE_SMB_OFF_T
3346 allocation_size |= (((SMB_BIG_UINT)IVAL(pdata,4)) << 32);
3347 #else /* LARGE_SMB_OFF_T */
3348 if (IVAL(pdata,4) != 0) /* more than 32 bits? */
3349 return ERROR_DOS(ERRDOS,ERRunknownlevel);
3350 #endif /* LARGE_SMB_OFF_T */
3351 DEBUG(10,("call_trans2setfilepathinfo: Set file allocation info for file %s to %.0f\n",
3352 fname, (double)allocation_size ));
3354 if (allocation_size) {
3355 allocation_size = smb_roundup(conn, allocation_size);
3358 if(allocation_size != get_file_size(sbuf)) {
3359 SMB_STRUCT_STAT new_sbuf;
3361 DEBUG(10,("call_trans2setfilepathinfo: file %s : setting new allocation size to %.0f\n",
3362 fname, (double)allocation_size ));
3365 files_struct *new_fsp = NULL;
3366 int access_mode = 0;
3369 if(global_oplock_break) {
3370 /* Queue this file modify as we are the process of an oplock break. */
3372 DEBUG(2,("call_trans2setfilepathinfo: queueing message due to being "));
3373 DEBUGADD(2,( "in oplock break state.\n"));
3375 push_oplock_pending_smb_message(inbuf, length);
3379 new_fsp = open_file_shared1(conn, fname, &sbuf,FILE_WRITE_DATA,
3380 SET_OPEN_MODE(DOS_OPEN_RDWR),
3381 (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN),
3382 FILE_ATTRIBUTE_NORMAL,
3383 INTERNAL_OPEN_ONLY, &access_mode, &action);
3385 if (new_fsp == NULL)
3386 return(UNIXERROR(ERRDOS,ERRbadpath));
3387 ret = vfs_allocate_file_space(new_fsp, allocation_size);
3388 if (SMB_VFS_FSTAT(new_fsp,new_fsp->fd,&new_sbuf) != 0) {
3389 DEBUG(3,("call_trans2setfilepathinfo: fstat of fnum %d failed (%s)\n",
3390 new_fsp->fnum, strerror(errno)));
3393 close_file(new_fsp,True);
3395 ret = vfs_allocate_file_space(fsp, allocation_size);
3396 if (SMB_VFS_FSTAT(fsp,fd,&new_sbuf) != 0) {
3397 DEBUG(3,("call_trans2setfilepathinfo: fstat of fnum %d failed (%s)\n",
3398 fsp->fnum, strerror(errno)));
3403 return ERROR_NT(NT_STATUS_DISK_FULL);
3405 /* Allocate can truncate size... */
3406 size = get_file_size(new_sbuf);
3412 case SMB_FILE_END_OF_FILE_INFORMATION:
3413 case SMB_SET_FILE_END_OF_FILE_INFO:
3416 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
3418 size = IVAL(pdata,0);
3419 #ifdef LARGE_SMB_OFF_T
3420 size |= (((SMB_OFF_T)IVAL(pdata,4)) << 32);
3421 #else /* LARGE_SMB_OFF_T */
3422 if (IVAL(pdata,4) != 0) /* more than 32 bits? */
3423 return ERROR_DOS(ERRDOS,ERRunknownlevel);
3424 #endif /* LARGE_SMB_OFF_T */
3425 DEBUG(10,("call_trans2setfilepathinfo: Set end of file info for file %s to %.0f\n", fname, (double)size ));
3429 case SMB_FILE_DISPOSITION_INFORMATION:
3430 case SMB_SET_FILE_DISPOSITION_INFO: /* Set delete on close for open file. */
3432 BOOL delete_on_close;
3435 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
3437 delete_on_close = (CVAL(pdata,0) ? True : False);
3439 /* Just ignore this set on a path. */
3440 if (tran_call != TRANSACT2_SETFILEINFO)
3444 return(UNIXERROR(ERRDOS,ERRbadfid));
3446 status = set_delete_on_close_internal(fsp, delete_on_close, dosmode);
3448 if (NT_STATUS_V(status) != NT_STATUS_V(NT_STATUS_OK))
3449 return ERROR_NT(status);
3451 /* The set is across all open files on this dev/inode pair. */
3452 status =set_delete_on_close_over_all(fsp, delete_on_close);
3453 if (NT_STATUS_V(status) != NT_STATUS_V(NT_STATUS_OK))
3454 return ERROR_NT(status);
3459 case SMB_FILE_POSITION_INFORMATION:
3461 SMB_BIG_UINT position_information;
3464 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
3466 position_information = (SMB_BIG_UINT)IVAL(pdata,0);
3467 #ifdef LARGE_SMB_OFF_T
3468 position_information |= (((SMB_BIG_UINT)IVAL(pdata,4)) << 32);
3469 #else /* LARGE_SMB_OFF_T */
3470 if (IVAL(pdata,4) != 0) /* more than 32 bits? */
3471 return ERROR_DOS(ERRDOS,ERRunknownlevel);
3472 #endif /* LARGE_SMB_OFF_T */
3473 DEBUG(10,("call_trans2setfilepathinfo: Set file position information for file %s to %.0f\n",
3474 fname, (double)position_information ));
3476 fsp->position_information = position_information;
3481 * CIFS UNIX extensions.
3484 case SMB_SET_FILE_UNIX_BASIC:
3486 uint32 raw_unixmode;
3488 if (total_data < 100)
3489 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
3491 if(IVAL(pdata, 0) != SMB_SIZE_NO_CHANGE_LO &&
3492 IVAL(pdata, 4) != SMB_SIZE_NO_CHANGE_HI) {
3493 size=IVAL(pdata,0); /* first 8 Bytes are size */
3494 #ifdef LARGE_SMB_OFF_T
3495 size |= (((SMB_OFF_T)IVAL(pdata,4)) << 32);
3496 #else /* LARGE_SMB_OFF_T */
3497 if (IVAL(pdata,4) != 0) /* more than 32 bits? */
3498 return ERROR_DOS(ERRDOS,ERRunknownlevel);
3499 #endif /* LARGE_SMB_OFF_T */
3501 pdata+=24; /* ctime & st_blocks are not changed */
3502 tvs.actime = interpret_long_date(pdata); /* access_time */
3503 tvs.modtime = interpret_long_date(pdata+8); /* modification_time */
3505 set_owner = (uid_t)IVAL(pdata,0);
3507 set_grp = (gid_t)IVAL(pdata,0);
3509 raw_unixmode = IVAL(pdata,28);
3510 unixmode = unix_perms_from_wire(conn, &sbuf, raw_unixmode);
3511 dosmode = 0; /* Ensure dos mode change doesn't override this. */
3513 DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_BASIC: name = %s \
3514 size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n",
3515 fname, (double)size, (unsigned int)set_owner, (unsigned int)set_grp, (int)raw_unixmode));
3517 if (!VALID_STAT(sbuf)) {
3520 * The only valid use of this is to create character and block
3521 * devices, and named pipes. This is deprecated (IMHO) and
3522 * a new info level should be used for mknod. JRA.
3525 uint32 file_type = IVAL(pdata,0);
3526 #if defined(HAVE_MAKEDEV)
3527 uint32 dev_major = IVAL(pdata,4);
3528 uint32 dev_minor = IVAL(pdata,12);
3531 uid_t myuid = geteuid();
3532 gid_t mygid = getegid();
3533 SMB_DEV_T dev = (SMB_DEV_T)0;
3535 if (tran_call == TRANSACT2_SETFILEINFO)
3536 return(ERROR_DOS(ERRDOS,ERRnoaccess));
3538 if (raw_unixmode == SMB_MODE_NO_CHANGE)
3539 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
3541 #if defined(HAVE_MAKEDEV)
3542 dev = makedev(dev_major, dev_minor);
3545 /* We can only create as the owner/group we are. */
3547 if ((set_owner != myuid) && (set_owner != (uid_t)SMB_UID_NO_CHANGE))
3548 return(ERROR_DOS(ERRDOS,ERRnoaccess));
3549 if ((set_grp != mygid) && (set_grp != (gid_t)SMB_GID_NO_CHANGE))
3550 return(ERROR_DOS(ERRDOS,ERRnoaccess));
3552 switch (file_type) {
3553 #if defined(S_IFIFO)
3554 case UNIX_TYPE_FIFO:
3555 unixmode |= S_IFIFO;
3558 #if defined(S_IFSOCK)
3559 case UNIX_TYPE_SOCKET:
3560 unixmode |= S_IFSOCK;
3563 #if defined(S_IFCHR)
3564 case UNIX_TYPE_CHARDEV:
3565 unixmode |= S_IFCHR;
3568 #if defined(S_IFBLK)
3569 case UNIX_TYPE_BLKDEV:
3570 unixmode |= S_IFBLK;
3574 return(ERROR_DOS(ERRDOS,ERRnoaccess));
3577 DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_BASIC doing mknod dev %.0f mode \
3578 0%o for file %s\n", (double)dev, unixmode, fname ));
3580 /* Ok - do the mknod. */
3581 if (SMB_VFS_MKNOD(conn,fname, unixmode, dev) != 0)
3582 return(UNIXERROR(ERRDOS,ERRnoaccess));
3584 inherit_access_acl(conn, fname, unixmode);
3587 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
3592 * Deal with the UNIX specific mode set.
3595 if (raw_unixmode != SMB_MODE_NO_CHANGE) {
3596 DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_BASIC setting mode 0%o for file %s\n",
3597 (unsigned int)unixmode, fname ));
3598 if (SMB_VFS_CHMOD(conn,fname,unixmode) != 0)
3599 return(UNIXERROR(ERRDOS,ERRnoaccess));
3603 * Deal with the UNIX specific uid set.
3606 if ((set_owner != (uid_t)SMB_UID_NO_CHANGE) && (sbuf.st_uid != set_owner)) {
3607 DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_BASIC changing owner %u for file %s\n",
3608 (unsigned int)set_owner, fname ));
3609 if (SMB_VFS_CHOWN(conn,fname,set_owner, (gid_t)-1) != 0)
3610 return(UNIXERROR(ERRDOS,ERRnoaccess));
3614 * Deal with the UNIX specific gid set.
3617 if ((set_grp != (uid_t)SMB_GID_NO_CHANGE) && (sbuf.st_gid != set_grp)) {
3618 DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_BASIC changing group %u for file %s\n",
3619 (unsigned int)set_owner, fname ));
3620 if (SMB_VFS_CHOWN(conn,fname,(uid_t)-1, set_grp) != 0)
3621 return(UNIXERROR(ERRDOS,ERRnoaccess));
3626 case SMB_SET_FILE_UNIX_LINK:
3628 pstring link_target;
3629 char *newname = fname;
3631 /* Set a symbolic link. */
3632 /* Don't allow this if follow links is false. */
3634 if (!lp_symlinks(SNUM(conn)))
3635 return(ERROR_DOS(ERRDOS,ERRnoaccess));
3637 srvstr_pull(inbuf, link_target, pdata, sizeof(link_target), -1, STR_TERMINATE);
3639 /* !widelinks forces the target path to be within the share. */
3640 /* This means we can interpret the target as a pathname. */
3641 if (!lp_widelinks(SNUM(conn))) {
3643 char *last_dirp = NULL;
3645 unix_format(link_target);
3646 if (*link_target == '/') {
3647 /* No absolute paths allowed. */
3648 return(UNIXERROR(ERRDOS,ERRnoaccess));
3650 pstrcpy(rel_name, newname);
3651 last_dirp = strrchr_m(rel_name, '/');
3653 last_dirp[1] = '\0';
3655 pstrcpy(rel_name, "./");
3657 pstrcat(rel_name, link_target);
3659 if (!check_name(rel_name, conn)) {
3660 return(UNIXERROR(ERRDOS,ERRnoaccess));
3664 DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_LINK doing symlink %s -> %s\n",
3665 fname, link_target ));
3667 if (SMB_VFS_SYMLINK(conn,link_target,newname) != 0)
3668 return(UNIXERROR(ERRDOS,ERRnoaccess));
3670 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
3674 case SMB_SET_FILE_UNIX_HLINK:
3677 char *newname = fname;
3679 /* Set a hard link. */
3680 srvstr_get_path(inbuf, oldname, pdata, sizeof(oldname), -1, STR_TERMINATE, &status, False);
3681 if (!NT_STATUS_IS_OK(status)) {
3682 return ERROR_NT(status);
3685 DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_LINK doing hard link %s -> %s\n",
3688 status = hardlink_internals(conn, oldname, newname);
3689 if (!NT_STATUS_IS_OK(status)) {
3690 return ERROR_NT(status);
3694 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
3698 case SMB_FILE_RENAME_INFORMATION:
3707 if (total_data < 12)
3708 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
3710 overwrite = (CVAL(pdata,0) ? True : False);
3711 root_fid = IVAL(pdata,4);
3712 len = IVAL(pdata,8);
3713 srvstr_get_path(inbuf, newname, &pdata[12], sizeof(newname), len, 0, &status, False);
3714 if (!NT_STATUS_IS_OK(status)) {
3715 return ERROR_NT(status);
3718 /* Check the new name has no '/' characters. */
3719 if (strchr_m(newname, '/'))
3720 return ERROR_NT(NT_STATUS_NOT_SUPPORTED);
3722 RESOLVE_DFSPATH(newname, conn, inbuf, outbuf);
3724 /* Create the base directory. */
3725 pstrcpy(base_name, fname);
3726 p = strrchr_m(base_name, '/');
3729 /* Append the new name. */
3730 pstrcat(base_name, "/");
3731 pstrcat(base_name, newname);
3734 DEBUG(10,("call_trans2setfilepathinfo: SMB_FILE_RENAME_INFORMATION (fnum %d) %s -> %s\n",
3735 fsp->fnum, fsp->fsp_name, base_name ));
3736 status = rename_internals_fsp(conn, fsp, base_name, 0, overwrite);
3738 DEBUG(10,("call_trans2setfilepathinfo: SMB_FILE_RENAME_INFORMATION %s -> %s\n",
3740 status = rename_internals(conn, fname, base_name, 0, overwrite);
3742 if (!NT_STATUS_IS_OK(status)) {
3743 return ERROR_NT(status);
3745 process_pending_change_notify_queue((time_t)0);
3747 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
3751 #if defined(HAVE_POSIX_ACLS)
3752 case SMB_SET_POSIX_ACL:
3754 uint16 posix_acl_version;
3755 uint16 num_file_acls;
3756 uint16 num_def_acls;
3757 BOOL valid_file_acls = True;
3758 BOOL valid_def_acls = True;
3760 if (total_data < SMB_POSIX_ACL_HEADER_SIZE) {
3761 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
3763 posix_acl_version = SVAL(pdata,0);
3764 num_file_acls = SVAL(pdata,2);
3765 num_def_acls = SVAL(pdata,4);
3767 if (num_file_acls == SMB_POSIX_IGNORE_ACE_ENTRIES) {
3768 valid_file_acls = False;
3772 if (num_def_acls == SMB_POSIX_IGNORE_ACE_ENTRIES) {
3773 valid_def_acls = False;
3777 if (posix_acl_version != SMB_POSIX_ACL_VERSION) {
3778 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
3781 if (total_data < SMB_POSIX_ACL_HEADER_SIZE +
3782 (num_file_acls+num_def_acls)*SMB_POSIX_ACL_ENTRY_SIZE) {
3783 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
3786 if (valid_file_acls && !set_unix_posix_acl(conn, fsp, fname, num_file_acls,
3787 pdata + SMB_POSIX_ACL_HEADER_SIZE)) {
3788 return(UNIXERROR(ERRDOS,ERRnoaccess));
3791 if (valid_def_acls && !set_unix_posix_default_acl(conn, fname, &sbuf, num_def_acls,
3792 pdata + SMB_POSIX_ACL_HEADER_SIZE +
3793 (num_file_acls*SMB_POSIX_ACL_ENTRY_SIZE))) {
3794 return(UNIXERROR(ERRDOS,ERRnoaccess));
3798 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
3804 return ERROR_DOS(ERRDOS,ERRunknownlevel);
3807 /* get some defaults (no modifications) if any info is zero or -1. */
3808 if (tvs.actime == (time_t)0 || tvs.actime == (time_t)-1)
3809 tvs.actime = sbuf.st_atime;
3811 if (tvs.modtime == (time_t)0 || tvs.modtime == (time_t)-1)
3812 tvs.modtime = sbuf.st_mtime;
3814 DEBUG(6,("actime: %s " , ctime(&tvs.actime)));
3815 DEBUG(6,("modtime: %s ", ctime(&tvs.modtime)));
3816 DEBUG(6,("size: %.0f ", (double)size));
3819 if (S_ISDIR(sbuf.st_mode))
3825 DEBUG(6,("dosmode: %x\n" , dosmode));
3827 if(!((info_level == SMB_SET_FILE_END_OF_FILE_INFO) ||
3828 (info_level == SMB_SET_FILE_ALLOCATION_INFO) ||
3829 (info_level == SMB_FILE_ALLOCATION_INFORMATION) ||
3830 (info_level == SMB_FILE_END_OF_FILE_INFORMATION))) {
3833 * Only do this test if we are not explicitly
3834 * changing the size of a file.
3837 size = get_file_size(sbuf);
3841 * Try and set the times, size and mode of this file -
3842 * if they are different from the current values
3844 if (sbuf.st_mtime != tvs.modtime || sbuf.st_atime != tvs.actime) {
3847 * This was a setfileinfo on an open file.
3848 * NT does this a lot. We also need to
3849 * set the time here, as it can be read by
3850 * FindFirst/FindNext and with the patch for bug #2045
3851 * in smbd/fileio.c it ensures that this timestamp is
3852 * kept sticky even after a write. We save the request
3853 * away and will set it on file close and after a write. JRA.
3856 if (tvs.modtime != (time_t)0 && tvs.modtime != (time_t)-1) {
3857 DEBUG(10,("call_trans2setfilepathinfo: setting pending modtime to %s\n", ctime(&tvs.modtime) ));
3858 fsp->pending_modtime = tvs.modtime;
3861 DEBUG(10,("call_trans2setfilepathinfo: setting utimes to modified values.\n"));
3863 if(file_utime(conn, fname, &tvs)!=0) {
3864 return(UNIXERROR(ERRDOS,ERRnoaccess));
3869 /* check the mode isn't different, before changing it */
3870 if ((dosmode != 0) && (dosmode != dos_mode(conn, fname, &sbuf))) {
3872 DEBUG(10,("call_trans2setfilepathinfo: file %s : setting dos mode %x\n", fname, dosmode ));
3874 if(file_set_dosmode(conn, fname, dosmode, &sbuf, False)) {
3875 DEBUG(2,("file_set_dosmode of %s failed (%s)\n", fname, strerror(errno)));
3876 return(UNIXERROR(ERRDOS,ERRnoaccess));
3880 if (size != get_file_size(sbuf)) {
3884 DEBUG(10,("call_trans2setfilepathinfo: file %s : setting new size to %.0f\n",
3885 fname, (double)size ));
3888 files_struct *new_fsp = NULL;
3889 int access_mode = 0;
3892 if(global_oplock_break) {
3893 /* Queue this file modify as we are the process of an oplock break. */
3895 DEBUG(2,("call_trans2setfilepathinfo: queueing message due to being "));
3896 DEBUGADD(2,( "in oplock break state.\n"));
3898 push_oplock_pending_smb_message(inbuf, length);
3902 new_fsp = open_file_shared(conn, fname, &sbuf,
3903 SET_OPEN_MODE(DOS_OPEN_RDWR),
3904 (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN),
3905 FILE_ATTRIBUTE_NORMAL,
3906 INTERNAL_OPEN_ONLY, &access_mode, &action);
3908 if (new_fsp == NULL)
3909 return(UNIXERROR(ERRDOS,ERRbadpath));
3910 ret = vfs_set_filelen(new_fsp, size);
3911 close_file(new_fsp,True);
3913 ret = vfs_set_filelen(fsp, size);
3917 return (UNIXERROR(ERRHRD,ERRdiskfull));
3921 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
3926 /****************************************************************************
3927 Reply to a TRANS2_MKDIR (make directory with extended attributes).
3928 ****************************************************************************/
3930 static int call_trans2mkdir(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize,
3931 char **pparams, int total_params, char **ppdata, int total_data,
3932 unsigned int max_data_bytes)
3934 char *params = *pparams;
3937 SMB_STRUCT_STAT sbuf;
3938 BOOL bad_path = False;
3939 NTSTATUS status = NT_STATUS_OK;
3941 if (!CAN_WRITE(conn))
3942 return ERROR_DOS(ERRSRV,ERRaccess);
3944 if (total_params < 4)
3945 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
3947 srvstr_get_path(inbuf, directory, ¶ms[4], sizeof(directory), -1, STR_TERMINATE, &status, False);
3948 if (!NT_STATUS_IS_OK(status)) {
3949 return ERROR_NT(status);
3952 DEBUG(3,("call_trans2mkdir : name = %s\n", directory));
3954 unix_convert(directory,conn,0,&bad_path,&sbuf);
3956 return ERROR_NT(NT_STATUS_OBJECT_PATH_NOT_FOUND);
3958 if (check_name(directory,conn))
3959 ret = vfs_MkDir(conn,directory,unix_mode(conn,aDIR,directory,True));
3962 DEBUG(5,("call_trans2mkdir error (%s)\n", strerror(errno)));
3963 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRnoaccess);
3966 /* Realloc the parameter and data sizes */
3967 params = SMB_REALLOC(*pparams,2);
3969 return ERROR_DOS(ERRDOS,ERRnomem);
3974 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
3979 /****************************************************************************
3980 Reply to a TRANS2_FINDNOTIFYFIRST (start monitoring a directory for changes).
3981 We don't actually do this - we just send a null response.
3982 ****************************************************************************/
3984 static int call_trans2findnotifyfirst(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize,
3985 char **pparams, int total_params, char **ppdata, int total_data,
3986 unsigned int max_data_bytes)
3988 static uint16 fnf_handle = 257;
3989 char *params = *pparams;
3992 if (total_params < 6)
3993 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
3995 info_level = SVAL(params,4);
3996 DEBUG(3,("call_trans2findnotifyfirst - info_level %d\n", info_level));
3998 switch (info_level) {
4003 return ERROR_DOS(ERRDOS,ERRunknownlevel);
4006 /* Realloc the parameter and data sizes */
4007 params = SMB_REALLOC(*pparams,6);
4009 return ERROR_DOS(ERRDOS,ERRnomem);
4012 SSVAL(params,0,fnf_handle);
4013 SSVAL(params,2,0); /* No changes */
4014 SSVAL(params,4,0); /* No EA errors */
4021 send_trans2_replies(outbuf, bufsize, params, 6, *ppdata, 0);
4026 /****************************************************************************
4027 Reply to a TRANS2_FINDNOTIFYNEXT (continue monitoring a directory for
4028 changes). Currently this does nothing.
4029 ****************************************************************************/
4031 static int call_trans2findnotifynext(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize,
4032 char **pparams, int total_params, char **ppdata, int total_data,
4033 unsigned int max_data_bytes)
4035 char *params = *pparams;
4037 DEBUG(3,("call_trans2findnotifynext\n"));
4039 /* Realloc the parameter and data sizes */
4040 params = SMB_REALLOC(*pparams,4);
4042 return ERROR_DOS(ERRDOS,ERRnomem);
4045 SSVAL(params,0,0); /* No changes */
4046 SSVAL(params,2,0); /* No EA errors */
4048 send_trans2_replies(outbuf, bufsize, params, 4, *ppdata, 0);
4053 /****************************************************************************
4054 Reply to a TRANS2_GET_DFS_REFERRAL - Shirish Kalele <kalele@veritas.com>.
4055 ****************************************************************************/
4057 static int call_trans2getdfsreferral(connection_struct *conn, char* inbuf, char* outbuf, int length, int bufsize,
4058 char **pparams, int total_params, char **ppdata, int total_data,
4059 unsigned int max_data_bytes)
4061 char *params = *pparams;
4064 int max_referral_level;
4066 DEBUG(10,("call_trans2getdfsreferral\n"));
4068 if (total_params < 2)
4069 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
4071 max_referral_level = SVAL(params,0);
4073 if(!lp_host_msdfs())
4074 return ERROR_DOS(ERRDOS,ERRbadfunc);
4076 srvstr_pull(inbuf, pathname, ¶ms[2], sizeof(pathname), -1, STR_TERMINATE);
4077 if((reply_size = setup_dfs_referral(conn, pathname,max_referral_level,ppdata)) < 0)
4078 return UNIXERROR(ERRDOS,ERRbadfile);
4080 SSVAL(outbuf,smb_flg2,SVAL(outbuf,smb_flg2) | FLAGS2_DFS_PATHNAMES);
4081 send_trans2_replies(outbuf,bufsize,0,0,*ppdata,reply_size);
4086 #define LMCAT_SPL 0x53
4087 #define LMFUNC_GETJOBID 0x60
4089 /****************************************************************************
4090 Reply to a TRANS2_IOCTL - used for OS/2 printing.
4091 ****************************************************************************/
4093 static int call_trans2ioctl(connection_struct *conn, char* inbuf, char* outbuf, int length, int bufsize,
4094 char **pparams, int total_params, char **ppdata, int total_data,
4095 unsigned int max_data_bytes)
4097 char *pdata = *ppdata;
4098 files_struct *fsp = file_fsp(inbuf,smb_vwv15);
4100 /* check for an invalid fid before proceeding */
4103 return(ERROR_DOS(ERRDOS,ERRbadfid));
4105 if ((SVAL(inbuf,(smb_setup+4)) == LMCAT_SPL) &&
4106 (SVAL(inbuf,(smb_setup+6)) == LMFUNC_GETJOBID)) {
4107 pdata = SMB_REALLOC(*ppdata, 32);
4109 return ERROR_DOS(ERRDOS,ERRnomem);
4112 /* NOTE - THIS IS ASCII ONLY AT THE MOMENT - NOT SURE IF OS/2
4113 CAN ACCEPT THIS IN UNICODE. JRA. */
4115 SSVAL(pdata,0,fsp->rap_print_jobid); /* Job number */
4116 srvstr_push( outbuf, pdata + 2, global_myname(), 15, STR_ASCII|STR_TERMINATE); /* Our NetBIOS name */
4117 srvstr_push( outbuf, pdata+18, lp_servicename(SNUM(conn)), 13, STR_ASCII|STR_TERMINATE); /* Service name */
4118 send_trans2_replies(outbuf,bufsize,*pparams,0,*ppdata,32);
4121 DEBUG(2,("Unknown TRANS2_IOCTL\n"));
4122 return ERROR_DOS(ERRSRV,ERRerror);
4126 /****************************************************************************
4127 Reply to a SMBfindclose (stop trans2 directory search).
4128 ****************************************************************************/
4130 int reply_findclose(connection_struct *conn,
4131 char *inbuf,char *outbuf,int length,int bufsize)
4134 int dptr_num=SVALS(inbuf,smb_vwv0);
4135 START_PROFILE(SMBfindclose);
4137 DEBUG(3,("reply_findclose, dptr_num = %d\n", dptr_num));
4139 dptr_close(&dptr_num);
4141 outsize = set_message(outbuf,0,0,True);
4143 DEBUG(3,("SMBfindclose dptr_num = %d\n", dptr_num));
4145 END_PROFILE(SMBfindclose);
4149 /****************************************************************************
4150 Reply to a SMBfindnclose (stop FINDNOTIFYFIRST directory search).
4151 ****************************************************************************/
4153 int reply_findnclose(connection_struct *conn,
4154 char *inbuf,char *outbuf,int length,int bufsize)
4158 START_PROFILE(SMBfindnclose);
4160 dptr_num = SVAL(inbuf,smb_vwv0);
4162 DEBUG(3,("reply_findnclose, dptr_num = %d\n", dptr_num));
4164 /* We never give out valid handles for a
4165 findnotifyfirst - so any dptr_num is ok here.
4168 outsize = set_message(outbuf,0,0,True);
4170 DEBUG(3,("SMB_findnclose dptr_num = %d\n", dptr_num));
4172 END_PROFILE(SMBfindnclose);
4176 /****************************************************************************
4177 Reply to a SMBtranss2 - just ignore it!
4178 ****************************************************************************/
4180 int reply_transs2(connection_struct *conn,
4181 char *inbuf,char *outbuf,int length,int bufsize)
4183 START_PROFILE(SMBtranss2);
4184 DEBUG(4,("Ignoring transs2 of length %d\n",length));
4185 END_PROFILE(SMBtranss2);
4189 /****************************************************************************
4190 Reply to a SMBtrans2.
4191 ****************************************************************************/
4193 int reply_trans2(connection_struct *conn,
4194 char *inbuf,char *outbuf,int length,int bufsize)
4197 unsigned int total_params = SVAL(inbuf, smb_tpscnt);
4198 unsigned int total_data =SVAL(inbuf, smb_tdscnt);
4199 unsigned int max_data_bytes = SVAL(inbuf, smb_mdrcnt);
4201 unsigned int max_param_reply = SVAL(inbuf, smb_mprcnt);
4202 unsigned int max_setup_fields = SVAL(inbuf, smb_msrcnt);
4203 BOOL close_tid = BITSETW(inbuf+smb_flags,0);
4204 BOOL no_final_response = BITSETW(inbuf+smb_flags,1);
4205 int32 timeout = IVALS(inbuf,smb_timeout);
4207 unsigned int suwcnt = SVAL(inbuf, smb_suwcnt);
4208 unsigned int tran_call = SVAL(inbuf, smb_setup0);
4209 char *params = NULL, *data = NULL;
4210 unsigned int num_params, num_params_sofar, num_data, num_data_sofar;
4211 START_PROFILE(SMBtrans2);
4213 if(global_oplock_break && (tran_call == TRANSACT2_OPEN)) {
4214 /* Queue this open message as we are the process of an
4217 DEBUG(2,("reply_trans2: queueing message trans2open due to being "));
4218 DEBUGADD(2,( "in oplock break state.\n"));
4220 push_oplock_pending_smb_message(inbuf, length);
4221 END_PROFILE(SMBtrans2);
4225 if (IS_IPC(conn) && (tran_call != TRANSACT2_OPEN)
4226 && (tran_call != TRANSACT2_GET_DFS_REFERRAL)) {
4227 END_PROFILE(SMBtrans2);
4228 return ERROR_DOS(ERRSRV,ERRaccess);
4231 outsize = set_message(outbuf,0,0,True);
4233 /* All trans2 messages we handle have smb_sucnt == 1 - ensure this
4234 is so as a sanity check */
4237 * Need to have rc=0 for ioctl to get job id for OS/2.
4238 * Network printing will fail if function is not successful.
4239 * Similar function in reply.c will be used if protocol
4240 * is LANMAN1.0 instead of LM1.2X002.
4241 * Until DosPrintSetJobInfo with PRJINFO3 is supported,
4242 * outbuf doesn't have to be set(only job id is used).
4244 if ( (suwcnt == 4) && (tran_call == TRANSACT2_IOCTL) &&
4245 (SVAL(inbuf,(smb_setup+4)) == LMCAT_SPL) &&
4246 (SVAL(inbuf,(smb_setup+6)) == LMFUNC_GETJOBID)) {
4247 DEBUG(2,("Got Trans2 DevIOctl jobid\n"));
4249 DEBUG(2,("Invalid smb_sucnt in trans2 call(%u)\n",suwcnt));
4250 DEBUG(2,("Transaction is %d\n",tran_call));
4251 END_PROFILE(SMBtrans2);
4252 ERROR_DOS(ERRDOS,ERRinvalidparam);
4256 /* Allocate the space for the maximum needed parameters and data */
4257 if (total_params > 0)
4258 params = (char *)SMB_MALLOC(total_params);
4260 data = (char *)SMB_MALLOC(total_data);
4262 if ((total_params && !params) || (total_data && !data)) {
4263 DEBUG(2,("Out of memory in reply_trans2\n"));
4266 END_PROFILE(SMBtrans2);
4267 return ERROR_DOS(ERRDOS,ERRnomem);
4270 /* Copy the param and data bytes sent with this request into
4271 the params buffer */
4272 num_params = num_params_sofar = SVAL(inbuf,smb_pscnt);
4273 num_data = num_data_sofar = SVAL(inbuf, smb_dscnt);
4275 if (num_params > total_params || num_data > total_data)
4276 exit_server("invalid params in reply_trans2");
4279 unsigned int psoff = SVAL(inbuf, smb_psoff);
4280 if ((psoff + num_params < psoff) || (psoff + num_params < num_params))
4282 if ((smb_base(inbuf) + psoff + num_params > inbuf + length) ||
4283 (smb_base(inbuf) + psoff + num_params < smb_base(inbuf)))
4285 memcpy( params, smb_base(inbuf) + psoff, num_params);
4288 unsigned int dsoff = SVAL(inbuf, smb_dsoff);
4289 if ((dsoff + num_data < dsoff) || (dsoff + num_data < num_data))
4291 if ((smb_base(inbuf) + dsoff + num_data > inbuf + length) ||
4292 (smb_base(inbuf) + dsoff + num_data < smb_base(inbuf)))
4294 memcpy( data, smb_base(inbuf) + dsoff, num_data);
4297 srv_signing_trans_start(SVAL(inbuf,smb_mid));
4299 if(num_data_sofar < total_data || num_params_sofar < total_params) {
4300 /* We need to send an interim response then receive the rest
4301 of the parameter/data bytes */
4302 outsize = set_message(outbuf,0,0,True);
4303 srv_signing_trans_stop();
4304 if (!send_smb(smbd_server_fd(),outbuf))
4305 exit_server("reply_trans2: send_smb failed.");
4307 while (num_data_sofar < total_data ||
4308 num_params_sofar < total_params) {
4310 unsigned int param_disp;
4311 unsigned int param_off;
4312 unsigned int data_disp;
4313 unsigned int data_off;
4315 ret = receive_next_smb(inbuf,bufsize,SMB_SECONDARY_WAIT);
4318 * The sequence number for the trans reply is always
4319 * based on the last secondary received.
4322 srv_signing_trans_start(SVAL(inbuf,smb_mid));
4325 (CVAL(inbuf, smb_com) != SMBtranss2)) || !ret) {
4326 outsize = set_message(outbuf,0,0,True);
4328 DEBUG(0,("reply_trans2: Invalid secondary trans2 packet\n"));
4330 DEBUG(0,("reply_trans2: %s in getting secondary trans2 response.\n",
4331 (smb_read_error == READ_ERROR) ? "error" : "timeout" ));
4335 /* Revise total_params and total_data in case
4336 they have changed downwards */
4337 if (SVAL(inbuf, smb_tpscnt) < total_params)
4338 total_params = SVAL(inbuf, smb_tpscnt);
4339 if (SVAL(inbuf, smb_tdscnt) < total_data)
4340 total_data = SVAL(inbuf, smb_tdscnt);
4342 num_params = SVAL(inbuf,smb_spscnt);
4343 param_off = SVAL(inbuf, smb_spsoff);
4344 param_disp = SVAL(inbuf, smb_spsdisp);
4345 num_params_sofar += num_params;
4347 num_data = SVAL(inbuf, smb_sdscnt);
4348 data_off = SVAL(inbuf, smb_sdsoff);
4349 data_disp = SVAL(inbuf, smb_sdsdisp);
4350 num_data_sofar += num_data;
4352 if (num_params_sofar > total_params || num_data_sofar > total_data)
4356 if (param_disp + num_params > total_params)
4358 if ((param_disp + num_params < param_disp) ||
4359 (param_disp + num_params < num_params))
4361 if (param_disp > total_params)
4363 if ((smb_base(inbuf) + param_off + num_params >= inbuf + bufsize) ||
4364 (smb_base(inbuf) + param_off + num_params < smb_base(inbuf)))
4366 if (params + param_disp < params)
4369 memcpy( ¶ms[param_disp], smb_base(inbuf) + param_off, num_params);
4372 if (data_disp + num_data > total_data)
4374 if ((data_disp + num_data < data_disp) ||
4375 (data_disp + num_data < num_data))
4377 if (data_disp > total_data)
4379 if ((smb_base(inbuf) + data_off + num_data >= inbuf + bufsize) ||
4380 (smb_base(inbuf) + data_off + num_data < smb_base(inbuf)))
4382 if (data + data_disp < data)
4385 memcpy( &data[data_disp], smb_base(inbuf) + data_off, num_data);
4390 if (Protocol >= PROTOCOL_NT1) {
4391 SSVAL(outbuf,smb_flg2,SVAL(outbuf,smb_flg2) | 0x40); /* IS_LONG_NAME */
4394 /* Now we must call the relevant TRANS2 function */
4396 case TRANSACT2_OPEN:
4397 START_PROFILE_NESTED(Trans2_open);
4398 outsize = call_trans2open(conn, inbuf, outbuf, bufsize,
4399 ¶ms, total_params, &data, total_data, max_data_bytes);
4400 END_PROFILE_NESTED(Trans2_open);
4403 case TRANSACT2_FINDFIRST:
4404 START_PROFILE_NESTED(Trans2_findfirst);
4405 outsize = call_trans2findfirst(conn, inbuf, outbuf, bufsize,
4406 ¶ms, total_params, &data, total_data, max_data_bytes);
4407 END_PROFILE_NESTED(Trans2_findfirst);
4410 case TRANSACT2_FINDNEXT:
4411 START_PROFILE_NESTED(Trans2_findnext);
4412 outsize = call_trans2findnext(conn, inbuf, outbuf, length, bufsize,
4413 ¶ms, total_params, &data, total_data, max_data_bytes);
4414 END_PROFILE_NESTED(Trans2_findnext);
4417 case TRANSACT2_QFSINFO:
4418 START_PROFILE_NESTED(Trans2_qfsinfo);
4419 outsize = call_trans2qfsinfo(conn, inbuf, outbuf, length, bufsize,
4420 ¶ms, total_params, &data, total_data, max_data_bytes);
4421 END_PROFILE_NESTED(Trans2_qfsinfo);
4424 #ifdef HAVE_SYS_QUOTAS
4425 case TRANSACT2_SETFSINFO:
4426 START_PROFILE_NESTED(Trans2_setfsinfo);
4427 outsize = call_trans2setfsinfo(conn, inbuf, outbuf, length, bufsize,
4428 ¶ms, total_params, &data, total_data, max_data_bytes);
4429 END_PROFILE_NESTED(Trans2_setfsinfo);
4432 case TRANSACT2_QPATHINFO:
4433 case TRANSACT2_QFILEINFO:
4434 START_PROFILE_NESTED(Trans2_qpathinfo);
4435 outsize = call_trans2qfilepathinfo(conn, inbuf, outbuf, length, bufsize,
4436 ¶ms, total_params, &data, total_data, max_data_bytes);
4437 END_PROFILE_NESTED(Trans2_qpathinfo);
4439 case TRANSACT2_SETPATHINFO:
4440 case TRANSACT2_SETFILEINFO:
4441 START_PROFILE_NESTED(Trans2_setpathinfo);
4442 outsize = call_trans2setfilepathinfo(conn, inbuf, outbuf, length, bufsize,
4443 ¶ms, total_params, &data, total_data, max_data_bytes);
4444 END_PROFILE_NESTED(Trans2_setpathinfo);
4447 case TRANSACT2_FINDNOTIFYFIRST:
4448 START_PROFILE_NESTED(Trans2_findnotifyfirst);
4449 outsize = call_trans2findnotifyfirst(conn, inbuf, outbuf, length, bufsize,
4450 ¶ms, total_params, &data, total_data, max_data_bytes);
4451 END_PROFILE_NESTED(Trans2_findnotifyfirst);
4454 case TRANSACT2_FINDNOTIFYNEXT:
4455 START_PROFILE_NESTED(Trans2_findnotifynext);
4456 outsize = call_trans2findnotifynext(conn, inbuf, outbuf, length, bufsize,
4457 ¶ms, total_params, &data, total_data, max_data_bytes);
4458 END_PROFILE_NESTED(Trans2_findnotifynext);
4460 case TRANSACT2_MKDIR:
4461 START_PROFILE_NESTED(Trans2_mkdir);
4462 outsize = call_trans2mkdir(conn, inbuf, outbuf, length, bufsize,
4463 ¶ms, total_params, &data, total_data, max_data_bytes);
4464 END_PROFILE_NESTED(Trans2_mkdir);
4467 case TRANSACT2_GET_DFS_REFERRAL:
4468 START_PROFILE_NESTED(Trans2_get_dfs_referral);
4469 outsize = call_trans2getdfsreferral(conn,inbuf,outbuf,length, bufsize,
4470 ¶ms, total_params, &data, total_data, max_data_bytes);
4471 END_PROFILE_NESTED(Trans2_get_dfs_referral);
4473 case TRANSACT2_IOCTL:
4474 START_PROFILE_NESTED(Trans2_ioctl);
4475 outsize = call_trans2ioctl(conn,inbuf,outbuf,length, bufsize,
4476 ¶ms, total_params, &data, total_data, max_data_bytes);
4477 END_PROFILE_NESTED(Trans2_ioctl);
4480 /* Error in request */
4481 DEBUG(2,("Unknown request %d in trans2 call\n", tran_call));
4484 END_PROFILE(SMBtrans2);
4485 srv_signing_trans_stop();
4486 return ERROR_DOS(ERRSRV,ERRerror);
4489 /* As we do not know how many data packets will need to be
4490 returned here the various call_trans2xxxx calls
4491 must send their own. Thus a call_trans2xxx routine only
4492 returns a value other than -1 when it wants to send
4496 srv_signing_trans_stop();
4500 END_PROFILE(SMBtrans2);
4501 return outsize; /* If a correct response was needed the
4502 call_trans2xxx calls have already sent
4503 it. If outsize != -1 then it is returning */
4507 srv_signing_trans_stop();
4510 END_PROFILE(SMBtrans2);
4511 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);