2 Unix SMB/CIFS implementation.
3 SMB transaction2 handling
4 Copyright (C) Jeremy Allison 1994-2003
5 Copyright (C) Stefan (metze) Metzmacher 2003
7 Extensively modified by Andrew Tridgell, 1995
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
27 extern int smb_read_error;
28 extern fstring local_machine;
29 extern int global_oplock_break;
30 extern uint32 global_client_caps;
31 extern struct current_user current_user;
33 #define get_file_size(sbuf) ((sbuf).st_size)
34 #define DIR_ENTRY_SAFETY_MARGIN 4096
36 /********************************************************************
37 Roundup a value to the nearest SMB_ROUNDUP_ALLOCATION_SIZE boundary.
38 Only do this for Windows clients.
39 ********************************************************************/
41 SMB_BIG_UINT smb_roundup(SMB_BIG_UINT val)
43 /* Only roundup for Windows clients. */
44 enum remote_arch_types ra_type = get_remote_arch();
45 if ((ra_type != RA_SAMBA) && (ra_type != RA_CIFSFS)) {
46 val = SMB_ROUNDUP(val,SMB_ROUNDUP_ALLOCATION_SIZE);
51 /********************************************************************
52 Given a stat buffer return the allocated size on disk, taking into
54 ********************************************************************/
56 SMB_BIG_UINT get_allocation_size(files_struct *fsp, SMB_STRUCT_STAT *sbuf)
60 #if defined(HAVE_STAT_ST_BLOCKS) && defined(STAT_ST_BLOCKSIZE)
61 ret = (SMB_BIG_UINT)STAT_ST_BLOCKSIZE * (SMB_BIG_UINT)sbuf->st_blocks;
63 ret = (SMB_BIG_UINT)get_file_size(*sbuf);
66 if (!ret && fsp && fsp->initial_allocation_size)
67 ret = fsp->initial_allocation_size;
69 ret = smb_roundup(ret);
74 /****************************************************************************
75 Utility functions for dealing with extended attributes.
76 ****************************************************************************/
78 static const char *prohibited_ea_names[] = {
79 SAMBA_POSIX_INHERITANCE_EA_NAME,
80 SAMBA_XATTR_DOS_ATTRIB,
84 /****************************************************************************
85 Refuse to allow clients to overwrite our private xattrs.
86 ****************************************************************************/
88 static BOOL samba_private_attr_name(const char *unix_ea_name)
92 for (i = 0; prohibited_ea_names[i]; i++) {
93 if (strequal( prohibited_ea_names[i], unix_ea_name))
100 struct ea_list *next, *prev;
104 /****************************************************************************
105 Get one EA value. Fill in a struct ea_struct.
106 ****************************************************************************/
108 static BOOL get_ea_value(TALLOC_CTX *mem_ctx, connection_struct *conn, files_struct *fsp,
109 const char *fname, char *ea_name, struct ea_struct *pea)
111 /* Get the value of this xattr. Max size is 64k. */
112 size_t attr_size = 256;
118 val = talloc_realloc(mem_ctx, val, attr_size);
123 if (fsp && fsp->fd != -1) {
124 sizeret = SMB_VFS_FGETXATTR(fsp, fsp->fd, ea_name, val, attr_size);
126 sizeret = SMB_VFS_GETXATTR(conn, fname, ea_name, val, attr_size);
129 if (sizeret == -1 && errno == ERANGE && attr_size != 65536) {
138 DEBUG(10,("get_ea_value: EA %s is of length %d: ", ea_name, sizeret));
139 dump_data(10, val, sizeret);
142 if (strnequal(ea_name, "user.", 5)) {
143 pea->name = &ea_name[5];
147 pea->value.data = val;
148 pea->value.length = (size_t)sizeret;
152 /****************************************************************************
153 Return a linked list of the total EA's. Plus the total size
154 ****************************************************************************/
156 static struct ea_list *get_ea_list(TALLOC_CTX *mem_ctx, connection_struct *conn, files_struct *fsp, const char *fname, size_t *pea_total_len)
158 /* Get a list of all xattrs. Max namesize is 64k. */
159 size_t ea_namelist_size = 1024;
164 struct ea_list *ea_list_head = NULL;
168 if (!lp_ea_support(SNUM(conn))) {
172 for (i = 0, ea_namelist = talloc(mem_ctx, ea_namelist_size); i < 6;
173 ea_namelist = talloc_realloc(mem_ctx, ea_namelist, ea_namelist_size), i++) {
174 if (fsp && fsp->fd != -1) {
175 sizeret = SMB_VFS_FLISTXATTR(fsp, fsp->fd, ea_namelist, ea_namelist_size);
177 sizeret = SMB_VFS_LISTXATTR(conn, fname, ea_namelist, ea_namelist_size);
180 if (sizeret == -1 && errno == ERANGE) {
181 ea_namelist_size *= 2;
190 DEBUG(10,("get_ea_list: ea_namelist size = %d\n", sizeret ));
193 for (p = ea_namelist; p - ea_namelist < sizeret; p += strlen(p) + 1) {
194 struct ea_list *listp, *tmp;
196 if (strnequal(p, "system.", 7) || samba_private_attr_name(p))
199 listp = talloc(mem_ctx, sizeof(struct ea_list));
203 if (!get_ea_value(mem_ctx, conn, fsp, fname, p, &listp->ea)) {
209 push_ascii_fstring(dos_ea_name, listp->ea.name);
210 *pea_total_len += 4 + strlen(dos_ea_name) + 1 + listp->ea.value.length;
211 DEBUG(10,("get_ea_list: total_len = %u, %s, val len = %u\n",
212 *pea_total_len, dos_ea_name,
213 (unsigned int)listp->ea.value.length ));
215 DLIST_ADD_END(ea_list_head, listp, tmp);
217 /* Add on 4 for total length. */
218 if (*pea_total_len) {
223 DEBUG(10,("get_ea_list: total_len = %u\n", *pea_total_len));
227 /****************************************************************************
228 Fill a qfilepathinfo buffer with EA's. Returns the length of the buffer
230 ****************************************************************************/
232 static unsigned int fill_ea_buffer(char *pdata, unsigned int total_data_size,
233 connection_struct *conn, files_struct *fsp, const char *fname)
235 unsigned int ret_data_size = 4;
239 struct ea_list *ea_list;
241 SMB_ASSERT(total_data_size >= 4);
244 if (!lp_ea_support(SNUM(conn))) {
247 mem_ctx = talloc_init("fill_ea_buffer");
252 ea_list = get_ea_list(mem_ctx, conn, fsp, fname, &total_ea_len);
254 talloc_destroy(mem_ctx);
258 if (total_ea_len > total_data_size) {
259 talloc_destroy(mem_ctx);
263 for (p = pdata + 4; ea_list; ea_list = ea_list->next) {
266 push_ascii_fstring(dos_ea_name, ea_list->ea.name);
267 dos_namelen = strlen(dos_ea_name);
268 if (dos_namelen > 255 || dos_namelen == 0) {
271 if (ea_list->ea.value.length > 65535) {
274 if (4 + dos_namelen + 1 + ea_list->ea.value.length > total_data_size) {
278 /* We know we have room. */
279 SCVAL(p,0,ea_list->ea.flags);
280 SCVAL(p,1,dos_namelen);
281 SSVAL(p,2,ea_list->ea.value.length);
282 fstrcpy(p+4, dos_ea_name);
283 memcpy( p + 4 + dos_namelen + 1, ea_list->ea.value.data, ea_list->ea.value.length);
285 total_data_size -= 4 + dos_namelen + 1 + ea_list->ea.value.length;
286 p += 4 + dos_namelen + 1 + ea_list->ea.value.length;
289 ret_data_size = PTR_DIFF(p, pdata);
290 DEBUG(10,("fill_ea_buffer: data_size = %u, total_ea_len = %u\n",
291 ret_data_size, total_ea_len ));
292 talloc_destroy(mem_ctx);
293 SIVAL(pdata,0,ret_data_size);
294 return ret_data_size;
297 static unsigned int estimate_ea_size(connection_struct *conn, files_struct *fsp, const char *fname)
299 size_t total_ea_len = 0;
300 TALLOC_CTX *mem_ctx = NULL;
302 if (!lp_ea_support(SNUM(conn))) {
305 mem_ctx = talloc_init("estimate_ea_size");
306 (void)get_ea_list(mem_ctx, conn, fsp, fname, &total_ea_len);
307 talloc_destroy(mem_ctx);
311 /****************************************************************************
312 Ensure the EA name is case insensitive by matching any existing EA name.
313 ****************************************************************************/
315 static void canonicalize_ea_name(connection_struct *conn, files_struct *fsp, const char *fname, fstring unix_ea_name)
318 TALLOC_CTX *mem_ctx = talloc_init("canonicalize_ea_name");
319 struct ea_list *ea_list = get_ea_list(mem_ctx, conn, fsp, fname, &total_ea_len);
321 for (; ea_list; ea_list = ea_list->next) {
322 if (strequal(&unix_ea_name[5], ea_list->ea.name)) {
323 DEBUG(10,("canonicalize_ea_name: %s -> %s\n",
324 &unix_ea_name[5], ea_list->ea.name));
325 safe_strcpy(&unix_ea_name[5], ea_list->ea.name, sizeof(fstring)-6);
329 talloc_destroy(mem_ctx);
332 /****************************************************************************
333 Set or delete an extended attribute.
334 ****************************************************************************/
336 static NTSTATUS set_ea(connection_struct *conn, files_struct *fsp, const char *fname,
337 char *pdata, int total_data)
339 unsigned int namelen;
342 fstring unix_ea_name;
344 if (!lp_ea_support(SNUM(conn))) {
345 return NT_STATUS_EAS_NOT_SUPPORTED;
348 if (total_data < 8) {
349 return NT_STATUS_INVALID_PARAMETER;
352 if (IVAL(pdata,0) > total_data) {
353 DEBUG(10,("set_ea: bad total data size (%u) > %u\n", IVAL(pdata,0), (unsigned int)total_data));
354 return NT_STATUS_INVALID_PARAMETER;
358 namelen = CVAL(pdata,1);
359 ealen = SVAL(pdata,2);
361 if (total_data < 8 + namelen + 1 + ealen) {
362 DEBUG(10,("set_ea: bad total data size (%u) < 8 + namelen (%u) + 1 + ealen (%u)\n",
363 (unsigned int)total_data, namelen, ealen));
364 return NT_STATUS_INVALID_PARAMETER;
367 if (pdata[namelen] != '\0') {
368 DEBUG(10,("set_ea: ea name not null terminated\n"));
369 return NT_STATUS_INVALID_PARAMETER;
372 fstrcpy(unix_ea_name, "user."); /* All EA's must start with user. */
373 pull_ascii(&unix_ea_name[5], pdata, sizeof(fstring) - 5, -1, STR_TERMINATE);
374 pdata += (namelen + 1);
376 canonicalize_ea_name(conn, fsp, fname, unix_ea_name);
378 DEBUG(10,("set_ea: ea_name %s ealen = %u\n", unix_ea_name, ealen));
380 DEBUG(10,("set_ea: data :\n"));
381 dump_data(10, pdata, ealen);
384 if (samba_private_attr_name(unix_ea_name)) {
385 DEBUG(10,("set_ea: ea name %s is a private Samba name.\n", unix_ea_name));
386 return NT_STATUS_ACCESS_DENIED;
390 /* Remove the attribute. */
391 if (fsp && (fsp->fd != -1)) {
392 DEBUG(10,("set_ea: deleting ea name %s on file %s by file descriptor.\n",
393 unix_ea_name, fsp->fsp_name));
394 ret = SMB_VFS_FREMOVEXATTR(fsp, fsp->fd, unix_ea_name);
396 DEBUG(10,("set_ea: deleting ea name %s on file %s.\n",
397 unix_ea_name, fname));
398 ret = SMB_VFS_REMOVEXATTR(conn, fname, unix_ea_name);
401 /* Removing a non existent attribute always succeeds. */
402 if (ret == -1 && errno == ENOATTR) {
403 DEBUG(10,("set_ea: deleting ea name %s didn't exist - succeeding by default.\n", unix_ea_name));
408 if (fsp && (fsp->fd != -1)) {
409 DEBUG(10,("set_ea: setting ea name %s on file %s by file descriptor.\n",
410 unix_ea_name, fsp->fsp_name));
411 ret = SMB_VFS_FSETXATTR(fsp, fsp->fd, unix_ea_name, pdata, ealen, 0);
413 DEBUG(10,("set_ea: setting ea name %s on file %s.\n",
414 unix_ea_name, fname));
415 ret = SMB_VFS_SETXATTR(conn, fname, unix_ea_name, pdata, ealen, 0);
421 if (errno == ENOTSUP) {
422 return NT_STATUS_EAS_NOT_SUPPORTED;
425 return map_nt_error_from_unix(errno);
431 /****************************************************************************
432 Send the required number of replies back.
433 We assume all fields other than the data fields are
434 set correctly for the type of call.
435 HACK ! Always assumes smb_setup field is zero.
436 ****************************************************************************/
438 static int send_trans2_replies(char *outbuf,
445 /* As we are using a protocol > LANMAN1 then the max_send
446 variable must have been set in the sessetupX call.
447 This takes precedence over the max_xmit field in the
448 global struct. These different max_xmit variables should
449 be merged as this is now too confusing */
452 int data_to_send = datasize;
453 int params_to_send = paramsize;
457 int params_sent_thistime, data_sent_thistime, total_sent_thistime;
458 int alignment_offset = 1; /* JRA. This used to be 3. Set to 1 to make netmon parse ok. */
459 int data_alignment_offset = 0;
461 /* Initially set the wcnt area to be 10 - this is true for all trans2 replies */
463 set_message(outbuf,10,0,True);
465 /* If there genuinely are no parameters or data to send just send the empty packet */
467 if(params_to_send == 0 && data_to_send == 0) {
468 if (!send_smb(smbd_server_fd(),outbuf))
469 exit_server("send_trans2_replies: send_smb failed.");
473 /* When sending params and data ensure that both are nicely aligned */
474 /* Only do this alignment when there is also data to send - else
475 can cause NT redirector problems. */
477 if (((params_to_send % 4) != 0) && (data_to_send != 0))
478 data_alignment_offset = 4 - (params_to_send % 4);
480 /* Space is bufsize minus Netbios over TCP header minus SMB header */
481 /* The alignment_offset is to align the param bytes on an even byte
482 boundary. NT 4.0 Beta needs this to work correctly. */
484 useable_space = bufsize - ((smb_buf(outbuf)+ alignment_offset+data_alignment_offset) - outbuf);
486 /* useable_space can never be more than max_send minus the alignment offset. */
488 useable_space = MIN(useable_space, max_send - (alignment_offset+data_alignment_offset));
490 while (params_to_send || data_to_send) {
491 /* Calculate whether we will totally or partially fill this packet */
493 total_sent_thistime = params_to_send + data_to_send + alignment_offset + data_alignment_offset;
495 /* We can never send more than useable_space */
497 * Note that 'useable_space' does not include the alignment offsets,
498 * but we must include the alignment offsets in the calculation of
499 * the length of the data we send over the wire, as the alignment offsets
500 * are sent here. Fix from Marc_Jacobsen@hp.com.
503 total_sent_thistime = MIN(total_sent_thistime, useable_space+ alignment_offset + data_alignment_offset);
505 set_message(outbuf, 10, total_sent_thistime, True);
507 /* Set total params and data to be sent */
508 SSVAL(outbuf,smb_tprcnt,paramsize);
509 SSVAL(outbuf,smb_tdrcnt,datasize);
511 /* Calculate how many parameters and data we can fit into
512 * this packet. Parameters get precedence
515 params_sent_thistime = MIN(params_to_send,useable_space);
516 data_sent_thistime = useable_space - params_sent_thistime;
517 data_sent_thistime = MIN(data_sent_thistime,data_to_send);
519 SSVAL(outbuf,smb_prcnt, params_sent_thistime);
521 /* smb_proff is the offset from the start of the SMB header to the
522 parameter bytes, however the first 4 bytes of outbuf are
523 the Netbios over TCP header. Thus use smb_base() to subtract
524 them from the calculation */
526 SSVAL(outbuf,smb_proff,((smb_buf(outbuf)+alignment_offset) - smb_base(outbuf)));
528 if(params_sent_thistime == 0)
529 SSVAL(outbuf,smb_prdisp,0);
531 /* Absolute displacement of param bytes sent in this packet */
532 SSVAL(outbuf,smb_prdisp,pp - params);
534 SSVAL(outbuf,smb_drcnt, data_sent_thistime);
535 if(data_sent_thistime == 0) {
536 SSVAL(outbuf,smb_droff,0);
537 SSVAL(outbuf,smb_drdisp, 0);
539 /* The offset of the data bytes is the offset of the
540 parameter bytes plus the number of parameters being sent this time */
541 SSVAL(outbuf,smb_droff,((smb_buf(outbuf)+alignment_offset) -
542 smb_base(outbuf)) + params_sent_thistime + data_alignment_offset);
543 SSVAL(outbuf,smb_drdisp, pd - pdata);
546 /* Copy the param bytes into the packet */
548 if(params_sent_thistime)
549 memcpy((smb_buf(outbuf)+alignment_offset),pp,params_sent_thistime);
551 /* Copy in the data bytes */
552 if(data_sent_thistime)
553 memcpy(smb_buf(outbuf)+alignment_offset+params_sent_thistime+
554 data_alignment_offset,pd,data_sent_thistime);
556 DEBUG(9,("t2_rep: params_sent_thistime = %d, data_sent_thistime = %d, useable_space = %d\n",
557 params_sent_thistime, data_sent_thistime, useable_space));
558 DEBUG(9,("t2_rep: params_to_send = %d, data_to_send = %d, paramsize = %d, datasize = %d\n",
559 params_to_send, data_to_send, paramsize, datasize));
561 /* Send the packet */
562 if (!send_smb(smbd_server_fd(),outbuf))
563 exit_server("send_trans2_replies: send_smb failed.");
565 pp += params_sent_thistime;
566 pd += data_sent_thistime;
568 params_to_send -= params_sent_thistime;
569 data_to_send -= data_sent_thistime;
572 if(params_to_send < 0 || data_to_send < 0) {
573 DEBUG(0,("send_trans2_replies failed sanity check pts = %d, dts = %d\n!!!",
574 params_to_send, data_to_send));
582 /****************************************************************************
583 Reply to a TRANSACT2_OPEN.
584 ****************************************************************************/
586 static int call_trans2open(connection_struct *conn, char *inbuf, char *outbuf, int bufsize,
587 char **pparams, int total_params, char **ppdata, int total_data,
588 unsigned int max_data_bytes)
590 char *params = *pparams;
595 BOOL return_additional_info;
604 int fmode=0,mtime=0,rmode;
606 SMB_STRUCT_STAT sbuf;
608 BOOL bad_path = False;
613 * Ensure we have enough parameters to perform the operation.
616 if (total_params < 29)
617 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
619 open_mode = SVAL(params, 2);
620 open_attr = SVAL(params,6);
621 oplock_request = (((SVAL(params,0)|(1<<1))>>1) | ((SVAL(params,0)|(1<<2))>>1));
623 return_additional_info = BITSETW(params,0);
624 open_sattr = SVAL(params, 4);
625 open_time = make_unix_date3(params+8);
627 open_ofun = SVAL(params,12);
628 open_size = IVAL(params,14);
632 return(ERROR_DOS(ERRSRV,ERRaccess));
634 srvstr_get_path(inbuf, fname, pname, sizeof(fname), -1, STR_TERMINATE, &status, False);
635 if (!NT_STATUS_IS_OK(status)) {
636 return ERROR_NT(status);
639 DEBUG(3,("trans2open %s mode=%d attr=%d ofun=%d size=%d\n",
640 fname,open_mode, open_attr, open_ofun, open_size));
642 /* XXXX we need to handle passed times, sattr and flags */
644 unix_convert(fname,conn,0,&bad_path,&sbuf);
646 return ERROR_NT(NT_STATUS_OBJECT_PATH_NOT_FOUND);
649 if (!check_name(fname,conn)) {
650 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRnoaccess);
653 fsp = open_file_shared(conn,fname,&sbuf,open_mode,open_ofun,(uint32)open_attr,
654 oplock_request, &rmode,&smb_action);
657 if (open_was_deferred(SVAL(inbuf,smb_mid))) {
658 /* We have re-scheduled this call. */
659 clear_cached_errors();
662 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRnoaccess);
665 size = get_file_size(sbuf);
666 fmode = dos_mode(conn,fname,&sbuf);
667 mtime = sbuf.st_mtime;
670 close_file(fsp,False);
671 return(ERROR_DOS(ERRDOS,ERRnoaccess));
674 /* Realloc the size of parameters and data we will return */
675 params = Realloc(*pparams, 28);
677 return(ERROR_DOS(ERRDOS,ERRnomem));
680 memset((char *)params,'\0',28);
681 SSVAL(params,0,fsp->fnum);
682 SSVAL(params,2,fmode);
683 put_dos_date2(params,4, mtime);
684 SIVAL(params,8, (uint32)size);
685 SSVAL(params,12,rmode);
687 if (oplock_request && lp_fake_oplocks(SNUM(conn)))
688 smb_action |= EXTENDED_OPLOCK_GRANTED;
690 SSVAL(params,18,smb_action);
693 * WARNING - this may need to be changed if SMB_INO_T <> 4 bytes.
695 SIVAL(params,20,inode);
697 /* Send the required number of replies */
698 send_trans2_replies(outbuf, bufsize, params, 28, *ppdata, 0);
703 /*********************************************************
704 Routine to check if a given string matches exactly.
705 as a special case a mask of "." does NOT match. That
706 is required for correct wildcard semantics
707 Case can be significant or not.
708 **********************************************************/
710 static BOOL exact_match(char *str,char *mask, BOOL case_sig)
712 if (mask[0] == '.' && mask[1] == 0)
715 return strcmp(str,mask)==0;
716 if (StrCaseCmp(str,mask) != 0) {
719 if (ms_has_wild(str)) {
725 /****************************************************************************
726 Return the filetype for UNIX extensions.
727 ****************************************************************************/
729 static uint32 unix_filetype(mode_t mode)
732 return UNIX_TYPE_FILE;
733 else if(S_ISDIR(mode))
734 return UNIX_TYPE_DIR;
736 else if(S_ISLNK(mode))
737 return UNIX_TYPE_SYMLINK;
740 else if(S_ISCHR(mode))
741 return UNIX_TYPE_CHARDEV;
744 else if(S_ISBLK(mode))
745 return UNIX_TYPE_BLKDEV;
748 else if(S_ISFIFO(mode))
749 return UNIX_TYPE_FIFO;
752 else if(S_ISSOCK(mode))
753 return UNIX_TYPE_SOCKET;
756 DEBUG(0,("unix_filetype: unknown filetype %u", (unsigned)mode));
757 return UNIX_TYPE_UNKNOWN;
760 /****************************************************************************
761 Map wire perms onto standard UNIX permissions. Obey share restrictions.
762 ****************************************************************************/
764 static mode_t unix_perms_from_wire( connection_struct *conn, SMB_STRUCT_STAT *pst, uint32 perms)
768 if (perms == SMB_MODE_NO_CHANGE)
771 ret |= ((perms & UNIX_X_OTH ) ? S_IXOTH : 0);
772 ret |= ((perms & UNIX_W_OTH ) ? S_IWOTH : 0);
773 ret |= ((perms & UNIX_R_OTH ) ? S_IROTH : 0);
774 ret |= ((perms & UNIX_X_GRP ) ? S_IXGRP : 0);
775 ret |= ((perms & UNIX_W_GRP ) ? S_IWGRP : 0);
776 ret |= ((perms & UNIX_R_GRP ) ? S_IRGRP : 0);
777 ret |= ((perms & UNIX_X_USR ) ? S_IXUSR : 0);
778 ret |= ((perms & UNIX_W_USR ) ? S_IWUSR : 0);
779 ret |= ((perms & UNIX_R_USR ) ? S_IRUSR : 0);
781 ret |= ((perms & UNIX_STICKY ) ? S_ISVTX : 0);
784 ret |= ((perms & UNIX_SET_GID ) ? S_ISGID : 0);
787 ret |= ((perms & UNIX_SET_UID ) ? S_ISUID : 0);
790 if (VALID_STAT(*pst) && S_ISDIR(pst->st_mode)) {
791 ret &= lp_dir_mask(SNUM(conn));
792 /* Add in force bits */
793 ret |= lp_force_dir_mode(SNUM(conn));
795 /* Apply mode mask */
796 ret &= lp_create_mask(SNUM(conn));
797 /* Add in force bits */
798 ret |= lp_force_create_mode(SNUM(conn));
804 /****************************************************************************
805 Checks for SMB_TIME_NO_CHANGE and if not found calls interpret_long_date.
806 ****************************************************************************/
808 time_t interpret_long_unix_date(char *p)
810 DEBUG(10,("interpret_long_unix_date\n"));
811 if(IVAL(p,0) == SMB_TIME_NO_CHANGE_LO &&
812 IVAL(p,4) == SMB_TIME_NO_CHANGE_HI) {
815 return interpret_long_date(p);
819 /****************************************************************************
820 Get a level dependent lanman2 dir entry.
821 ****************************************************************************/
823 static BOOL get_lanman2_dir_entry(connection_struct *conn,
824 void *inbuf, void *outbuf,
825 char *path_mask,int dirtype,int info_level,
826 int requires_resume_key,
827 BOOL dont_descend,char **ppdata,
828 char *base_data, int space_remaining,
829 BOOL *out_of_space, BOOL *got_exact_match,
834 SMB_STRUCT_STAT sbuf;
838 char *p, *q, *pdata = *ppdata;
842 SMB_OFF_T file_size = 0;
843 SMB_BIG_UINT allocation_size = 0;
845 time_t mdate=0, adate=0, cdate=0;
848 int nt_extmode; /* Used for NT connections instead of mode */
849 BOOL needslash = ( conn->dirpath[strlen(conn->dirpath) -1] != '/');
852 *out_of_space = False;
853 *got_exact_match = False;
858 p = strrchr_m(path_mask,'/');
865 pstrcpy(mask, path_mask);
870 /* Needed if we run out of space */
871 prev_dirpos = TellDir(conn->dirptr);
872 dname = ReadDirName(conn->dirptr);
875 * Due to bugs in NT client redirectors we are not using
876 * resume keys any more - set them to zero.
877 * Check out the related comments in findfirst/findnext.
883 DEBUG(8,("get_lanman2_dir_entry:readdir on dirptr 0x%lx now at offset %d\n",
884 (long)conn->dirptr,TellDir(conn->dirptr)));
889 pstrcpy(fname,dname);
891 if(!(got_match = *got_exact_match = exact_match(fname, mask, conn->case_sensitive)))
892 got_match = mask_match(fname, mask, conn->case_sensitive);
894 if(!got_match && !mangle_is_8_3(fname, False)) {
897 * It turns out that NT matches wildcards against
898 * both long *and* short names. This may explain some
899 * of the wildcard wierdness from old DOS clients
900 * that some people have been seeing.... JRA.
904 pstrcpy( newname, fname);
905 mangle_map( newname, True, False, SNUM(conn));
906 if(!(got_match = *got_exact_match = exact_match(newname, mask, conn->case_sensitive)))
907 got_match = mask_match(newname, mask, conn->case_sensitive);
911 BOOL isdots = (strequal(fname,"..") || strequal(fname,"."));
912 if (dont_descend && !isdots)
915 pstrcpy(pathreal,conn->dirpath);
917 pstrcat(pathreal,"/");
918 pstrcat(pathreal,dname);
920 if (INFO_LEVEL_IS_UNIX(info_level)) {
921 if (SMB_VFS_LSTAT(conn,pathreal,&sbuf) != 0) {
922 DEBUG(5,("get_lanman2_dir_entry:Couldn't lstat [%s] (%s)\n",
923 pathreal,strerror(errno)));
926 } else if (SMB_VFS_STAT(conn,pathreal,&sbuf) != 0) {
928 /* Needed to show the msdfs symlinks as
931 if(lp_host_msdfs() &&
932 lp_msdfs_root(SNUM(conn)) &&
933 is_msdfs_link(conn, pathreal, NULL, NULL,
936 DEBUG(5,("get_lanman2_dir_entry: Masquerading msdfs link %s as a directory\n", pathreal));
937 sbuf.st_mode = (sbuf.st_mode & 0xFFF) | S_IFDIR;
941 DEBUG(5,("get_lanman2_dir_entry:Couldn't stat [%s] (%s)\n",
942 pathreal,strerror(errno)));
947 mode = dos_mode(conn,pathreal,&sbuf);
949 if (!dir_check_ftype(conn,mode,&sbuf,dirtype)) {
950 DEBUG(5,("[%s] attribs didn't match %x\n",fname,dirtype));
954 file_size = get_file_size(sbuf);
955 allocation_size = get_allocation_size(NULL,&sbuf);
956 mdate = sbuf.st_mtime;
957 adate = sbuf.st_atime;
958 cdate = get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(conn)));
960 if (lp_dos_filetime_resolution(SNUM(conn))) {
969 DEBUG(5,("get_lanman2_dir_entry found %s fname=%s\n",pathreal,fname));
975 mangle_map(fname,False,True,SNUM(conn));
980 nt_extmode = mode ? mode : FILE_ATTRIBUTE_NORMAL;
982 switch (info_level) {
983 case SMB_INFO_STANDARD:
984 DEBUG(10,("get_lanman2_dir_entry: SMB_INFO_STANDARD\n"));
985 if(requires_resume_key) {
989 put_dos_date2(p,l1_fdateCreation,cdate);
990 put_dos_date2(p,l1_fdateLastAccess,adate);
991 put_dos_date2(p,l1_fdateLastWrite,mdate);
992 SIVAL(p,l1_cbFile,(uint32)file_size);
993 SIVAL(p,l1_cbFileAlloc,(uint32)allocation_size);
994 SSVAL(p,l1_attrFile,mode);
997 p += align_string(outbuf, p, 0);
998 len = srvstr_push(outbuf, p, fname, -1, STR_TERMINATE);
999 if (SVAL(outbuf, smb_flg2) & FLAGS2_UNICODE_STRINGS) {
1001 SCVAL(nameptr, -1, len - 2);
1003 SCVAL(nameptr, -1, 0);
1007 SCVAL(nameptr, -1, len - 1);
1009 SCVAL(nameptr, -1, 0);
1015 case SMB_INFO_QUERY_EA_SIZE:
1016 DEBUG(10,("get_lanman2_dir_entry: SMB_INFO_QUERY_EA_SIZE\n"));
1017 if(requires_resume_key) {
1021 put_dos_date2(p,l2_fdateCreation,cdate);
1022 put_dos_date2(p,l2_fdateLastAccess,adate);
1023 put_dos_date2(p,l2_fdateLastWrite,mdate);
1024 SIVAL(p,l2_cbFile,(uint32)file_size);
1025 SIVAL(p,l2_cbFileAlloc,(uint32)allocation_size);
1026 SSVAL(p,l2_attrFile,mode);
1028 unsigned int ea_size = estimate_ea_size(conn, NULL, pathreal);
1029 SIVAL(p,l2_cbList,ea_size); /* Extended attributes */
1033 len = srvstr_push(outbuf, p, fname, -1, STR_TERMINATE | STR_NOALIGN);
1034 if (SVAL(outbuf, smb_flg2) & FLAGS2_UNICODE_STRINGS) {
1047 SCVAL(nameptr,0,len);
1049 SCVAL(p,0,0); p += 1; /* Extra zero byte ? - why.. */
1052 case SMB_FIND_FILE_BOTH_DIRECTORY_INFO:
1053 DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_FILE_BOTH_DIRECTORY_INFO\n"));
1054 was_8_3 = mangle_is_8_3(fname, True);
1056 SIVAL(p,0,reskey); p += 4;
1057 put_long_date(p,cdate); p += 8;
1058 put_long_date(p,adate); p += 8;
1059 put_long_date(p,mdate); p += 8;
1060 put_long_date(p,mdate); p += 8;
1061 SOFF_T(p,0,file_size); p += 8;
1062 SOFF_T(p,0,allocation_size); p += 8;
1063 SIVAL(p,0,nt_extmode); p += 4;
1064 q = p; p += 4; /* q is placeholder for name length. */
1066 unsigned int ea_size = estimate_ea_size(conn, NULL, pathreal);
1067 SIVAL(p,0,ea_size); /* Extended attributes */
1070 /* Clear the short name buffer. This is
1071 * IMPORTANT as not doing so will trigger
1072 * a Win2k client bug. JRA.
1075 if (!was_8_3 && lp_manglednames(SNUM(conn))) {
1076 pstring mangled_name;
1077 pstrcpy(mangled_name, fname);
1078 mangle_map(mangled_name,True,True,SNUM(conn));
1079 mangled_name[12] = 0;
1080 len = srvstr_push(outbuf, p+2, mangled_name, 24, STR_UPPER|STR_UNICODE);
1087 len = srvstr_push(outbuf, p, fname, -1, STR_TERMINATE_ASCII);
1090 len = PTR_DIFF(p, pdata);
1091 len = (len + 3) & ~3;
1096 case SMB_FIND_FILE_DIRECTORY_INFO:
1097 DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_FILE_DIRECTORY_INFO\n"));
1099 SIVAL(p,0,reskey); p += 4;
1100 put_long_date(p,cdate); p += 8;
1101 put_long_date(p,adate); p += 8;
1102 put_long_date(p,mdate); p += 8;
1103 put_long_date(p,mdate); p += 8;
1104 SOFF_T(p,0,file_size); p += 8;
1105 SOFF_T(p,0,allocation_size); p += 8;
1106 SIVAL(p,0,nt_extmode); p += 4;
1107 len = srvstr_push(outbuf, p + 4, fname, -1, STR_TERMINATE_ASCII);
1110 len = PTR_DIFF(p, pdata);
1111 len = (len + 3) & ~3;
1116 case SMB_FIND_FILE_FULL_DIRECTORY_INFO:
1117 DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_FILE_FULL_DIRECTORY_INFO\n"));
1119 SIVAL(p,0,reskey); p += 4;
1120 put_long_date(p,cdate); p += 8;
1121 put_long_date(p,adate); p += 8;
1122 put_long_date(p,mdate); p += 8;
1123 put_long_date(p,mdate); p += 8;
1124 SOFF_T(p,0,file_size); p += 8;
1125 SOFF_T(p,0,allocation_size); p += 8;
1126 SIVAL(p,0,nt_extmode); p += 4;
1127 q = p; p += 4; /* q is placeholder for name length. */
1129 unsigned int ea_size = estimate_ea_size(conn, NULL, pathreal);
1130 SIVAL(p,0,ea_size); /* Extended attributes */
1133 len = srvstr_push(outbuf, p, fname, -1, STR_TERMINATE_ASCII);
1137 len = PTR_DIFF(p, pdata);
1138 len = (len + 3) & ~3;
1143 case SMB_FIND_FILE_NAMES_INFO:
1144 DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_FILE_NAMES_INFO\n"));
1146 SIVAL(p,0,reskey); p += 4;
1148 /* this must *not* be null terminated or w2k gets in a loop trying to set an
1149 acl on a dir (tridge) */
1150 len = srvstr_push(outbuf, p, fname, -1, STR_TERMINATE_ASCII);
1153 len = PTR_DIFF(p, pdata);
1154 len = (len + 3) & ~3;
1159 case SMB_FIND_ID_FULL_DIRECTORY_INFO:
1160 DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_ID_FULL_DIRECTORY_INFO\n"));
1162 SIVAL(p,0,reskey); p += 4;
1163 put_long_date(p,cdate); p += 8;
1164 put_long_date(p,adate); p += 8;
1165 put_long_date(p,mdate); p += 8;
1166 put_long_date(p,mdate); p += 8;
1167 SOFF_T(p,0,file_size); p += 8;
1168 SOFF_T(p,0,allocation_size); p += 8;
1169 SIVAL(p,0,nt_extmode); p += 4;
1170 q = p; p += 4; /* q is placeholder for name length. */
1172 unsigned int ea_size = estimate_ea_size(conn, NULL, pathreal);
1173 SIVAL(p,0,ea_size); /* Extended attributes */
1176 SIVAL(p,0,0); p += 4; /* Unknown - reserved ? */
1177 SIVAL(p,0,sbuf.st_dev); p += 4;
1178 SIVAL(p,0,sbuf.st_ino); p += 4;
1179 len = srvstr_push(outbuf, p, fname, -1, STR_TERMINATE_ASCII);
1182 len = PTR_DIFF(p, pdata);
1183 len = (len + 3) & ~3;
1188 case SMB_FIND_ID_BOTH_DIRECTORY_INFO:
1189 DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_ID_BOTH_DIRECTORY_INFO\n"));
1190 was_8_3 = mangle_is_8_3(fname, True);
1192 SIVAL(p,0,reskey); p += 4;
1193 put_long_date(p,cdate); p += 8;
1194 put_long_date(p,adate); p += 8;
1195 put_long_date(p,mdate); p += 8;
1196 put_long_date(p,mdate); p += 8;
1197 SOFF_T(p,0,file_size); p += 8;
1198 SOFF_T(p,0,allocation_size); p += 8;
1199 SIVAL(p,0,nt_extmode); p += 4;
1200 q = p; p += 4; /* q is placeholder for name length */
1202 unsigned int ea_size = estimate_ea_size(conn, NULL, pathreal);
1203 SIVAL(p,0,ea_size); /* Extended attributes */
1206 /* Clear the short name buffer. This is
1207 * IMPORTANT as not doing so will trigger
1208 * a Win2k client bug. JRA.
1211 if (!was_8_3 && lp_manglednames(SNUM(conn))) {
1212 pstring mangled_name;
1213 pstrcpy(mangled_name, fname);
1214 mangle_map(mangled_name,True,True,SNUM(conn));
1215 mangled_name[12] = 0;
1216 len = srvstr_push(outbuf, p+2, mangled_name, 24, STR_UPPER|STR_UNICODE);
1223 SSVAL(p,0,0); p += 2; /* Reserved ? */
1224 SIVAL(p,0,sbuf.st_dev); p += 4;
1225 SIVAL(p,0,sbuf.st_ino); p += 4;
1226 len = srvstr_push(outbuf, p, fname, -1, STR_TERMINATE_ASCII);
1229 len = PTR_DIFF(p, pdata);
1230 len = (len + 3) & ~3;
1235 /* CIFS UNIX Extension. */
1237 case SMB_FIND_FILE_UNIX:
1238 DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_FILE_UNIX\n"));
1240 SIVAL(p,0,reskey); p+= 4; /* Used for continuing search. */
1242 /* Begin of SMB_QUERY_FILE_UNIX_BASIC */
1243 SOFF_T(p,0,get_file_size(sbuf)); /* File size 64 Bit */
1246 SOFF_T(p,0,get_allocation_size(NULL,&sbuf)); /* Number of bytes used on disk - 64 Bit */
1249 put_long_date(p,sbuf.st_ctime); /* Inode change Time 64 Bit */
1250 put_long_date(p+8,sbuf.st_atime); /* Last access time 64 Bit */
1251 put_long_date(p+16,sbuf.st_mtime); /* Last modification time 64 Bit */
1254 SIVAL(p,0,sbuf.st_uid); /* user id for the owner */
1258 SIVAL(p,0,sbuf.st_gid); /* group id of owner */
1262 SIVAL(p,0,unix_filetype(sbuf.st_mode));
1265 SIVAL(p,0,unix_dev_major(sbuf.st_rdev)); /* Major device number if type is device */
1269 SIVAL(p,0,unix_dev_minor(sbuf.st_rdev)); /* Minor device number if type is device */
1273 SINO_T(p,0,(SMB_INO_T)sbuf.st_ino); /* inode number */
1276 SIVAL(p,0, unix_perms_to_wire(sbuf.st_mode)); /* Standard UNIX file permissions */
1280 SIVAL(p,0,sbuf.st_nlink); /* number of hard links */
1284 len = srvstr_push(outbuf, p, fname, -1, STR_TERMINATE);
1287 len = PTR_DIFF(p, pdata);
1288 len = (len + 3) & ~3;
1289 SIVAL(pdata,0,len); /* Offset from this structure to the beginning of the next one */
1291 /* End of SMB_QUERY_FILE_UNIX_BASIC */
1300 if (PTR_DIFF(p,pdata) > space_remaining) {
1301 /* Move the dirptr back to prev_dirpos */
1302 SeekDir(conn->dirptr, prev_dirpos);
1303 *out_of_space = True;
1304 DEBUG(9,("get_lanman2_dir_entry: out of space\n"));
1305 return False; /* Not finished - just out of space */
1308 /* Setup the last_filename pointer, as an offset from base_data */
1309 *last_name_off = PTR_DIFF(nameptr,base_data);
1310 /* Advance the data pointer to the next slot */
1316 /****************************************************************************
1317 Reply to a TRANS2_FINDFIRST.
1318 ****************************************************************************/
1320 static int call_trans2findfirst(connection_struct *conn, char *inbuf, char *outbuf, int bufsize,
1321 char **pparams, int total_params, char **ppdata, int total_data,
1322 unsigned int max_data_bytes)
1324 /* We must be careful here that we don't return more than the
1325 allowed number of data bytes. If this means returning fewer than
1326 maxentries then so be it. We assume that the redirector has
1327 enough room for the fixed number of parameter bytes it has
1329 char *params = *pparams;
1330 char *pdata = *ppdata;
1331 int dirtype = SVAL(params,0);
1332 int maxentries = SVAL(params,2);
1333 uint16 findfirst_flags = SVAL(params,4);
1334 BOOL close_after_first = (findfirst_flags & FLAG_TRANS2_FIND_CLOSE);
1335 BOOL close_if_end = (findfirst_flags & FLAG_TRANS2_FIND_CLOSE_IF_END);
1336 BOOL requires_resume_key = (findfirst_flags & FLAG_TRANS2_FIND_REQUIRE_RESUME);
1337 int info_level = SVAL(params,6);
1341 int last_name_off=0;
1345 BOOL finished = False;
1346 BOOL dont_descend = False;
1347 BOOL out_of_space = False;
1348 int space_remaining;
1349 BOOL bad_path = False;
1350 SMB_STRUCT_STAT sbuf;
1351 NTSTATUS ntstatus = NT_STATUS_OK;
1353 if (total_params < 12)
1354 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
1356 *directory = *mask = 0;
1358 DEBUG(3,("call_trans2findfirst: dirtype = %d, maxentries = %d, close_after_first=%d, \
1359 close_if_end = %d requires_resume_key = %d level = 0x%x, max_data_bytes = %d\n",
1360 dirtype, maxentries, close_after_first, close_if_end, requires_resume_key,
1361 info_level, max_data_bytes));
1364 /* W2K3 seems to treat zero as 1. */
1368 switch (info_level) {
1369 case SMB_INFO_STANDARD:
1370 case SMB_INFO_QUERY_EA_SIZE:
1371 case SMB_FIND_FILE_DIRECTORY_INFO:
1372 case SMB_FIND_FILE_FULL_DIRECTORY_INFO:
1373 case SMB_FIND_FILE_NAMES_INFO:
1374 case SMB_FIND_FILE_BOTH_DIRECTORY_INFO:
1375 case SMB_FIND_ID_FULL_DIRECTORY_INFO:
1376 case SMB_FIND_ID_BOTH_DIRECTORY_INFO:
1378 case SMB_FIND_FILE_UNIX:
1379 if (!lp_unix_extensions())
1380 return(ERROR_DOS(ERRDOS,ERRunknownlevel));
1383 return(ERROR_DOS(ERRDOS,ERRunknownlevel));
1386 srvstr_get_path(inbuf, directory, params+12, sizeof(directory), -1, STR_TERMINATE, &ntstatus, True);
1387 if (!NT_STATUS_IS_OK(ntstatus)) {
1388 return ERROR_NT(ntstatus);
1391 RESOLVE_FINDFIRST_DFSPATH(directory, conn, inbuf, outbuf);
1393 unix_convert(directory,conn,0,&bad_path,&sbuf);
1395 return ERROR_NT(NT_STATUS_OBJECT_PATH_NOT_FOUND);
1397 if(!check_name(directory,conn)) {
1398 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRbadpath);
1401 p = strrchr_m(directory,'/');
1403 /* Windows and OS/2 systems treat search on the root '\' as if it were '\*' */
1404 if((directory[0] == '.') && (directory[1] == '\0'))
1407 pstrcpy(mask,directory);
1408 pstrcpy(directory,"./");
1414 DEBUG(5,("dir=%s, mask = %s\n",directory, mask));
1416 pdata = Realloc(*ppdata, max_data_bytes + DIR_ENTRY_SAFETY_MARGIN);
1418 return(ERROR_DOS(ERRDOS,ERRnomem));
1421 memset((char *)pdata,'\0',max_data_bytes + DIR_ENTRY_SAFETY_MARGIN);
1423 /* Realloc the params space */
1424 params = Realloc(*pparams, 10);
1426 return ERROR_DOS(ERRDOS,ERRnomem);
1429 dptr_num = dptr_create(conn,directory, False, True ,SVAL(inbuf,smb_pid));
1431 return(UNIXERROR(ERRDOS,ERRbadfile));
1433 /* Save the wildcard match and attribs we are using on this directory -
1434 needed as lanman2 assumes these are being saved between calls */
1436 if(!(wcard = strdup(mask))) {
1437 dptr_close(&dptr_num);
1438 return ERROR_DOS(ERRDOS,ERRnomem);
1441 dptr_set_wcard(dptr_num, wcard);
1442 dptr_set_attr(dptr_num, dirtype);
1444 DEBUG(4,("dptr_num is %d, wcard = %s, attr = %d\n",dptr_num, wcard, dirtype));
1446 /* We don't need to check for VOL here as this is returned by
1447 a different TRANS2 call. */
1449 DEBUG(8,("dirpath=<%s> dontdescend=<%s>\n", conn->dirpath,lp_dontdescend(SNUM(conn))));
1450 if (in_list(conn->dirpath,lp_dontdescend(SNUM(conn)),conn->case_sensitive))
1451 dont_descend = True;
1454 space_remaining = max_data_bytes;
1455 out_of_space = False;
1457 for (i=0;(i<maxentries) && !finished && !out_of_space;i++) {
1458 BOOL got_exact_match = False;
1460 /* this is a heuristic to avoid seeking the dirptr except when
1461 absolutely necessary. It allows for a filename of about 40 chars */
1462 if (space_remaining < DIRLEN_GUESS && numentries > 0) {
1463 out_of_space = True;
1466 finished = !get_lanman2_dir_entry(conn,
1468 mask,dirtype,info_level,
1469 requires_resume_key,dont_descend,
1470 &p,pdata,space_remaining, &out_of_space, &got_exact_match,
1474 if (finished && out_of_space)
1477 if (!finished && !out_of_space)
1481 * As an optimisation if we know we aren't looking
1482 * for a wildcard name (ie. the name matches the wildcard exactly)
1483 * then we can finish on any (first) match.
1484 * This speeds up large directory searches. JRA.
1490 space_remaining = max_data_bytes - PTR_DIFF(p,pdata);
1493 /* Check if we can close the dirptr */
1494 if(close_after_first || (finished && close_if_end)) {
1495 DEBUG(5,("call_trans2findfirst - (2) closing dptr_num %d\n", dptr_num));
1496 dptr_close(&dptr_num);
1500 * If there are no matching entries we must return ERRDOS/ERRbadfile -
1501 * from observation of NT.
1504 if(numentries == 0) {
1505 dptr_close(&dptr_num);
1506 return ERROR_DOS(ERRDOS,ERRbadfile);
1509 /* At this point pdata points to numentries directory entries. */
1511 /* Set up the return parameter block */
1512 SSVAL(params,0,dptr_num);
1513 SSVAL(params,2,numentries);
1514 SSVAL(params,4,finished);
1515 SSVAL(params,6,0); /* Never an EA error */
1516 SSVAL(params,8,last_name_off);
1518 send_trans2_replies( outbuf, bufsize, params, 10, pdata, PTR_DIFF(p,pdata));
1520 if ((! *directory) && dptr_path(dptr_num))
1521 slprintf(directory,sizeof(directory)-1, "(%s)",dptr_path(dptr_num));
1523 DEBUG( 4, ( "%s mask=%s directory=%s dirtype=%d numentries=%d\n",
1524 smb_fn_name(CVAL(inbuf,smb_com)),
1525 mask, directory, dirtype, numentries ) );
1528 * Force a name mangle here to ensure that the
1529 * mask as an 8.3 name is top of the mangled cache.
1530 * The reasons for this are subtle. Don't remove
1531 * this code unless you know what you are doing
1532 * (see PR#13758). JRA.
1535 if(!mangle_is_8_3_wildcards( mask, False))
1536 mangle_map(mask, True, True, SNUM(conn));
1541 /****************************************************************************
1542 Reply to a TRANS2_FINDNEXT.
1543 ****************************************************************************/
1545 static int call_trans2findnext(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize,
1546 char **pparams, int total_params, char **ppdata, int total_data,
1547 unsigned int max_data_bytes)
1549 /* We must be careful here that we don't return more than the
1550 allowed number of data bytes. If this means returning fewer than
1551 maxentries then so be it. We assume that the redirector has
1552 enough room for the fixed number of parameter bytes it has
1554 char *params = *pparams;
1555 char *pdata = *ppdata;
1556 int dptr_num = SVAL(params,0);
1557 int maxentries = SVAL(params,2);
1558 uint16 info_level = SVAL(params,4);
1559 uint32 resume_key = IVAL(params,6);
1560 uint16 findnext_flags = SVAL(params,10);
1561 BOOL close_after_request = (findnext_flags & FLAG_TRANS2_FIND_CLOSE);
1562 BOOL close_if_end = (findnext_flags & FLAG_TRANS2_FIND_CLOSE_IF_END);
1563 BOOL requires_resume_key = (findnext_flags & FLAG_TRANS2_FIND_REQUIRE_RESUME);
1564 BOOL continue_bit = (findnext_flags & FLAG_TRANS2_FIND_CONTINUE);
1565 pstring resume_name;
1571 int i, last_name_off=0;
1572 BOOL finished = False;
1573 BOOL dont_descend = False;
1574 BOOL out_of_space = False;
1575 int space_remaining;
1576 NTSTATUS ntstatus = NT_STATUS_OK;
1578 if (total_params < 12)
1579 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
1581 *mask = *directory = *resume_name = 0;
1583 srvstr_get_path(inbuf, resume_name, params+12, sizeof(resume_name), -1, STR_TERMINATE, &ntstatus, True);
1584 if (!NT_STATUS_IS_OK(ntstatus)) {
1585 return ERROR_NT(ntstatus);
1588 DEBUG(3,("call_trans2findnext: dirhandle = %d, max_data_bytes = %d, maxentries = %d, \
1589 close_after_request=%d, close_if_end = %d requires_resume_key = %d \
1590 resume_key = %d resume name = %s continue=%d level = %d\n",
1591 dptr_num, max_data_bytes, maxentries, close_after_request, close_if_end,
1592 requires_resume_key, resume_key, resume_name, continue_bit, info_level));
1595 /* W2K3 seems to treat zero as 1. */
1599 switch (info_level) {
1600 case SMB_INFO_STANDARD:
1601 case SMB_INFO_QUERY_EA_SIZE:
1602 case SMB_FIND_FILE_DIRECTORY_INFO:
1603 case SMB_FIND_FILE_FULL_DIRECTORY_INFO:
1604 case SMB_FIND_FILE_NAMES_INFO:
1605 case SMB_FIND_FILE_BOTH_DIRECTORY_INFO:
1607 case SMB_FIND_FILE_UNIX:
1608 if (!lp_unix_extensions())
1609 return(ERROR_DOS(ERRDOS,ERRunknownlevel));
1612 return ERROR_DOS(ERRDOS,ERRunknownlevel);
1615 pdata = Realloc( *ppdata, max_data_bytes + DIR_ENTRY_SAFETY_MARGIN);
1617 return ERROR_DOS(ERRDOS,ERRnomem);
1620 memset((char *)pdata,'\0',max_data_bytes + DIR_ENTRY_SAFETY_MARGIN);
1622 /* Realloc the params space */
1623 params = Realloc(*pparams, 6*SIZEOFWORD);
1624 if( params == NULL )
1625 return ERROR_DOS(ERRDOS,ERRnomem);
1629 /* Check that the dptr is valid */
1630 if(!(conn->dirptr = dptr_fetch_lanman2(dptr_num)))
1631 return ERROR_DOS(ERRDOS,ERRnofiles);
1633 string_set(&conn->dirpath,dptr_path(dptr_num));
1635 /* Get the wildcard mask from the dptr */
1636 if((p = dptr_wcard(dptr_num))== NULL) {
1637 DEBUG(2,("dptr_num %d has no wildcard\n", dptr_num));
1638 return ERROR_DOS(ERRDOS,ERRnofiles);
1642 pstrcpy(directory,conn->dirpath);
1644 /* Get the attr mask from the dptr */
1645 dirtype = dptr_attr(dptr_num);
1647 DEBUG(3,("dptr_num is %d, mask = %s, attr = %x, dirptr=(0x%lX,%d)\n",
1648 dptr_num, mask, dirtype,
1650 TellDir(conn->dirptr)));
1652 /* We don't need to check for VOL here as this is returned by
1653 a different TRANS2 call. */
1655 DEBUG(8,("dirpath=<%s> dontdescend=<%s>\n",conn->dirpath,lp_dontdescend(SNUM(conn))));
1656 if (in_list(conn->dirpath,lp_dontdescend(SNUM(conn)),conn->case_sensitive))
1657 dont_descend = True;
1660 space_remaining = max_data_bytes;
1661 out_of_space = False;
1664 * Seek to the correct position. We no longer use the resume key but
1665 * depend on the last file name instead.
1668 if(*resume_name && !continue_bit) {
1671 * Fix for NT redirector problem triggered by resume key indexes
1672 * changing between directory scans. We now return a resume key of 0
1673 * and instead look for the filename to continue from (also given
1674 * to us by NT/95/smbfs/smbclient). If no other scans have been done between the
1675 * findfirst/findnext (as is usual) then the directory pointer
1676 * should already be at the correct place. Check this by scanning
1677 * backwards looking for an exact (ie. case sensitive) filename match.
1678 * If we get to the beginning of the directory and haven't found it then scan
1679 * forwards again looking for a match. JRA.
1682 int current_pos, start_pos;
1683 const char *dname = NULL;
1684 pstring dname_pstring;
1685 void *dirptr = conn->dirptr;
1686 start_pos = TellDir(dirptr);
1687 for(current_pos = start_pos; current_pos >= 0; current_pos--) {
1688 DEBUG(7,("call_trans2findnext: seeking to pos %d\n", current_pos));
1690 SeekDir(dirptr, current_pos);
1691 dname = ReadDirName(dirptr);
1694 * Remember, mangle_map is called by
1695 * get_lanman2_dir_entry(), so the resume name
1696 * could be mangled. Ensure we do the same
1700 /* make sure we get a copy that mangle_map can modify */
1702 pstrcpy(dname_pstring, dname);
1703 mangle_map( dname_pstring, False, True, SNUM(conn));
1705 if(strcsequal( resume_name, dname_pstring)) {
1706 SeekDir(dirptr, current_pos+1);
1707 DEBUG(7,("call_trans2findnext: got match at pos %d\n", current_pos+1 ));
1714 * Scan forward from start if not found going backwards.
1717 if(current_pos < 0) {
1718 DEBUG(7,("call_trans2findnext: notfound: seeking to pos %d\n", start_pos));
1719 SeekDir(dirptr, start_pos);
1720 for(current_pos = start_pos; (dname = ReadDirName(dirptr)) != NULL; ++current_pos) {
1723 * Remember, mangle_map is called by
1724 * get_lanman2_dir_entry(), so the resume name
1725 * could be mangled. Ensure we do the same
1730 /* make sure we get a copy that mangle_map can modify */
1732 pstrcpy(dname_pstring, dname);
1733 mangle_map(dname_pstring, False, True, SNUM(conn));
1735 if(strcsequal( resume_name, dname_pstring)) {
1736 SeekDir(dirptr, current_pos+1);
1737 DEBUG(7,("call_trans2findnext: got match at pos %d\n", current_pos+1 ));
1742 } /* end if current_pos */
1743 /* Can't find the name. Just resume from where we were... */
1745 SeekDir(dirptr, start_pos);
1747 } /* end if resume_name && !continue_bit */
1749 for (i=0;(i<(int)maxentries) && !finished && !out_of_space ;i++) {
1750 BOOL got_exact_match = False;
1752 /* this is a heuristic to avoid seeking the dirptr except when
1753 absolutely necessary. It allows for a filename of about 40 chars */
1754 if (space_remaining < DIRLEN_GUESS && numentries > 0) {
1755 out_of_space = True;
1758 finished = !get_lanman2_dir_entry(conn,
1760 mask,dirtype,info_level,
1761 requires_resume_key,dont_descend,
1762 &p,pdata,space_remaining, &out_of_space, &got_exact_match,
1766 if (finished && out_of_space)
1769 if (!finished && !out_of_space)
1773 * As an optimisation if we know we aren't looking
1774 * for a wildcard name (ie. the name matches the wildcard exactly)
1775 * then we can finish on any (first) match.
1776 * This speeds up large directory searches. JRA.
1782 space_remaining = max_data_bytes - PTR_DIFF(p,pdata);
1785 /* Check if we can close the dirptr */
1786 if(close_after_request || (finished && close_if_end)) {
1787 DEBUG(5,("call_trans2findnext: closing dptr_num = %d\n", dptr_num));
1788 dptr_close(&dptr_num); /* This frees up the saved mask */
1791 /* Set up the return parameter block */
1792 SSVAL(params,0,numentries);
1793 SSVAL(params,2,finished);
1794 SSVAL(params,4,0); /* Never an EA error */
1795 SSVAL(params,6,last_name_off);
1797 send_trans2_replies( outbuf, bufsize, params, 8, pdata, PTR_DIFF(p,pdata));
1799 if ((! *directory) && dptr_path(dptr_num))
1800 slprintf(directory,sizeof(directory)-1, "(%s)",dptr_path(dptr_num));
1802 DEBUG( 3, ( "%s mask=%s directory=%s dirtype=%d numentries=%d\n",
1803 smb_fn_name(CVAL(inbuf,smb_com)),
1804 mask, directory, dirtype, numentries ) );
1809 /****************************************************************************
1810 Reply to a TRANS2_QFSINFO (query filesystem info).
1811 ****************************************************************************/
1813 static int call_trans2qfsinfo(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize,
1814 char **pparams, int total_params, char **ppdata, int total_data,
1815 unsigned int max_data_bytes)
1817 char *pdata = *ppdata;
1818 char *params = *pparams;
1819 uint16 info_level = SVAL(params,0);
1822 char *vname = volume_label(SNUM(conn));
1823 int snum = SNUM(conn);
1824 char *fstype = lp_fstype(SNUM(conn));
1827 DEBUG(3,("call_trans2qfsinfo: level = %d\n", info_level));
1829 if(SMB_VFS_STAT(conn,".",&st)!=0) {
1830 DEBUG(2,("call_trans2qfsinfo: stat of . failed (%s)\n", strerror(errno)));
1831 return ERROR_DOS(ERRSRV,ERRinvdevice);
1834 pdata = Realloc(*ppdata, max_data_bytes + DIR_ENTRY_SAFETY_MARGIN);
1835 if ( pdata == NULL )
1836 return ERROR_DOS(ERRDOS,ERRnomem);
1839 memset((char *)pdata,'\0',max_data_bytes + DIR_ENTRY_SAFETY_MARGIN);
1841 switch (info_level) {
1842 case SMB_INFO_ALLOCATION:
1844 SMB_BIG_UINT dfree,dsize,bsize,block_size,sectors_per_unit,bytes_per_sector;
1846 SMB_VFS_DISK_FREE(conn,".",False,&bsize,&dfree,&dsize);
1847 block_size = lp_block_size(snum);
1848 if (bsize < block_size) {
1849 SMB_BIG_UINT factor = block_size/bsize;
1854 if (bsize > block_size) {
1855 SMB_BIG_UINT factor = bsize/block_size;
1860 bytes_per_sector = 512;
1861 sectors_per_unit = bsize/bytes_per_sector;
1863 DEBUG(5,("call_trans2qfsinfo : SMB_INFO_ALLOCATION id=%x, bsize=%u, cSectorUnit=%u, \
1864 cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)st.st_dev, (unsigned int)bsize, (unsigned int)sectors_per_unit,
1865 (unsigned int)bytes_per_sector, (unsigned int)dsize, (unsigned int)dfree));
1867 SIVAL(pdata,l1_idFileSystem,st.st_dev);
1868 SIVAL(pdata,l1_cSectorUnit,sectors_per_unit);
1869 SIVAL(pdata,l1_cUnit,dsize);
1870 SIVAL(pdata,l1_cUnitAvail,dfree);
1871 SSVAL(pdata,l1_cbSector,bytes_per_sector);
1875 case SMB_INFO_VOLUME:
1876 /* Return volume name */
1878 * Add volume serial number - hash of a combination of
1879 * the called hostname and the service name.
1881 SIVAL(pdata,0,str_checksum(lp_servicename(snum)) ^ (str_checksum(local_machine)<<16) );
1882 len = srvstr_push(outbuf, pdata+l2_vol_szVolLabel, vname, -1, STR_NOALIGN);
1883 SCVAL(pdata,l2_vol_cch,len);
1884 data_len = l2_vol_szVolLabel + len;
1885 DEBUG(5,("call_trans2qfsinfo : time = %x, namelen = %d, name = %s\n",
1886 (unsigned)st.st_ctime, len, vname));
1889 case SMB_QUERY_FS_ATTRIBUTE_INFO:
1890 case SMB_FS_ATTRIBUTE_INFORMATION:
1893 #if defined(HAVE_SYS_QUOTAS)
1894 quota_flag = FILE_VOLUME_QUOTAS;
1897 SIVAL(pdata,0,FILE_CASE_PRESERVED_NAMES|FILE_CASE_SENSITIVE_SEARCH|
1898 (lp_nt_acl_support(SNUM(conn)) ? FILE_PERSISTENT_ACLS : 0)|
1899 quota_flag); /* FS ATTRIBUTES */
1901 SIVAL(pdata,4,255); /* Max filename component length */
1902 /* NOTE! the fstype must *not* be null terminated or win98 won't recognise it
1903 and will think we can't do long filenames */
1904 len = srvstr_push(outbuf, pdata+12, fstype, -1, STR_UNICODE);
1906 data_len = 12 + len;
1909 case SMB_QUERY_FS_LABEL_INFO:
1910 case SMB_FS_LABEL_INFORMATION:
1911 len = srvstr_push(outbuf, pdata+4, vname, -1, 0);
1916 case SMB_QUERY_FS_VOLUME_INFO:
1917 case SMB_FS_VOLUME_INFORMATION:
1920 * Add volume serial number - hash of a combination of
1921 * the called hostname and the service name.
1923 SIVAL(pdata,8,str_checksum(lp_servicename(snum)) ^
1924 (str_checksum(local_machine)<<16));
1926 len = srvstr_push(outbuf, pdata+18, vname, -1, STR_UNICODE);
1927 SIVAL(pdata,12,len);
1929 DEBUG(5,("call_trans2qfsinfo : SMB_QUERY_FS_VOLUME_INFO namelen = %d, vol=%s serv=%s\n",
1930 (int)strlen(vname),vname, lp_servicename(snum)));
1933 case SMB_QUERY_FS_SIZE_INFO:
1934 case SMB_FS_SIZE_INFORMATION:
1936 SMB_BIG_UINT dfree,dsize,bsize,block_size,sectors_per_unit,bytes_per_sector;
1938 SMB_VFS_DISK_FREE(conn,".",False,&bsize,&dfree,&dsize);
1939 block_size = lp_block_size(snum);
1940 if (bsize < block_size) {
1941 SMB_BIG_UINT factor = block_size/bsize;
1946 if (bsize > block_size) {
1947 SMB_BIG_UINT factor = bsize/block_size;
1952 bytes_per_sector = 512;
1953 sectors_per_unit = bsize/bytes_per_sector;
1954 DEBUG(5,("call_trans2qfsinfo : SMB_QUERY_FS_SIZE_INFO bsize=%u, cSectorUnit=%u, \
1955 cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize, (unsigned int)sectors_per_unit,
1956 (unsigned int)bytes_per_sector, (unsigned int)dsize, (unsigned int)dfree));
1957 SBIG_UINT(pdata,0,dsize);
1958 SBIG_UINT(pdata,8,dfree);
1959 SIVAL(pdata,16,sectors_per_unit);
1960 SIVAL(pdata,20,bytes_per_sector);
1964 case SMB_FS_FULL_SIZE_INFORMATION:
1966 SMB_BIG_UINT dfree,dsize,bsize,block_size,sectors_per_unit,bytes_per_sector;
1968 SMB_VFS_DISK_FREE(conn,".",False,&bsize,&dfree,&dsize);
1969 block_size = lp_block_size(snum);
1970 if (bsize < block_size) {
1971 SMB_BIG_UINT factor = block_size/bsize;
1976 if (bsize > block_size) {
1977 SMB_BIG_UINT factor = bsize/block_size;
1982 bytes_per_sector = 512;
1983 sectors_per_unit = bsize/bytes_per_sector;
1984 DEBUG(5,("call_trans2qfsinfo : SMB_QUERY_FS_FULL_SIZE_INFO bsize=%u, cSectorUnit=%u, \
1985 cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize, (unsigned int)sectors_per_unit,
1986 (unsigned int)bytes_per_sector, (unsigned int)dsize, (unsigned int)dfree));
1987 SBIG_UINT(pdata,0,dsize); /* Total Allocation units. */
1988 SBIG_UINT(pdata,8,dfree); /* Caller available allocation units. */
1989 SBIG_UINT(pdata,16,dfree); /* Actual available allocation units. */
1990 SIVAL(pdata,24,sectors_per_unit); /* Sectors per allocation unit. */
1991 SIVAL(pdata,28,bytes_per_sector); /* Bytes per sector. */
1995 case SMB_QUERY_FS_DEVICE_INFO:
1996 case SMB_FS_DEVICE_INFORMATION:
1998 SIVAL(pdata,0,0); /* dev type */
1999 SIVAL(pdata,4,0); /* characteristics */
2002 #ifdef HAVE_SYS_QUOTAS
2003 case SMB_FS_QUOTA_INFORMATION:
2005 * what we have to send --metze:
2007 * Unknown1: 24 NULL bytes
2008 * Soft Quota Treshold: 8 bytes seems like SMB_BIG_UINT or so
2009 * Hard Quota Limit: 8 bytes seems like SMB_BIG_UINT or so
2010 * Quota Flags: 2 byte :
2011 * Unknown3: 6 NULL bytes
2015 * details for Quota Flags:
2017 * 0x0020 Log Limit: log if the user exceeds his Hard Quota
2018 * 0x0010 Log Warn: log if the user exceeds his Soft Quota
2019 * 0x0002 Deny Disk: deny disk access when the user exceeds his Hard Quota
2020 * 0x0001 Enable Quotas: enable quota for this fs
2024 /* we need to fake up a fsp here,
2025 * because its not send in this call
2028 SMB_NTQUOTA_STRUCT quotas;
2031 ZERO_STRUCT(quotas);
2038 if (current_user.uid != 0) {
2039 DEBUG(0,("set_user_quota: access_denied service [%s] user [%s]\n",
2040 lp_servicename(SNUM(conn)),conn->user));
2041 return ERROR_DOS(ERRDOS,ERRnoaccess);
2044 if (vfs_get_ntquota(&fsp, SMB_USER_FS_QUOTA_TYPE, NULL, "as)!=0) {
2045 DEBUG(0,("vfs_get_ntquota() failed for service [%s]\n",lp_servicename(SNUM(conn))));
2046 return ERROR_DOS(ERRSRV,ERRerror);
2051 DEBUG(10,("SMB_FS_QUOTA_INFORMATION: for service [%s]\n",lp_servicename(SNUM(conn))));
2053 /* Unknown1 24 NULL bytes*/
2054 SBIG_UINT(pdata,0,(SMB_BIG_UINT)0);
2055 SBIG_UINT(pdata,8,(SMB_BIG_UINT)0);
2056 SBIG_UINT(pdata,16,(SMB_BIG_UINT)0);
2058 /* Default Soft Quota 8 bytes */
2059 SBIG_UINT(pdata,24,quotas.softlim);
2061 /* Default Hard Quota 8 bytes */
2062 SBIG_UINT(pdata,32,quotas.hardlim);
2064 /* Quota flag 2 bytes */
2065 SSVAL(pdata,40,quotas.qflags);
2067 /* Unknown3 6 NULL bytes */
2073 #endif /* HAVE_SYS_QUOTAS */
2074 case SMB_FS_OBJECTID_INFORMATION:
2079 * Query the version and capabilities of the CIFS UNIX extensions
2083 case SMB_QUERY_CIFS_UNIX_INFO:
2084 if (!lp_unix_extensions())
2085 return ERROR_DOS(ERRDOS,ERRunknownlevel);
2087 SSVAL(pdata,0,CIFS_UNIX_MAJOR_VERSION);
2088 SSVAL(pdata,2,CIFS_UNIX_MINOR_VERSION);
2089 SBIG_UINT(pdata,4,((SMB_BIG_UINT)CIFS_UNIX_POSIX_ACLS_CAP)); /* We have POSIX ACLs. */
2092 case SMB_MAC_QUERY_FS_INFO:
2094 * Thursby MAC extension... ONLY on NTFS filesystems
2095 * once we do streams then we don't need this
2097 if (strequal(lp_fstype(SNUM(conn)),"NTFS")) {
2099 SIVAL(pdata,84,0x100); /* Don't support mac... */
2104 return ERROR_DOS(ERRDOS,ERRunknownlevel);
2108 send_trans2_replies( outbuf, bufsize, params, 0, pdata, data_len);
2110 DEBUG( 4, ( "%s info_level = %d\n", smb_fn_name(CVAL(inbuf,smb_com)), info_level) );
2115 #ifdef HAVE_SYS_QUOTAS
2116 /****************************************************************************
2117 Reply to a TRANS2_SETFSINFO (set filesystem info).
2118 ****************************************************************************/
2120 static int call_trans2setfsinfo(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize,
2121 char **pparams, int total_params, char **ppdata, int total_data,
2122 unsigned int max_data_bytes)
2124 char *pdata = *ppdata;
2125 char *params = *pparams;
2126 files_struct *fsp = NULL;
2129 SMB_NTQUOTA_STRUCT quotas;
2131 ZERO_STRUCT(quotas);
2133 DEBUG(10,("call_trans2setfsinfo: SET_FS_QUOTA: for service [%s]\n",lp_servicename(SNUM(conn))));
2136 if ((current_user.uid != 0)||!CAN_WRITE(conn)) {
2137 DEBUG(0,("set_user_quota: access_denied service [%s] user [%s]\n",
2138 lp_servicename(SNUM(conn)),conn->user));
2139 return ERROR_DOS(ERRSRV,ERRaccess);
2143 if (total_params < 4) {
2144 DEBUG(0,("call_trans2setfsinfo: requires total_params(%d) >= 4 bytes!\n",
2146 return ERROR_DOS(ERRDOS,ERRinvalidparam);
2149 fsp = file_fsp(params,0);
2151 if (!CHECK_NTQUOTA_HANDLE_OK(fsp,conn)) {
2152 DEBUG(3,("TRANSACT_GET_USER_QUOTA: no valid QUOTA HANDLE\n"));
2153 return ERROR_NT(NT_STATUS_INVALID_HANDLE);
2156 info_level = SVAL(params,2);
2158 switch(info_level) {
2159 case SMB_FS_QUOTA_INFORMATION:
2160 /* note: normaly there're 48 bytes,
2161 * but we didn't use the last 6 bytes for now
2164 if (total_data < 42) {
2165 DEBUG(0,("call_trans2setfsinfo: SET_FS_QUOTA: requires total_data(%d) >= 42 bytes!\n",
2167 return ERROR_DOS(ERRDOS,ERRunknownlevel);
2170 /* unknown_1 24 NULL bytes in pdata*/
2172 /* the soft quotas 8 bytes (SMB_BIG_UINT)*/
2173 quotas.softlim = (SMB_BIG_UINT)IVAL(pdata,24);
2174 #ifdef LARGE_SMB_OFF_T
2175 quotas.softlim |= (((SMB_BIG_UINT)IVAL(pdata,28)) << 32);
2176 #else /* LARGE_SMB_OFF_T */
2177 if ((IVAL(pdata,28) != 0)&&
2178 ((quotas.softlim != 0xFFFFFFFF)||
2179 (IVAL(pdata,28)!=0xFFFFFFFF))) {
2180 /* more than 32 bits? */
2181 return ERROR_DOS(ERRDOS,ERRunknownlevel);
2183 #endif /* LARGE_SMB_OFF_T */
2185 /* the hard quotas 8 bytes (SMB_BIG_UINT)*/
2186 quotas.hardlim = (SMB_BIG_UINT)IVAL(pdata,32);
2187 #ifdef LARGE_SMB_OFF_T
2188 quotas.hardlim |= (((SMB_BIG_UINT)IVAL(pdata,36)) << 32);
2189 #else /* LARGE_SMB_OFF_T */
2190 if ((IVAL(pdata,36) != 0)&&
2191 ((quotas.hardlim != 0xFFFFFFFF)||
2192 (IVAL(pdata,36)!=0xFFFFFFFF))) {
2193 /* more than 32 bits? */
2194 return ERROR_DOS(ERRDOS,ERRunknownlevel);
2196 #endif /* LARGE_SMB_OFF_T */
2198 /* quota_flags 2 bytes **/
2199 quotas.qflags = SVAL(pdata,40);
2201 /* unknown_2 6 NULL bytes follow*/
2203 /* now set the quotas */
2204 if (vfs_set_ntquota(fsp, SMB_USER_FS_QUOTA_TYPE, NULL, "as)!=0) {
2205 DEBUG(0,("vfs_set_ntquota() failed for service [%s]\n",lp_servicename(SNUM(conn))));
2206 return ERROR_DOS(ERRSRV,ERRerror);
2211 DEBUG(3,("call_trans2setfsinfo: unknown level (0x%X) not implemented yet.\n",
2213 return ERROR_DOS(ERRDOS,ERRunknownlevel);
2218 * sending this reply works fine,
2219 * but I'm not sure it's the same
2220 * like windows do...
2223 outsize = set_message(outbuf,10,0,True);
2227 #endif /* HAVE_SYS_QUOTAS */
2229 /****************************************************************************
2230 Utility function to set bad path error.
2231 ****************************************************************************/
2233 int set_bad_path_error(int err, BOOL bad_path, char *outbuf, int def_class, uint32 def_code)
2235 DEBUG(10,("set_bad_path_error: err = %d bad_path = %d\n",
2236 err, (int)bad_path ));
2240 return ERROR_NT(NT_STATUS_OBJECT_PATH_NOT_FOUND);
2242 return ERROR_NT(NT_STATUS_OBJECT_NAME_NOT_FOUND);
2245 return UNIXERROR(def_class,def_code);
2248 /****************************************************************************
2249 Utility function to count the number of entries in a POSIX acl.
2250 ****************************************************************************/
2252 static unsigned int count_acl_entries(connection_struct *conn, SMB_ACL_T posix_acl)
2254 unsigned int ace_count = 0;
2255 int entry_id = SMB_ACL_FIRST_ENTRY;
2256 SMB_ACL_ENTRY_T entry;
2258 while ( posix_acl && (SMB_VFS_SYS_ACL_GET_ENTRY(conn, posix_acl, entry_id, &entry) == 1)) {
2260 if (entry_id == SMB_ACL_FIRST_ENTRY) {
2261 entry_id = SMB_ACL_NEXT_ENTRY;
2268 /****************************************************************************
2269 Utility function to marshall a POSIX acl into wire format.
2270 ****************************************************************************/
2272 static BOOL marshall_posix_acl(connection_struct *conn, char *pdata, SMB_STRUCT_STAT *pst, SMB_ACL_T posix_acl)
2274 int entry_id = SMB_ACL_FIRST_ENTRY;
2275 SMB_ACL_ENTRY_T entry;
2277 while ( posix_acl && (SMB_VFS_SYS_ACL_GET_ENTRY(conn, posix_acl, entry_id, &entry) == 1)) {
2278 SMB_ACL_TAG_T tagtype;
2279 SMB_ACL_PERMSET_T permset;
2280 unsigned char perms = 0;
2281 unsigned int own_grp;
2284 if (entry_id == SMB_ACL_FIRST_ENTRY) {
2285 entry_id = SMB_ACL_NEXT_ENTRY;
2288 if (SMB_VFS_SYS_ACL_GET_TAG_TYPE(conn, entry, &tagtype) == -1) {
2289 DEBUG(0,("marshall_posix_acl: SMB_VFS_SYS_ACL_GET_TAG_TYPE failed.\n"));
2293 if (SMB_VFS_SYS_ACL_GET_PERMSET(conn, entry, &permset) == -1) {
2294 DEBUG(0,("marshall_posix_acl: SMB_VFS_SYS_ACL_GET_PERMSET failed.\n"));
2298 perms |= (SMB_VFS_SYS_ACL_GET_PERM(conn, permset, SMB_ACL_READ) ? SMB_POSIX_ACL_READ : 0);
2299 perms |= (SMB_VFS_SYS_ACL_GET_PERM(conn, permset, SMB_ACL_WRITE) ? SMB_POSIX_ACL_WRITE : 0);
2300 perms |= (SMB_VFS_SYS_ACL_GET_PERM(conn, permset, SMB_ACL_EXECUTE) ? SMB_POSIX_ACL_EXECUTE : 0);
2302 SCVAL(pdata,1,perms);
2305 case SMB_ACL_USER_OBJ:
2306 SCVAL(pdata,0,SMB_POSIX_ACL_USER_OBJ);
2307 own_grp = (unsigned int)pst->st_uid;
2308 SIVAL(pdata,2,own_grp);
2313 uid_t *puid = (uid_t *)SMB_VFS_SYS_ACL_GET_QUALIFIER(conn, entry);
2315 DEBUG(0,("marshall_posix_acl: SMB_VFS_SYS_ACL_GET_QUALIFIER failed.\n"));
2317 own_grp = (unsigned int)*puid;
2318 SMB_VFS_SYS_ACL_FREE_QUALIFIER(conn, (void *)puid,tagtype);
2319 SCVAL(pdata,0,SMB_POSIX_ACL_USER);
2320 SIVAL(pdata,2,own_grp);
2324 case SMB_ACL_GROUP_OBJ:
2325 SCVAL(pdata,0,SMB_POSIX_ACL_GROUP_OBJ);
2326 own_grp = (unsigned int)pst->st_gid;
2327 SIVAL(pdata,2,own_grp);
2332 gid_t *pgid= (gid_t *)SMB_VFS_SYS_ACL_GET_QUALIFIER(conn, entry);
2334 DEBUG(0,("marshall_posix_acl: SMB_VFS_SYS_ACL_GET_QUALIFIER failed.\n"));
2336 own_grp = (unsigned int)*pgid;
2337 SMB_VFS_SYS_ACL_FREE_QUALIFIER(conn, (void *)pgid,tagtype);
2338 SCVAL(pdata,0,SMB_POSIX_ACL_GROUP);
2339 SIVAL(pdata,2,own_grp);
2344 SCVAL(pdata,0,SMB_POSIX_ACL_MASK);
2345 SIVAL(pdata,2,0xFFFFFFFF);
2346 SIVAL(pdata,6,0xFFFFFFFF);
2349 SCVAL(pdata,0,SMB_POSIX_ACL_OTHER);
2350 SIVAL(pdata,2,0xFFFFFFFF);
2351 SIVAL(pdata,6,0xFFFFFFFF);
2354 DEBUG(0,("marshall_posix_acl: unknown tagtype.\n"));
2362 /****************************************************************************
2363 Reply to a TRANS2_QFILEPATHINFO or TRANSACT2_QFILEINFO (query file info by
2364 file name or file id).
2365 ****************************************************************************/
2367 static int call_trans2qfilepathinfo(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize,
2368 char **pparams, int total_params, char **ppdata, int total_data,
2369 unsigned int max_data_bytes)
2371 char *params = *pparams;
2372 char *pdata = *ppdata;
2373 uint16 tran_call = SVAL(inbuf, smb_setup0);
2376 SMB_OFF_T file_size=0;
2377 SMB_BIG_UINT allocation_size=0;
2378 unsigned int data_size;
2379 unsigned int param_size = 2;
2380 SMB_STRUCT_STAT sbuf;
2381 pstring fname, dos_fname;
2386 BOOL bad_path = False;
2387 BOOL delete_pending = False;
2390 files_struct *fsp = NULL;
2391 uint32 desired_access = 0x12019F; /* Default - GENERIC_EXECUTE mapping from Windows */
2394 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
2398 if (tran_call == TRANSACT2_QFILEINFO) {
2399 if (total_params < 4)
2400 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
2402 fsp = file_fsp(params,0);
2403 info_level = SVAL(params,2);
2405 DEBUG(3,("call_trans2qfilepathinfo: TRANSACT2_QFILEINFO: level = %d\n", info_level));
2407 if(fsp && (fsp->fake_file_handle)) {
2409 * This is actually for the QUOTA_FAKE_FILE --metze
2412 pstrcpy(fname, fsp->fsp_name);
2413 /* We know this name is ok, it's already passed the checks. */
2415 } else if(fsp && (fsp->is_directory || fsp->fd == -1)) {
2417 * This is actually a QFILEINFO on a directory
2418 * handle (returned from an NT SMB). NT5.0 seems
2419 * to do this call. JRA.
2421 /* We know this name is ok, it's already passed the checks. */
2422 pstrcpy(fname, fsp->fsp_name);
2424 if (INFO_LEVEL_IS_UNIX(info_level)) {
2425 /* Always do lstat for UNIX calls. */
2426 if (SMB_VFS_LSTAT(conn,fname,&sbuf)) {
2427 DEBUG(3,("call_trans2qfilepathinfo: SMB_VFS_LSTAT of %s failed (%s)\n",fname,strerror(errno)));
2428 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRbadpath);
2430 } else if (SMB_VFS_STAT(conn,fname,&sbuf)) {
2431 DEBUG(3,("call_trans2qfilepathinfo: SMB_VFS_STAT of %s failed (%s)\n",fname,strerror(errno)));
2432 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRbadpath);
2435 delete_pending = fsp->is_directory ? fsp->directory_delete_on_close : 0;
2438 * Original code - this is an open file.
2440 CHECK_FSP(fsp,conn);
2442 pstrcpy(fname, fsp->fsp_name);
2443 if (SMB_VFS_FSTAT(fsp,fsp->fd,&sbuf) != 0) {
2444 DEBUG(3,("fstat of fnum %d failed (%s)\n", fsp->fnum, strerror(errno)));
2445 return(UNIXERROR(ERRDOS,ERRbadfid));
2447 pos = fsp->position_information;
2448 delete_pending = fsp->delete_on_close;
2449 desired_access = fsp->desired_access;
2452 NTSTATUS status = NT_STATUS_OK;
2455 if (total_params < 6)
2456 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
2458 info_level = SVAL(params,0);
2460 DEBUG(3,("call_trans2qfilepathinfo: TRANSACT2_QPATHINFO: level = %d\n", info_level));
2462 srvstr_get_path(inbuf, fname, ¶ms[6], sizeof(fname), -1, STR_TERMINATE, &status, False);
2463 if (!NT_STATUS_IS_OK(status)) {
2464 return ERROR_NT(status);
2467 RESOLVE_DFSPATH(fname, conn, inbuf, outbuf);
2469 unix_convert(fname,conn,0,&bad_path,&sbuf);
2471 return ERROR_NT(NT_STATUS_OBJECT_PATH_NOT_FOUND);
2473 if (!check_name(fname,conn)) {
2474 DEBUG(3,("call_trans2qfilepathinfo: fileinfo of %s failed (%s)\n",fname,strerror(errno)));
2475 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRbadpath);
2478 if (INFO_LEVEL_IS_UNIX(info_level)) {
2479 /* Always do lstat for UNIX calls. */
2480 if (SMB_VFS_LSTAT(conn,fname,&sbuf)) {
2481 DEBUG(3,("call_trans2qfilepathinfo: SMB_VFS_LSTAT of %s failed (%s)\n",fname,strerror(errno)));
2482 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRbadpath);
2484 } else if (!VALID_STAT(sbuf) && SMB_VFS_STAT(conn,fname,&sbuf) && (info_level != SMB_INFO_IS_NAME_VALID)) {
2485 DEBUG(3,("call_trans2qfilepathinfo: SMB_VFS_STAT of %s failed (%s)\n",fname,strerror(errno)));
2486 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRbadpath);
2490 if (INFO_LEVEL_IS_UNIX(info_level) && !lp_unix_extensions())
2491 return ERROR_DOS(ERRDOS,ERRunknownlevel);
2493 DEBUG(3,("call_trans2qfilepathinfo %s (fnum = %d) level=%d call=%d total_data=%d\n",
2494 fname,fsp ? fsp->fnum : -1, info_level,tran_call,total_data));
2496 p = strrchr_m(fname,'/');
2502 mode = dos_mode(conn,fname,&sbuf);
2504 mode = FILE_ATTRIBUTE_NORMAL;
2506 fullpathname = fname;
2507 file_size = get_file_size(sbuf);
2508 allocation_size = get_allocation_size(fsp,&sbuf);
2512 params = Realloc(*pparams,2);
2514 return ERROR_DOS(ERRDOS,ERRnomem);
2516 memset((char *)params,'\0',2);
2517 data_size = max_data_bytes + DIR_ENTRY_SAFETY_MARGIN;
2518 pdata = Realloc(*ppdata, data_size);
2519 if ( pdata == NULL )
2520 return ERROR_DOS(ERRDOS,ERRnomem);
2523 if (total_data > 0 && IVAL(pdata,0) == total_data) {
2524 /* uggh, EAs for OS2 */
2525 DEBUG(4,("Rejecting EA request with total_data=%d\n",total_data));
2526 return ERROR_DOS(ERRDOS,ERReasnotsupported);
2529 memset((char *)pdata,'\0',data_size);
2531 c_time = get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(conn)));
2533 if (lp_dos_filetime_resolution(SNUM(conn))) {
2535 sbuf.st_atime &= ~1;
2536 sbuf.st_ctime &= ~1;
2537 sbuf.st_mtime &= ~1;
2540 /* NT expects the name to be in an exact form of the *full*
2541 filename. See the trans2 torture test */
2542 if (strequal(base_name,".")) {
2543 pstrcpy(dos_fname, "\\");
2545 pstr_sprintf(dos_fname, "\\%s", fname);
2546 string_replace(dos_fname, '/', '\\');
2549 switch (info_level) {
2550 case SMB_INFO_STANDARD:
2551 DEBUG(10,("call_trans2qfilepathinfo: SMB_INFO_STANDARD\n"));
2553 put_dos_date2(pdata,l1_fdateCreation,c_time);
2554 put_dos_date2(pdata,l1_fdateLastAccess,sbuf.st_atime);
2555 put_dos_date2(pdata,l1_fdateLastWrite,sbuf.st_mtime); /* write time */
2556 SIVAL(pdata,l1_cbFile,(uint32)file_size);
2557 SIVAL(pdata,l1_cbFileAlloc,(uint32)allocation_size);
2558 SSVAL(pdata,l1_attrFile,mode);
2561 case SMB_INFO_QUERY_EA_SIZE:
2563 unsigned int ea_size = estimate_ea_size(conn, fsp, fname);
2564 DEBUG(10,("call_trans2qfilepathinfo: SMB_INFO_QUERY_EA_SIZE\n"));
2566 put_dos_date2(pdata,l1_fdateCreation,c_time);
2567 put_dos_date2(pdata,l1_fdateLastAccess,sbuf.st_atime);
2568 put_dos_date2(pdata,l1_fdateLastWrite,sbuf.st_mtime); /* write time */
2569 SIVAL(pdata,l1_cbFile,(uint32)file_size);
2570 SIVAL(pdata,l1_cbFileAlloc,(uint32)allocation_size);
2571 SSVAL(pdata,l1_attrFile,mode);
2572 SIVAL(pdata,l1_attrFile+2,ea_size);
2576 case SMB_INFO_IS_NAME_VALID:
2577 DEBUG(10,("call_trans2qfilepathinfo: SMB_INFO_IS_NAME_VALID\n"));
2578 if (tran_call == TRANSACT2_QFILEINFO) {
2579 /* os/2 needs this ? really ?*/
2580 return ERROR_DOS(ERRDOS,ERRbadfunc);
2586 case SMB_INFO_QUERY_EAS_FROM_LIST:
2587 DEBUG(10,("call_trans2qfilepathinfo: SMB_INFO_QUERY_EAS_FROM_LIST\n"));
2589 put_dos_date2(pdata,0,c_time);
2590 put_dos_date2(pdata,4,sbuf.st_atime);
2591 put_dos_date2(pdata,8,sbuf.st_mtime);
2592 SIVAL(pdata,12,(uint32)file_size);
2593 SIVAL(pdata,16,(uint32)allocation_size);
2594 SIVAL(pdata,20,mode);
2597 case SMB_INFO_QUERY_ALL_EAS:
2598 DEBUG(10,("call_trans2qfilepathinfo: SMB_INFO_QUERY_ALL_EAS\n"));
2599 /* We have data_size bytes to put EA's into. */
2600 data_size = fill_ea_buffer(pdata, data_size, conn, fsp, fname);
2603 case SMB_FILE_BASIC_INFORMATION:
2604 case SMB_QUERY_FILE_BASIC_INFO:
2606 if (info_level == SMB_QUERY_FILE_BASIC_INFO) {
2607 DEBUG(10,("call_trans2qfilepathinfo: SMB_QUERY_FILE_BASIC_INFO\n"));
2608 data_size = 36; /* w95 returns 40 bytes not 36 - why ?. */
2610 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_BASIC_INFORMATION\n"));
2614 put_long_date(pdata,c_time);
2615 put_long_date(pdata+8,sbuf.st_atime);
2616 put_long_date(pdata+16,sbuf.st_mtime); /* write time */
2617 put_long_date(pdata+24,sbuf.st_mtime); /* change time */
2618 SIVAL(pdata,32,mode);
2620 DEBUG(5,("SMB_QFBI - "));
2622 time_t create_time = c_time;
2623 DEBUG(5,("create: %s ", ctime(&create_time)));
2625 DEBUG(5,("access: %s ", ctime(&sbuf.st_atime)));
2626 DEBUG(5,("write: %s ", ctime(&sbuf.st_mtime)));
2627 DEBUG(5,("change: %s ", ctime(&sbuf.st_mtime)));
2628 DEBUG(5,("mode: %x\n", mode));
2632 case SMB_FILE_STANDARD_INFORMATION:
2633 case SMB_QUERY_FILE_STANDARD_INFO:
2635 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_STANDARD_INFORMATION\n"));
2637 SOFF_T(pdata,0,allocation_size);
2638 SOFF_T(pdata,8,file_size);
2639 if (delete_pending & sbuf.st_nlink)
2640 SIVAL(pdata,16,sbuf.st_nlink - 1);
2642 SIVAL(pdata,16,sbuf.st_nlink);
2644 SCVAL(pdata,21,(mode&aDIR)?1:0);
2647 case SMB_FILE_EA_INFORMATION:
2648 case SMB_QUERY_FILE_EA_INFO:
2650 unsigned int ea_size = estimate_ea_size(conn, fsp, fname);
2651 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_EA_INFORMATION\n"));
2653 SIVAL(pdata,0,ea_size);
2657 /* Get the 8.3 name - used if NT SMB was negotiated. */
2658 case SMB_QUERY_FILE_ALT_NAME_INFO:
2659 case SMB_FILE_ALTERNATE_NAME_INFORMATION:
2663 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_ALTERNATE_NAME_INFORMATION\n"));
2664 pstrcpy(short_name,base_name);
2665 /* Mangle if not already 8.3 */
2666 if(!mangle_is_8_3(short_name, True)) {
2667 mangle_map(short_name,True,True,SNUM(conn));
2669 len = srvstr_push(outbuf, pdata+4, short_name, -1, STR_UNICODE);
2670 data_size = 4 + len;
2675 case SMB_QUERY_FILE_NAME_INFO:
2677 this must be *exactly* right for ACLs on mapped drives to work
2679 len = srvstr_push(outbuf, pdata+4, dos_fname, -1, STR_UNICODE);
2680 DEBUG(10,("call_trans2qfilepathinfo: SMB_QUERY_FILE_NAME_INFO\n"));
2681 data_size = 4 + len;
2685 case SMB_FILE_ALLOCATION_INFORMATION:
2686 case SMB_QUERY_FILE_ALLOCATION_INFO:
2687 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_ALLOCATION_INFORMATION\n"));
2689 SOFF_T(pdata,0,allocation_size);
2692 case SMB_FILE_END_OF_FILE_INFORMATION:
2693 case SMB_QUERY_FILE_END_OF_FILEINFO:
2694 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_END_OF_FILE_INFORMATION\n"));
2696 SOFF_T(pdata,0,file_size);
2699 case SMB_QUERY_FILE_ALL_INFO:
2700 case SMB_FILE_ALL_INFORMATION:
2702 unsigned int ea_size = estimate_ea_size(conn, fsp, fname);
2703 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_ALL_INFORMATION\n"));
2704 put_long_date(pdata,c_time);
2705 put_long_date(pdata+8,sbuf.st_atime);
2706 put_long_date(pdata+16,sbuf.st_mtime); /* write time */
2707 put_long_date(pdata+24,sbuf.st_mtime); /* change time */
2708 SIVAL(pdata,32,mode);
2710 SOFF_T(pdata,0,allocation_size);
2711 SOFF_T(pdata,8,file_size);
2712 if (delete_pending && sbuf.st_nlink)
2713 SIVAL(pdata,16,sbuf.st_nlink - 1);
2715 SIVAL(pdata,16,sbuf.st_nlink);
2716 SCVAL(pdata,20,delete_pending);
2717 SCVAL(pdata,21,(mode&aDIR)?1:0);
2719 SIVAL(pdata,0,ea_size);
2720 pdata += 4; /* EA info */
2721 len = srvstr_push(outbuf, pdata+4, dos_fname, -1, STR_UNICODE);
2724 data_size = PTR_DIFF(pdata,(*ppdata));
2727 case SMB_FILE_INTERNAL_INFORMATION:
2728 /* This should be an index number - looks like
2731 I think this causes us to fail the IFSKIT
2732 BasicFileInformationTest. -tpot */
2734 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_INTERNAL_INFORMATION\n"));
2735 SIVAL(pdata,0,sbuf.st_dev);
2736 SIVAL(pdata,4,sbuf.st_ino);
2740 case SMB_FILE_ACCESS_INFORMATION:
2741 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_ACCESS_INFORMATION\n"));
2742 SIVAL(pdata,0,desired_access);
2746 case SMB_FILE_NAME_INFORMATION:
2747 /* Pathname with leading '\'. */
2750 byte_len = dos_PutUniCode(pdata+4,dos_fname,max_data_bytes,False);
2751 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_NAME_INFORMATION\n"));
2752 SIVAL(pdata,0,byte_len);
2753 data_size = 4 + byte_len;
2757 case SMB_FILE_DISPOSITION_INFORMATION:
2758 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_DISPOSITION_INFORMATION\n"));
2760 SCVAL(pdata,0,delete_pending);
2763 case SMB_FILE_POSITION_INFORMATION:
2764 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_POSITION_INFORMATION\n"));
2766 SOFF_T(pdata,0,pos);
2769 case SMB_FILE_MODE_INFORMATION:
2770 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_MODE_INFORMATION\n"));
2771 SIVAL(pdata,0,mode);
2775 case SMB_FILE_ALIGNMENT_INFORMATION:
2776 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_ALIGNMENT_INFORMATION\n"));
2777 SIVAL(pdata,0,0); /* No alignment needed. */
2783 * NT4 server just returns "invalid query" to this - if we try to answer
2784 * it then NTws gets a BSOD! (tridge).
2785 * W2K seems to want this. JRA.
2787 case SMB_QUERY_FILE_STREAM_INFO:
2789 case SMB_FILE_STREAM_INFORMATION:
2790 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_STREAM_INFORMATION\n"));
2794 size_t byte_len = dos_PutUniCode(pdata+24,"::$DATA", 0xE, False);
2795 SIVAL(pdata,0,0); /* ??? */
2796 SIVAL(pdata,4,byte_len); /* Byte length of unicode string ::$DATA */
2797 SOFF_T(pdata,8,file_size);
2798 SIVAL(pdata,16,allocation_size);
2799 SIVAL(pdata,20,0); /* ??? */
2800 data_size = 24 + byte_len;
2804 case SMB_QUERY_COMPRESSION_INFO:
2805 case SMB_FILE_COMPRESSION_INFORMATION:
2806 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_COMPRESSION_INFORMATION\n"));
2807 SOFF_T(pdata,0,file_size);
2808 SIVAL(pdata,8,0); /* ??? */
2809 SIVAL(pdata,12,0); /* ??? */
2813 case SMB_FILE_NETWORK_OPEN_INFORMATION:
2814 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_NETWORK_OPEN_INFORMATION\n"));
2815 put_long_date(pdata,c_time);
2816 put_long_date(pdata+8,sbuf.st_atime);
2817 put_long_date(pdata+16,sbuf.st_mtime); /* write time */
2818 put_long_date(pdata+24,sbuf.st_mtime); /* change time */
2819 SIVAL(pdata,32,allocation_size);
2820 SOFF_T(pdata,40,file_size);
2821 SIVAL(pdata,48,mode);
2822 SIVAL(pdata,52,0); /* ??? */
2826 case SMB_FILE_ATTRIBUTE_TAG_INFORMATION:
2827 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_ATTRIBUTE_TAG_INFORMATION\n"));
2828 SIVAL(pdata,0,mode);
2834 * CIFS UNIX Extensions.
2837 case SMB_QUERY_FILE_UNIX_BASIC:
2839 DEBUG(10,("call_trans2qfilepathinfo: SMB_QUERY_FILE_UNIX_BASIC\n"));
2840 DEBUG(4,("call_trans2qfilepathinfo: st_mode=%o\n",(int)sbuf.st_mode));
2842 SOFF_T(pdata,0,get_file_size(sbuf)); /* File size 64 Bit */
2845 SOFF_T(pdata,0,get_allocation_size(fsp,&sbuf)); /* Number of bytes used on disk - 64 Bit */
2848 put_long_date(pdata,sbuf.st_ctime); /* Creation Time 64 Bit */
2849 put_long_date(pdata+8,sbuf.st_atime); /* Last access time 64 Bit */
2850 put_long_date(pdata+16,sbuf.st_mtime); /* Last modification time 64 Bit */
2853 SIVAL(pdata,0,sbuf.st_uid); /* user id for the owner */
2857 SIVAL(pdata,0,sbuf.st_gid); /* group id of owner */
2861 SIVAL(pdata,0,unix_filetype(sbuf.st_mode));
2864 SIVAL(pdata,0,unix_dev_major(sbuf.st_rdev)); /* Major device number if type is device */
2868 SIVAL(pdata,0,unix_dev_minor(sbuf.st_rdev)); /* Minor device number if type is device */
2872 SINO_T(pdata,0,(SMB_INO_T)sbuf.st_ino); /* inode number */
2875 SIVAL(pdata,0, unix_perms_to_wire(sbuf.st_mode)); /* Standard UNIX file permissions */
2879 SIVAL(pdata,0,sbuf.st_nlink); /* number of hard links */
2882 data_size = PTR_DIFF(pdata,(*ppdata));
2886 DEBUG(4,("call_trans2qfilepathinfo: SMB_QUERY_FILE_UNIX_BASIC"));
2888 for (i=0; i<100; i++)
2889 DEBUG(4,("%d=%x, ",i, (*ppdata)[i]));
2895 case SMB_QUERY_FILE_UNIX_LINK:
2899 DEBUG(10,("call_trans2qfilepathinfo: SMB_QUERY_FILE_UNIX_LINK\n"));
2901 if(!S_ISLNK(sbuf.st_mode))
2902 return(UNIXERROR(ERRSRV,ERRbadlink));
2904 return(UNIXERROR(ERRDOS,ERRbadlink));
2906 len = SMB_VFS_READLINK(conn,fullpathname, buffer, sizeof(pstring)-1); /* read link */
2908 return(UNIXERROR(ERRDOS,ERRnoaccess));
2910 len = srvstr_push(outbuf, pdata, buffer, -1, STR_TERMINATE);
2912 data_size = PTR_DIFF(pdata,(*ppdata));
2917 case SMB_QUERY_POSIX_ACL:
2919 SMB_ACL_T file_acl = NULL;
2920 SMB_ACL_T dir_acl = NULL;
2921 uint16 num_file_acls = 0;
2922 uint16 num_dir_acls = 0;
2924 if (fsp && !fsp->is_directory && (fsp->fd != -1)) {
2925 file_acl = SMB_VFS_SYS_ACL_GET_FD(fsp, fsp->fd);
2927 file_acl = SMB_VFS_SYS_ACL_GET_FILE(conn, fname, SMB_ACL_TYPE_ACCESS);
2930 if (file_acl == NULL && no_acl_syscall_error(errno)) {
2931 DEBUG(5,("call_trans2qfilepathinfo: ACLs not implemented on filesystem containing %s\n",
2933 return ERROR_NT(NT_STATUS_NOT_IMPLEMENTED);
2936 if (S_ISDIR(sbuf.st_mode)) {
2937 if (fsp && fsp->is_directory) {
2938 dir_acl = SMB_VFS_SYS_ACL_GET_FILE(conn, fsp->fsp_name, SMB_ACL_TYPE_DEFAULT);
2940 dir_acl = SMB_VFS_SYS_ACL_GET_FILE(conn, fname, SMB_ACL_TYPE_DEFAULT);
2942 dir_acl = free_empty_sys_acl(conn, dir_acl);
2945 num_file_acls = count_acl_entries(conn, file_acl);
2946 num_dir_acls = count_acl_entries(conn, dir_acl);
2948 if ( data_size < (num_file_acls + num_dir_acls)*SMB_POSIX_ACL_ENTRY_SIZE + SMB_POSIX_ACL_HEADER_SIZE) {
2949 DEBUG(5,("call_trans2qfilepathinfo: data_size too small (%u) need %u\n",
2951 (unsigned int)((num_file_acls + num_dir_acls)*SMB_POSIX_ACL_ENTRY_SIZE +
2952 SMB_POSIX_ACL_HEADER_SIZE) ));
2954 SMB_VFS_SYS_ACL_FREE_ACL(conn, file_acl);
2957 SMB_VFS_SYS_ACL_FREE_ACL(conn, dir_acl);
2959 return ERROR_NT(NT_STATUS_BUFFER_TOO_SMALL);
2962 SSVAL(pdata,0,SMB_POSIX_ACL_VERSION);
2963 SSVAL(pdata,2,num_file_acls);
2964 SSVAL(pdata,4,num_dir_acls);
2965 if (!marshall_posix_acl(conn, pdata + SMB_POSIX_ACL_HEADER_SIZE, &sbuf, file_acl)) {
2967 SMB_VFS_SYS_ACL_FREE_ACL(conn, file_acl);
2970 SMB_VFS_SYS_ACL_FREE_ACL(conn, dir_acl);
2972 return ERROR_NT(NT_STATUS_INTERNAL_ERROR);
2974 if (!marshall_posix_acl(conn, pdata + SMB_POSIX_ACL_HEADER_SIZE + (num_file_acls*SMB_POSIX_ACL_ENTRY_SIZE), &sbuf, dir_acl)) {
2976 SMB_VFS_SYS_ACL_FREE_ACL(conn, file_acl);
2979 SMB_VFS_SYS_ACL_FREE_ACL(conn, dir_acl);
2981 return ERROR_NT(NT_STATUS_INTERNAL_ERROR);
2985 SMB_VFS_SYS_ACL_FREE_ACL(conn, file_acl);
2988 SMB_VFS_SYS_ACL_FREE_ACL(conn, dir_acl);
2990 data_size = (num_file_acls + num_dir_acls)*SMB_POSIX_ACL_ENTRY_SIZE + SMB_POSIX_ACL_HEADER_SIZE;
2995 return ERROR_DOS(ERRDOS,ERRunknownlevel);
2998 send_trans2_replies(outbuf, bufsize, params, param_size, *ppdata, data_size);
3003 /****************************************************************************
3004 Deal with the internal needs of setting the delete on close flag. Note that
3005 as the tdb locking is recursive, it is safe to call this from within
3006 open_file_shared. JRA.
3007 ****************************************************************************/
3009 NTSTATUS set_delete_on_close_internal(files_struct *fsp, BOOL delete_on_close, uint32 dosmode)
3011 if (delete_on_close) {
3013 * Only allow delete on close for writable files.
3016 if (dosmode & aRONLY) {
3017 DEBUG(10,("set_delete_on_close_internal: file %s delete on close flag set but file attribute is readonly.\n",
3019 return NT_STATUS_CANNOT_DELETE;
3023 * Only allow delete on close for writable shares.
3026 if (!CAN_WRITE(fsp->conn)) {
3027 DEBUG(10,("set_delete_on_close_internal: file %s delete on close flag set but write access denied on share.\n",
3029 return NT_STATUS_ACCESS_DENIED;
3033 * Only allow delete on close for files/directories opened with delete intent.
3036 if (!(fsp->desired_access & DELETE_ACCESS)) {
3037 DEBUG(10,("set_delete_on_close_internal: file %s delete on close flag set but delete access denied.\n",
3039 return NT_STATUS_ACCESS_DENIED;
3043 if(fsp->is_directory) {
3044 fsp->directory_delete_on_close = delete_on_close;
3045 DEBUG(10, ("set_delete_on_close_internal: %s delete on close flag for fnum = %d, directory %s\n",
3046 delete_on_close ? "Added" : "Removed", fsp->fnum, fsp->fsp_name ));
3048 fsp->delete_on_close = delete_on_close;
3049 DEBUG(10, ("set_delete_on_close_internal: %s delete on close flag for fnum = %d, file %s\n",
3050 delete_on_close ? "Added" : "Removed", fsp->fnum, fsp->fsp_name ));
3053 return NT_STATUS_OK;
3056 /****************************************************************************
3057 Sets the delete on close flag over all share modes on this file.
3058 Modify the share mode entry for all files open
3059 on this device and inode to tell other smbds we have
3060 changed the delete on close flag. This will be noticed
3061 in the close code, the last closer will delete the file
3063 ****************************************************************************/
3065 NTSTATUS set_delete_on_close_over_all(files_struct *fsp, BOOL delete_on_close)
3067 DEBUG(10,("set_delete_on_close_over_all: %s delete on close flag for fnum = %d, file %s\n",
3068 delete_on_close ? "Adding" : "Removing", fsp->fnum, fsp->fsp_name ));
3070 if (fsp->is_directory || fsp->is_stat)
3071 return NT_STATUS_OK;
3073 if (lock_share_entry_fsp(fsp) == False)
3074 return NT_STATUS_ACCESS_DENIED;
3076 if (!modify_delete_flag(fsp->dev, fsp->inode, delete_on_close)) {
3077 DEBUG(0,("set_delete_on_close_over_all: failed to change delete on close flag for file %s\n",
3079 unlock_share_entry_fsp(fsp);
3080 return NT_STATUS_ACCESS_DENIED;
3083 unlock_share_entry_fsp(fsp);
3084 return NT_STATUS_OK;
3087 /****************************************************************************
3088 Set a hard link (called by UNIX extensions and by NT rename with HARD link
3090 ****************************************************************************/
3092 NTSTATUS hardlink_internals(connection_struct *conn, char *oldname, char *newname)
3094 BOOL bad_path_oldname = False;
3095 BOOL bad_path_newname = False;
3096 SMB_STRUCT_STAT sbuf1, sbuf2;
3097 pstring last_component_oldname;
3098 pstring last_component_newname;
3099 NTSTATUS status = NT_STATUS_OK;
3105 if (ms_has_wild(newname) || ms_has_wild(oldname)) {
3106 return NT_STATUS_OBJECT_PATH_SYNTAX_BAD;
3109 unix_convert(oldname,conn,last_component_oldname,&bad_path_oldname,&sbuf1);
3110 if (bad_path_oldname) {
3111 return NT_STATUS_OBJECT_PATH_NOT_FOUND;
3114 /* Quick check for "." and ".." */
3115 if (last_component_oldname[0] == '.') {
3116 if (!last_component_oldname[1] || (last_component_oldname[1] == '.' && !last_component_oldname[2])) {
3117 return NT_STATUS_OBJECT_NAME_INVALID;
3121 /* source must already exist. */
3122 if (!VALID_STAT(sbuf1)) {
3123 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3126 if (!check_name(oldname,conn)) {
3127 return NT_STATUS_ACCESS_DENIED;
3130 unix_convert(newname,conn,last_component_newname,&bad_path_newname,&sbuf2);
3131 if (bad_path_newname) {
3132 return NT_STATUS_OBJECT_PATH_NOT_FOUND;
3135 /* Quick check for "." and ".." */
3136 if (last_component_newname[0] == '.') {
3137 if (!last_component_newname[1] || (last_component_newname[1] == '.' && !last_component_newname[2])) {
3138 return NT_STATUS_OBJECT_NAME_INVALID;
3142 /* Disallow if newname already exists. */
3143 if (VALID_STAT(sbuf2)) {
3144 return NT_STATUS_OBJECT_NAME_COLLISION;
3147 if (!check_name(newname,conn)) {
3148 return NT_STATUS_ACCESS_DENIED;
3151 /* No links from a directory. */
3152 if (S_ISDIR(sbuf1.st_mode)) {
3153 return NT_STATUS_FILE_IS_A_DIRECTORY;
3156 /* Ensure this is within the share. */
3157 if (!reduce_name(conn, oldname) != 0)
3158 return NT_STATUS_ACCESS_DENIED;
3160 DEBUG(10,("hardlink_internals: doing hard link %s -> %s\n", newname, oldname ));
3162 if (SMB_VFS_LINK(conn,oldname,newname) != 0) {
3163 status = map_nt_error_from_unix(errno);
3164 DEBUG(3,("hardlink_internals: Error %s hard link %s -> %s\n",
3165 nt_errstr(status), newname, oldname));
3171 /****************************************************************************
3172 Reply to a TRANS2_SETFILEINFO (set file info by fileid).
3173 ****************************************************************************/
3175 static int call_trans2setfilepathinfo(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize,
3176 char **pparams, int total_params, char **ppdata, int total_data,
3177 unsigned int max_data_bytes)
3179 char *params = *pparams;
3180 char *pdata = *ppdata;
3181 uint16 tran_call = SVAL(inbuf, smb_setup0);
3186 SMB_STRUCT_STAT sbuf;
3189 BOOL bad_path = False;
3190 files_struct *fsp = NULL;
3191 uid_t set_owner = (uid_t)SMB_UID_NO_CHANGE;
3192 gid_t set_grp = (uid_t)SMB_GID_NO_CHANGE;
3193 mode_t unixmode = 0;
3194 NTSTATUS status = NT_STATUS_OK;
3197 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
3201 if (tran_call == TRANSACT2_SETFILEINFO) {
3202 if (total_params < 4)
3203 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
3205 fsp = file_fsp(params,0);
3206 info_level = SVAL(params,2);
3208 if(fsp && (fsp->is_directory || fsp->fd == -1)) {
3210 * This is actually a SETFILEINFO on a directory
3211 * handle (returned from an NT SMB). NT5.0 seems
3212 * to do this call. JRA.
3214 pstrcpy(fname, fsp->fsp_name);
3215 if (SMB_VFS_STAT(conn,fname,&sbuf) != 0) {
3216 DEBUG(3,("call_trans2setfilepathinfo: fileinfo of %s failed (%s)\n",fname,strerror(errno)));
3217 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRbadpath);
3219 } else if (fsp && fsp->print_file) {
3221 * Doing a DELETE_ON_CLOSE should cancel a print job.
3223 if ((info_level == SMB_SET_FILE_DISPOSITION_INFO) && CVAL(pdata,0)) {
3224 fsp->share_mode = FILE_DELETE_ON_CLOSE;
3226 DEBUG(3,("call_trans2setfilepathinfo: Cancelling print job (%s)\n", fsp->fsp_name ));
3229 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
3232 return (UNIXERROR(ERRDOS,ERRbadpath));
3235 * Original code - this is an open file.
3237 CHECK_FSP(fsp,conn);
3239 pstrcpy(fname, fsp->fsp_name);
3242 if (SMB_VFS_FSTAT(fsp,fd,&sbuf) != 0) {
3243 DEBUG(3,("call_trans2setfilepathinfo: fstat of fnum %d failed (%s)\n",fsp->fnum, strerror(errno)));
3244 return(UNIXERROR(ERRDOS,ERRbadfid));
3249 if (total_params < 6)
3250 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
3252 info_level = SVAL(params,0);
3253 srvstr_get_path(inbuf, fname, ¶ms[6], sizeof(fname), -1, STR_TERMINATE, &status, False);
3254 if (!NT_STATUS_IS_OK(status)) {
3255 return ERROR_NT(status);
3257 unix_convert(fname,conn,0,&bad_path,&sbuf);
3259 return ERROR_NT(NT_STATUS_OBJECT_PATH_NOT_FOUND);
3263 * For CIFS UNIX extensions the target name may not exist.
3266 if(!VALID_STAT(sbuf) && !INFO_LEVEL_IS_UNIX(info_level)) {
3267 DEBUG(3,("call_trans2setfilepathinfo: stat of %s failed (%s)\n", fname, strerror(errno)));
3268 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRbadpath);
3271 if(!check_name(fname, conn)) {
3272 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRbadpath);
3277 if (!CAN_WRITE(conn))
3278 return ERROR_DOS(ERRSRV,ERRaccess);
3280 if (INFO_LEVEL_IS_UNIX(info_level) && !lp_unix_extensions())
3281 return ERROR_DOS(ERRDOS,ERRunknownlevel);
3283 if (VALID_STAT(sbuf))
3284 unixmode = sbuf.st_mode;
3286 DEBUG(3,("call_trans2setfilepathinfo(%d) %s (fnum %d) info_level=%d totdata=%d\n",
3287 tran_call,fname, fsp ? fsp->fnum : -1, info_level,total_data));
3289 /* Realloc the parameter and data sizes */
3290 params = Realloc(*pparams,2);
3292 return ERROR_DOS(ERRDOS,ERRnomem);
3298 /* the pending modtime overrides the current modtime */
3299 sbuf.st_mtime = fsp->pending_modtime;
3302 size = get_file_size(sbuf);
3303 tvs.modtime = sbuf.st_mtime;
3304 tvs.actime = sbuf.st_atime;
3305 dosmode = dos_mode(conn,fname,&sbuf);
3306 unixmode = sbuf.st_mode;
3308 set_owner = VALID_STAT(sbuf) ? sbuf.st_uid : (uid_t)SMB_UID_NO_CHANGE;
3309 set_grp = VALID_STAT(sbuf) ? sbuf.st_gid : (gid_t)SMB_GID_NO_CHANGE;
3311 switch (info_level) {
3312 case SMB_INFO_STANDARD:
3314 if (total_data < 12)
3315 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
3318 tvs.actime = make_unix_date2(pdata+l1_fdateLastAccess);
3320 tvs.modtime = make_unix_date2(pdata+l1_fdateLastWrite);
3324 case SMB_INFO_SET_EA:
3325 status = set_ea(conn, fsp, fname, pdata, total_data);
3326 if (NT_STATUS_V(status) != NT_STATUS_V(NT_STATUS_OK))
3327 return ERROR_NT(status);
3330 /* XXXX um, i don't think this is right.
3331 it's also not in the cifs6.txt spec.
3333 case SMB_INFO_QUERY_EAS_FROM_LIST:
3334 if (total_data < 28)
3335 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
3337 tvs.actime = make_unix_date2(pdata+8);
3338 tvs.modtime = make_unix_date2(pdata+12);
3339 size = IVAL(pdata,16);
3340 dosmode = IVAL(pdata,24);
3343 /* XXXX nor this. not in cifs6.txt, either. */
3344 case SMB_INFO_QUERY_ALL_EAS:
3345 if (total_data < 28)
3346 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
3348 tvs.actime = make_unix_date2(pdata+8);
3349 tvs.modtime = make_unix_date2(pdata+12);
3350 size = IVAL(pdata,16);
3351 dosmode = IVAL(pdata,24);
3354 case SMB_SET_FILE_BASIC_INFO:
3355 case SMB_FILE_BASIC_INFORMATION:
3357 /* Patch to do this correctly from Paul Eggert <eggert@twinsun.com>. */
3359 time_t changed_time;
3361 if (total_data < 36)
3362 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
3364 /* Ignore create time at offset pdata. */
3367 tvs.actime = interpret_long_date(pdata+8);
3369 write_time = interpret_long_date(pdata+16);
3370 changed_time = interpret_long_date(pdata+24);
3372 tvs.modtime = MIN(write_time, changed_time);
3374 if (write_time > tvs.modtime && write_time != 0xffffffff) {
3375 tvs.modtime = write_time;
3377 /* Prefer a defined time to an undefined one. */
3378 if (tvs.modtime == (time_t)0 || tvs.modtime == (time_t)-1)
3379 tvs.modtime = (write_time == (time_t)0 || write_time == (time_t)-1
3380 ? changed_time : write_time);
3383 dosmode = IVAL(pdata,32);
3387 case SMB_FILE_ALLOCATION_INFORMATION:
3388 case SMB_SET_FILE_ALLOCATION_INFO:
3391 SMB_BIG_UINT allocation_size;
3394 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
3396 allocation_size = (SMB_BIG_UINT)IVAL(pdata,0);
3397 #ifdef LARGE_SMB_OFF_T
3398 allocation_size |= (((SMB_BIG_UINT)IVAL(pdata,4)) << 32);
3399 #else /* LARGE_SMB_OFF_T */
3400 if (IVAL(pdata,4) != 0) /* more than 32 bits? */
3401 return ERROR_DOS(ERRDOS,ERRunknownlevel);
3402 #endif /* LARGE_SMB_OFF_T */
3403 DEBUG(10,("call_trans2setfilepathinfo: Set file allocation info for file %s to %.0f\n",
3404 fname, (double)allocation_size ));
3406 if (allocation_size)
3407 allocation_size = smb_roundup(allocation_size);
3409 if(allocation_size != get_file_size(sbuf)) {
3410 SMB_STRUCT_STAT new_sbuf;
3412 DEBUG(10,("call_trans2setfilepathinfo: file %s : setting new allocation size to %.0f\n",
3413 fname, (double)allocation_size ));
3416 files_struct *new_fsp = NULL;
3417 int access_mode = 0;
3420 if(global_oplock_break) {
3421 /* Queue this file modify as we are the process of an oplock break. */
3423 DEBUG(2,("call_trans2setfilepathinfo: queueing message due to being "));
3424 DEBUGADD(2,( "in oplock break state.\n"));
3426 push_oplock_pending_smb_message(inbuf, length);
3430 new_fsp = open_file_shared1(conn, fname, &sbuf,FILE_WRITE_DATA,
3431 SET_OPEN_MODE(DOS_OPEN_RDWR),
3432 (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN),
3433 FILE_ATTRIBUTE_NORMAL,
3434 INTERNAL_OPEN_ONLY, &access_mode, &action);
3436 if (new_fsp == NULL)
3437 return(UNIXERROR(ERRDOS,ERRbadpath));
3438 ret = vfs_allocate_file_space(new_fsp, allocation_size);
3439 if (SMB_VFS_FSTAT(new_fsp,new_fsp->fd,&new_sbuf) != 0) {
3440 DEBUG(3,("call_trans2setfilepathinfo: fstat of fnum %d failed (%s)\n",
3441 new_fsp->fnum, strerror(errno)));
3444 close_file(new_fsp,True);
3446 ret = vfs_allocate_file_space(fsp, allocation_size);
3447 if (SMB_VFS_FSTAT(fsp,fd,&new_sbuf) != 0) {
3448 DEBUG(3,("call_trans2setfilepathinfo: fstat of fnum %d failed (%s)\n",
3449 fsp->fnum, strerror(errno)));
3454 return ERROR_NT(NT_STATUS_DISK_FULL);
3456 /* Allocate can truncate size... */
3457 size = get_file_size(new_sbuf);
3463 case SMB_FILE_END_OF_FILE_INFORMATION:
3464 case SMB_SET_FILE_END_OF_FILE_INFO:
3467 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
3469 size = IVAL(pdata,0);
3470 #ifdef LARGE_SMB_OFF_T
3471 size |= (((SMB_OFF_T)IVAL(pdata,4)) << 32);
3472 #else /* LARGE_SMB_OFF_T */
3473 if (IVAL(pdata,4) != 0) /* more than 32 bits? */
3474 return ERROR_DOS(ERRDOS,ERRunknownlevel);
3475 #endif /* LARGE_SMB_OFF_T */
3476 DEBUG(10,("call_trans2setfilepathinfo: Set end of file info for file %s to %.0f\n", fname, (double)size ));
3480 case SMB_FILE_DISPOSITION_INFORMATION:
3481 case SMB_SET_FILE_DISPOSITION_INFO: /* Set delete on close for open file. */
3483 BOOL delete_on_close;
3486 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
3488 delete_on_close = (CVAL(pdata,0) ? True : False);
3490 /* Just ignore this set on a path. */
3491 if (tran_call != TRANSACT2_SETFILEINFO)
3495 return(UNIXERROR(ERRDOS,ERRbadfid));
3497 status = set_delete_on_close_internal(fsp, delete_on_close, dosmode);
3499 if (NT_STATUS_V(status) != NT_STATUS_V(NT_STATUS_OK))
3500 return ERROR_NT(status);
3502 /* The set is across all open files on this dev/inode pair. */
3503 status =set_delete_on_close_over_all(fsp, delete_on_close);
3504 if (NT_STATUS_V(status) != NT_STATUS_V(NT_STATUS_OK))
3505 return ERROR_NT(status);
3510 case SMB_FILE_POSITION_INFORMATION:
3512 SMB_BIG_UINT position_information;
3515 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
3517 position_information = (SMB_BIG_UINT)IVAL(pdata,0);
3518 #ifdef LARGE_SMB_OFF_T
3519 position_information |= (((SMB_BIG_UINT)IVAL(pdata,4)) << 32);
3520 #else /* LARGE_SMB_OFF_T */
3521 if (IVAL(pdata,4) != 0) /* more than 32 bits? */
3522 return ERROR_DOS(ERRDOS,ERRunknownlevel);
3523 #endif /* LARGE_SMB_OFF_T */
3524 DEBUG(10,("call_trans2setfilepathinfo: Set file position information for file %s to %.0f\n",
3525 fname, (double)position_information ));
3527 fsp->position_information = position_information;
3532 * CIFS UNIX extensions.
3535 case SMB_SET_FILE_UNIX_BASIC:
3537 uint32 raw_unixmode;
3539 if (total_data < 100)
3540 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
3542 if(IVAL(pdata, 0) != SMB_SIZE_NO_CHANGE_LO &&
3543 IVAL(pdata, 4) != SMB_SIZE_NO_CHANGE_HI) {
3544 size=IVAL(pdata,0); /* first 8 Bytes are size */
3545 #ifdef LARGE_SMB_OFF_T
3546 size |= (((SMB_OFF_T)IVAL(pdata,4)) << 32);
3547 #else /* LARGE_SMB_OFF_T */
3548 if (IVAL(pdata,4) != 0) /* more than 32 bits? */
3549 return ERROR_DOS(ERRDOS,ERRunknownlevel);
3550 #endif /* LARGE_SMB_OFF_T */
3552 pdata+=24; /* ctime & st_blocks are not changed */
3553 tvs.actime = interpret_long_unix_date(pdata); /* access_time */
3554 tvs.modtime = interpret_long_unix_date(pdata+8); /* modification_time */
3556 set_owner = (uid_t)IVAL(pdata,0);
3558 set_grp = (gid_t)IVAL(pdata,0);
3560 raw_unixmode = IVAL(pdata,28);
3561 unixmode = unix_perms_from_wire(conn, &sbuf, raw_unixmode);
3562 dosmode = 0; /* Ensure dos mode change doesn't override this. */
3564 DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_BASIC: name = %s \
3565 size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n",
3566 fname, (double)size, (unsigned int)set_owner, (unsigned int)set_grp, (int)raw_unixmode));
3568 if (!VALID_STAT(sbuf)) {
3571 * The only valid use of this is to create character and block
3572 * devices, and named pipes. This is deprecated (IMHO) and
3573 * a new info level should be used for mknod. JRA.
3576 uint32 file_type = IVAL(pdata,0);
3577 #if defined(HAVE_MAKEDEV)
3578 uint32 dev_major = IVAL(pdata,4);
3579 uint32 dev_minor = IVAL(pdata,12);
3582 uid_t myuid = geteuid();
3583 gid_t mygid = getegid();
3584 SMB_DEV_T dev = (SMB_DEV_T)0;
3586 if (tran_call == TRANSACT2_SETFILEINFO)
3587 return(ERROR_DOS(ERRDOS,ERRnoaccess));
3589 if (raw_unixmode == SMB_MODE_NO_CHANGE)
3590 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
3592 #if defined(HAVE_MAKEDEV)
3593 dev = makedev(dev_major, dev_minor);
3596 /* We can only create as the owner/group we are. */
3598 if ((set_owner != myuid) && (set_owner != (uid_t)SMB_UID_NO_CHANGE))
3599 return(ERROR_DOS(ERRDOS,ERRnoaccess));
3600 if ((set_grp != mygid) && (set_grp != (gid_t)SMB_GID_NO_CHANGE))
3601 return(ERROR_DOS(ERRDOS,ERRnoaccess));
3603 switch (file_type) {
3604 #if defined(S_IFIFO)
3605 case UNIX_TYPE_FIFO:
3606 unixmode |= S_IFIFO;
3609 #if defined(S_IFSOCK)
3610 case UNIX_TYPE_SOCKET:
3611 unixmode |= S_IFSOCK;
3614 #if defined(S_IFCHR)
3615 case UNIX_TYPE_CHARDEV:
3616 unixmode |= S_IFCHR;
3619 #if defined(S_IFBLK)
3620 case UNIX_TYPE_BLKDEV:
3621 unixmode |= S_IFBLK;
3625 return(ERROR_DOS(ERRDOS,ERRnoaccess));
3628 DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_BASIC doing mknod dev %.0f mode \
3629 0%o for file %s\n", (double)dev, unixmode, fname ));
3631 /* Ok - do the mknod. */
3632 if (SMB_VFS_MKNOD(conn,fname, unixmode, dev) != 0)
3633 return(UNIXERROR(ERRDOS,ERRnoaccess));
3635 inherit_access_acl(conn, fname, unixmode);
3638 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
3643 * Deal with the UNIX specific mode set.
3646 if (raw_unixmode != SMB_MODE_NO_CHANGE) {
3647 DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_BASIC setting mode 0%o for file %s\n",
3648 (unsigned int)unixmode, fname ));
3649 if (SMB_VFS_CHMOD(conn,fname,unixmode) != 0)
3650 return(UNIXERROR(ERRDOS,ERRnoaccess));
3654 * Deal with the UNIX specific uid set.
3657 if ((set_owner != (uid_t)SMB_UID_NO_CHANGE) && (sbuf.st_uid != set_owner)) {
3658 DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_BASIC changing owner %u for file %s\n",
3659 (unsigned int)set_owner, fname ));
3660 if (SMB_VFS_CHOWN(conn,fname,set_owner, (gid_t)-1) != 0)
3661 return(UNIXERROR(ERRDOS,ERRnoaccess));
3665 * Deal with the UNIX specific gid set.
3668 if ((set_grp != (uid_t)SMB_GID_NO_CHANGE) && (sbuf.st_gid != set_grp)) {
3669 DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_BASIC changing group %u for file %s\n",
3670 (unsigned int)set_owner, fname ));
3671 if (SMB_VFS_CHOWN(conn,fname,(uid_t)-1, set_grp) != 0)
3672 return(UNIXERROR(ERRDOS,ERRnoaccess));
3677 case SMB_SET_FILE_UNIX_LINK:
3679 pstring link_target;
3680 char *newname = fname;
3682 /* Set a symbolic link. */
3683 /* Don't allow this if follow links is false. */
3685 if (!lp_symlinks(SNUM(conn)))
3686 return(ERROR_DOS(ERRDOS,ERRnoaccess));
3688 srvstr_pull(inbuf, link_target, pdata, sizeof(link_target), -1, STR_TERMINATE);
3690 /* !widelinks forces the target path to be within the share. */
3691 /* This means we can interpret the target as a pathname. */
3692 if (!lp_widelinks(SNUM(conn))) {
3694 char *last_dirp = NULL;
3696 unix_format(link_target);
3697 if (*link_target == '/') {
3698 /* No absolute paths allowed. */
3699 return(UNIXERROR(ERRDOS,ERRnoaccess));
3701 pstrcpy(rel_name, newname);
3702 last_dirp = strrchr_m(rel_name, '/');
3704 last_dirp[1] = '\0';
3706 pstrcpy(rel_name, "./");
3708 pstrcat(rel_name, link_target);
3710 if (!check_name(rel_name, conn)) {
3711 return(UNIXERROR(ERRDOS,ERRnoaccess));
3715 DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_LINK doing symlink %s -> %s\n",
3716 fname, link_target ));
3718 if (SMB_VFS_SYMLINK(conn,link_target,newname) != 0)
3719 return(UNIXERROR(ERRDOS,ERRnoaccess));
3721 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
3725 case SMB_SET_FILE_UNIX_HLINK:
3728 char *newname = fname;
3730 /* Set a hard link. */
3731 srvstr_get_path(inbuf, oldname, pdata, sizeof(oldname), -1, STR_TERMINATE, &status, False);
3732 if (!NT_STATUS_IS_OK(status)) {
3733 return ERROR_NT(status);
3736 DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_LINK doing hard link %s -> %s\n",
3739 status = hardlink_internals(conn, oldname, newname);
3740 if (!NT_STATUS_IS_OK(status)) {
3741 return ERROR_NT(status);
3745 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
3749 case SMB_FILE_RENAME_INFORMATION:
3758 if (total_data < 12)
3759 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
3761 overwrite = (CVAL(pdata,0) ? True : False);
3762 root_fid = IVAL(pdata,4);
3763 len = IVAL(pdata,8);
3764 srvstr_get_path(inbuf, newname, &pdata[12], sizeof(newname), len, 0, &status, False);
3765 if (!NT_STATUS_IS_OK(status)) {
3766 return ERROR_NT(status);
3769 /* Check the new name has no '/' characters. */
3770 if (strchr_m(newname, '/'))
3771 return ERROR_NT(NT_STATUS_NOT_SUPPORTED);
3773 RESOLVE_DFSPATH(newname, conn, inbuf, outbuf);
3775 /* Create the base directory. */
3776 pstrcpy(base_name, fname);
3777 p = strrchr_m(base_name, '/');
3780 /* Append the new name. */
3781 pstrcat(base_name, "/");
3782 pstrcat(base_name, newname);
3785 DEBUG(10,("call_trans2setfilepathinfo: SMB_FILE_RENAME_INFORMATION (fnum %d) %s -> %s\n",
3786 fsp->fnum, fsp->fsp_name, base_name ));
3787 status = rename_internals_fsp(conn, fsp, base_name, 0, overwrite);
3789 DEBUG(10,("call_trans2setfilepathinfo: SMB_FILE_RENAME_INFORMATION %s -> %s\n",
3791 status = rename_internals(conn, fname, base_name, 0, overwrite);
3793 if (!NT_STATUS_IS_OK(status)) {
3794 return ERROR_NT(status);
3796 process_pending_change_notify_queue((time_t)0);
3798 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
3802 return ERROR_DOS(ERRDOS,ERRunknownlevel);
3805 /* get some defaults (no modifications) if any info is zero or -1. */
3806 if (tvs.actime == (time_t)0 || tvs.actime == (time_t)-1)
3807 tvs.actime = sbuf.st_atime;
3809 if (tvs.modtime == (time_t)0 || tvs.modtime == (time_t)-1)
3810 tvs.modtime = sbuf.st_mtime;
3812 DEBUG(6,("actime: %s " , ctime(&tvs.actime)));
3813 DEBUG(6,("modtime: %s ", ctime(&tvs.modtime)));
3814 DEBUG(6,("size: %.0f ", (double)size));
3817 if (S_ISDIR(sbuf.st_mode))
3823 DEBUG(6,("dosmode: %x\n" , dosmode));
3825 if(!((info_level == SMB_SET_FILE_END_OF_FILE_INFO) ||
3826 (info_level == SMB_SET_FILE_ALLOCATION_INFO) ||
3827 (info_level == SMB_FILE_ALLOCATION_INFORMATION) ||
3828 (info_level == SMB_FILE_END_OF_FILE_INFORMATION))) {
3831 * Only do this test if we are not explicitly
3832 * changing the size of a file.
3835 size = get_file_size(sbuf);
3839 * Try and set the times, size and mode of this file -
3840 * if they are different from the current values
3842 if (sbuf.st_mtime != tvs.modtime || sbuf.st_atime != tvs.actime) {
3845 * This was a setfileinfo on an open file.
3846 * NT does this a lot. It's actually pointless
3847 * setting the time here, as it will be overwritten
3848 * on the next write, so we save the request
3849 * away and will set it on file close. JRA.
3852 if (tvs.modtime != (time_t)0 && tvs.modtime != (time_t)-1) {
3853 DEBUG(10,("call_trans2setfilepathinfo: setting pending modtime to %s\n", ctime(&tvs.modtime) ));
3854 fsp->pending_modtime = tvs.modtime;
3859 DEBUG(10,("call_trans2setfilepathinfo: setting utimes to modified values.\n"));
3861 if(file_utime(conn, fname, &tvs)!=0)
3862 return(UNIXERROR(ERRDOS,ERRnoaccess));
3866 /* check the mode isn't different, before changing it */
3867 if ((dosmode != 0) && (dosmode != dos_mode(conn, fname, &sbuf))) {
3869 DEBUG(10,("call_trans2setfilepathinfo: file %s : setting dos mode %x\n", fname, dosmode ));
3871 if(file_set_dosmode(conn, fname, dosmode, NULL)) {
3872 DEBUG(2,("file_set_dosmode of %s failed (%s)\n", fname, strerror(errno)));
3873 return(UNIXERROR(ERRDOS,ERRnoaccess));
3877 if (size != get_file_size(sbuf)) {
3881 DEBUG(10,("call_trans2setfilepathinfo: file %s : setting new size to %.0f\n",
3882 fname, (double)size ));
3885 files_struct *new_fsp = NULL;
3886 int access_mode = 0;
3889 if(global_oplock_break) {
3890 /* Queue this file modify as we are the process of an oplock break. */
3892 DEBUG(2,("call_trans2setfilepathinfo: queueing message due to being "));
3893 DEBUGADD(2,( "in oplock break state.\n"));
3895 push_oplock_pending_smb_message(inbuf, length);
3899 new_fsp = open_file_shared(conn, fname, &sbuf,
3900 SET_OPEN_MODE(DOS_OPEN_RDWR),
3901 (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN),
3902 FILE_ATTRIBUTE_NORMAL,
3903 INTERNAL_OPEN_ONLY, &access_mode, &action);
3905 if (new_fsp == NULL)
3906 return(UNIXERROR(ERRDOS,ERRbadpath));
3907 ret = vfs_set_filelen(new_fsp, size);
3908 close_file(new_fsp,True);
3910 ret = vfs_set_filelen(fsp, size);
3914 return (UNIXERROR(ERRHRD,ERRdiskfull));
3918 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
3923 /****************************************************************************
3924 Reply to a TRANS2_MKDIR (make directory with extended attributes).
3925 ****************************************************************************/
3927 static int call_trans2mkdir(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize,
3928 char **pparams, int total_params, char **ppdata, int total_data,
3929 unsigned int max_data_bytes)
3931 char *params = *pparams;
3934 SMB_STRUCT_STAT sbuf;
3935 BOOL bad_path = False;
3936 NTSTATUS status = NT_STATUS_OK;
3938 if (!CAN_WRITE(conn))
3939 return ERROR_DOS(ERRSRV,ERRaccess);
3941 if (total_params < 4)
3942 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
3944 srvstr_get_path(inbuf, directory, ¶ms[4], sizeof(directory), -1, STR_TERMINATE, &status, False);
3945 if (!NT_STATUS_IS_OK(status)) {
3946 return ERROR_NT(status);
3949 DEBUG(3,("call_trans2mkdir : name = %s\n", directory));
3951 unix_convert(directory,conn,0,&bad_path,&sbuf);
3953 return ERROR_NT(NT_STATUS_OBJECT_PATH_NOT_FOUND);
3955 if (check_name(directory,conn))
3956 ret = vfs_MkDir(conn,directory,unix_mode(conn,aDIR,directory));
3959 DEBUG(5,("call_trans2mkdir error (%s)\n", strerror(errno)));
3960 return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRnoaccess);
3963 /* Realloc the parameter and data sizes */
3964 params = Realloc(*pparams,2);
3966 return ERROR_DOS(ERRDOS,ERRnomem);
3971 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
3976 /****************************************************************************
3977 Reply to a TRANS2_FINDNOTIFYFIRST (start monitoring a directory for changes).
3978 We don't actually do this - we just send a null response.
3979 ****************************************************************************/
3981 static int call_trans2findnotifyfirst(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize,
3982 char **pparams, int total_params, char **ppdata, int total_data,
3983 unsigned int max_data_bytes)
3985 static uint16 fnf_handle = 257;
3986 char *params = *pparams;
3989 if (total_params < 6)
3990 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
3992 info_level = SVAL(params,4);
3993 DEBUG(3,("call_trans2findnotifyfirst - info_level %d\n", info_level));
3995 switch (info_level) {
4000 return ERROR_DOS(ERRDOS,ERRunknownlevel);
4003 /* Realloc the parameter and data sizes */
4004 params = Realloc(*pparams,6);
4006 return ERROR_DOS(ERRDOS,ERRnomem);
4009 SSVAL(params,0,fnf_handle);
4010 SSVAL(params,2,0); /* No changes */
4011 SSVAL(params,4,0); /* No EA errors */
4018 send_trans2_replies(outbuf, bufsize, params, 6, *ppdata, 0);
4023 /****************************************************************************
4024 Reply to a TRANS2_FINDNOTIFYNEXT (continue monitoring a directory for
4025 changes). Currently this does nothing.
4026 ****************************************************************************/
4028 static int call_trans2findnotifynext(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize,
4029 char **pparams, int total_params, char **ppdata, int total_data,
4030 unsigned int max_data_bytes)
4032 char *params = *pparams;
4034 DEBUG(3,("call_trans2findnotifynext\n"));
4036 /* Realloc the parameter and data sizes */
4037 params = Realloc(*pparams,4);
4039 return ERROR_DOS(ERRDOS,ERRnomem);
4042 SSVAL(params,0,0); /* No changes */
4043 SSVAL(params,2,0); /* No EA errors */
4045 send_trans2_replies(outbuf, bufsize, params, 4, *ppdata, 0);
4050 /****************************************************************************
4051 Reply to a TRANS2_GET_DFS_REFERRAL - Shirish Kalele <kalele@veritas.com>.
4052 ****************************************************************************/
4054 static int call_trans2getdfsreferral(connection_struct *conn, char* inbuf, char* outbuf, int length, int bufsize,
4055 char **pparams, int total_params, char **ppdata, int total_data,
4056 unsigned int max_data_bytes)
4058 char *params = *pparams;
4061 int max_referral_level;
4063 DEBUG(10,("call_trans2getdfsreferral\n"));
4065 if (total_params < 2)
4066 return(ERROR_DOS(ERRDOS,ERRinvalidparam));
4068 max_referral_level = SVAL(params,0);
4070 if(!lp_host_msdfs())
4071 return ERROR_DOS(ERRDOS,ERRbadfunc);
4073 srvstr_pull(inbuf, pathname, ¶ms[2], sizeof(pathname), -1, STR_TERMINATE);
4074 if((reply_size = setup_dfs_referral(conn, pathname,max_referral_level,ppdata)) < 0)
4075 return UNIXERROR(ERRDOS,ERRbadfile);
4077 SSVAL(outbuf,smb_flg2,SVAL(outbuf,smb_flg2) | FLAGS2_DFS_PATHNAMES);
4078 send_trans2_replies(outbuf,bufsize,0,0,*ppdata,reply_size);
4083 #define LMCAT_SPL 0x53
4084 #define LMFUNC_GETJOBID 0x60
4086 /****************************************************************************
4087 Reply to a TRANS2_IOCTL - used for OS/2 printing.
4088 ****************************************************************************/
4090 static int call_trans2ioctl(connection_struct *conn, char* inbuf, char* outbuf, int length, int bufsize,
4091 char **pparams, int total_params, char **ppdata, int total_data,
4092 unsigned int max_data_bytes)
4094 char *pdata = *ppdata;
4095 files_struct *fsp = file_fsp(inbuf,smb_vwv15);
4097 /* check for an invalid fid before proceeding */
4100 return(ERROR_DOS(ERRDOS,ERRbadfid));
4102 if ((SVAL(inbuf,(smb_setup+4)) == LMCAT_SPL) &&
4103 (SVAL(inbuf,(smb_setup+6)) == LMFUNC_GETJOBID)) {
4104 pdata = Realloc(*ppdata, 32);
4106 return ERROR_DOS(ERRDOS,ERRnomem);
4109 /* NOTE - THIS IS ASCII ONLY AT THE MOMENT - NOT SURE IF OS/2
4110 CAN ACCEPT THIS IN UNICODE. JRA. */
4112 SSVAL(pdata,0,fsp->rap_print_jobid); /* Job number */
4113 srvstr_push( outbuf, pdata + 2, global_myname(), 15, STR_ASCII|STR_TERMINATE); /* Our NetBIOS name */
4114 srvstr_push( outbuf, pdata+18, lp_servicename(SNUM(conn)), 13, STR_ASCII|STR_TERMINATE); /* Service name */
4115 send_trans2_replies(outbuf,bufsize,*pparams,0,*ppdata,32);
4118 DEBUG(2,("Unknown TRANS2_IOCTL\n"));
4119 return ERROR_DOS(ERRSRV,ERRerror);
4123 /****************************************************************************
4124 Reply to a SMBfindclose (stop trans2 directory search).
4125 ****************************************************************************/
4127 int reply_findclose(connection_struct *conn,
4128 char *inbuf,char *outbuf,int length,int bufsize)
4131 int dptr_num=SVALS(inbuf,smb_vwv0);
4132 START_PROFILE(SMBfindclose);
4134 DEBUG(3,("reply_findclose, dptr_num = %d\n", dptr_num));
4136 dptr_close(&dptr_num);
4138 outsize = set_message(outbuf,0,0,True);
4140 DEBUG(3,("SMBfindclose dptr_num = %d\n", dptr_num));
4142 END_PROFILE(SMBfindclose);
4146 /****************************************************************************
4147 Reply to a SMBfindnclose (stop FINDNOTIFYFIRST directory search).
4148 ****************************************************************************/
4150 int reply_findnclose(connection_struct *conn,
4151 char *inbuf,char *outbuf,int length,int bufsize)
4155 START_PROFILE(SMBfindnclose);
4157 dptr_num = SVAL(inbuf,smb_vwv0);
4159 DEBUG(3,("reply_findnclose, dptr_num = %d\n", dptr_num));
4161 /* We never give out valid handles for a
4162 findnotifyfirst - so any dptr_num is ok here.
4165 outsize = set_message(outbuf,0,0,True);
4167 DEBUG(3,("SMB_findnclose dptr_num = %d\n", dptr_num));
4169 END_PROFILE(SMBfindnclose);
4173 /****************************************************************************
4174 Reply to a SMBtranss2 - just ignore it!
4175 ****************************************************************************/
4177 int reply_transs2(connection_struct *conn,
4178 char *inbuf,char *outbuf,int length,int bufsize)
4180 START_PROFILE(SMBtranss2);
4181 DEBUG(4,("Ignoring transs2 of length %d\n",length));
4182 END_PROFILE(SMBtranss2);
4186 /****************************************************************************
4187 Reply to a SMBtrans2.
4188 ****************************************************************************/
4190 int reply_trans2(connection_struct *conn,
4191 char *inbuf,char *outbuf,int length,int bufsize)
4194 unsigned int total_params = SVAL(inbuf, smb_tpscnt);
4195 unsigned int total_data =SVAL(inbuf, smb_tdscnt);
4196 unsigned int max_data_bytes = SVAL(inbuf, smb_mdrcnt);
4198 unsigned int max_param_reply = SVAL(inbuf, smb_mprcnt);
4199 unsigned int max_setup_fields = SVAL(inbuf, smb_msrcnt);
4200 BOOL close_tid = BITSETW(inbuf+smb_flags,0);
4201 BOOL no_final_response = BITSETW(inbuf+smb_flags,1);
4202 int32 timeout = IVALS(inbuf,smb_timeout);
4204 unsigned int suwcnt = SVAL(inbuf, smb_suwcnt);
4205 unsigned int tran_call = SVAL(inbuf, smb_setup0);
4206 char *params = NULL, *data = NULL;
4207 unsigned int num_params, num_params_sofar, num_data, num_data_sofar;
4208 START_PROFILE(SMBtrans2);
4210 if(global_oplock_break && (tran_call == TRANSACT2_OPEN)) {
4211 /* Queue this open message as we are the process of an
4214 DEBUG(2,("reply_trans2: queueing message trans2open due to being "));
4215 DEBUGADD(2,( "in oplock break state.\n"));
4217 push_oplock_pending_smb_message(inbuf, length);
4218 END_PROFILE(SMBtrans2);
4222 if (IS_IPC(conn) && (tran_call != TRANSACT2_OPEN)
4223 && (tran_call != TRANSACT2_GET_DFS_REFERRAL)) {
4224 END_PROFILE(SMBtrans2);
4225 return ERROR_DOS(ERRSRV,ERRaccess);
4228 outsize = set_message(outbuf,0,0,True);
4230 /* All trans2 messages we handle have smb_sucnt == 1 - ensure this
4231 is so as a sanity check */
4234 * Need to have rc=0 for ioctl to get job id for OS/2.
4235 * Network printing will fail if function is not successful.
4236 * Similar function in reply.c will be used if protocol
4237 * is LANMAN1.0 instead of LM1.2X002.
4238 * Until DosPrintSetJobInfo with PRJINFO3 is supported,
4239 * outbuf doesn't have to be set(only job id is used).
4241 if ( (suwcnt == 4) && (tran_call == TRANSACT2_IOCTL) &&
4242 (SVAL(inbuf,(smb_setup+4)) == LMCAT_SPL) &&
4243 (SVAL(inbuf,(smb_setup+6)) == LMFUNC_GETJOBID)) {
4244 DEBUG(2,("Got Trans2 DevIOctl jobid\n"));
4246 DEBUG(2,("Invalid smb_sucnt in trans2 call(%u)\n",suwcnt));
4247 DEBUG(2,("Transaction is %d\n",tran_call));
4248 END_PROFILE(SMBtrans2);
4249 ERROR_DOS(ERRDOS,ERRinvalidparam);
4253 /* Allocate the space for the maximum needed parameters and data */
4254 if (total_params > 0)
4255 params = (char *)malloc(total_params);
4257 data = (char *)malloc(total_data);
4259 if ((total_params && !params) || (total_data && !data)) {
4260 DEBUG(2,("Out of memory in reply_trans2\n"));
4263 END_PROFILE(SMBtrans2);
4264 return ERROR_DOS(ERRDOS,ERRnomem);
4267 /* Copy the param and data bytes sent with this request into
4268 the params buffer */
4269 num_params = num_params_sofar = SVAL(inbuf,smb_pscnt);
4270 num_data = num_data_sofar = SVAL(inbuf, smb_dscnt);
4272 if (num_params > total_params || num_data > total_data)
4273 exit_server("invalid params in reply_trans2");
4276 unsigned int psoff = SVAL(inbuf, smb_psoff);
4277 if ((psoff + num_params < psoff) || (psoff + num_params < num_params))
4279 if ((smb_base(inbuf) + psoff + num_params > inbuf + length) ||
4280 (smb_base(inbuf) + psoff + num_params < smb_base(inbuf)))
4282 memcpy( params, smb_base(inbuf) + psoff, num_params);
4285 unsigned int dsoff = SVAL(inbuf, smb_dsoff);
4286 if ((dsoff + num_data < dsoff) || (dsoff + num_data < num_data))
4288 if ((smb_base(inbuf) + dsoff + num_data > inbuf + length) ||
4289 (smb_base(inbuf) + dsoff + num_data < smb_base(inbuf)))
4291 memcpy( data, smb_base(inbuf) + dsoff, num_data);
4294 srv_signing_trans_start(SVAL(inbuf,smb_mid));
4296 if(num_data_sofar < total_data || num_params_sofar < total_params) {
4297 /* We need to send an interim response then receive the rest
4298 of the parameter/data bytes */
4299 outsize = set_message(outbuf,0,0,True);
4300 srv_signing_trans_stop();
4301 if (!send_smb(smbd_server_fd(),outbuf))
4302 exit_server("reply_trans2: send_smb failed.");
4304 while (num_data_sofar < total_data ||
4305 num_params_sofar < total_params) {
4307 unsigned int param_disp;
4308 unsigned int param_off;
4309 unsigned int data_disp;
4310 unsigned int data_off;
4312 ret = receive_next_smb(inbuf,bufsize,SMB_SECONDARY_WAIT);
4315 * The sequence number for the trans reply is always
4316 * based on the last secondary received.
4319 srv_signing_trans_start(SVAL(inbuf,smb_mid));
4322 (CVAL(inbuf, smb_com) != SMBtranss2)) || !ret) {
4323 outsize = set_message(outbuf,0,0,True);
4325 DEBUG(0,("reply_trans2: Invalid secondary trans2 packet\n"));
4327 DEBUG(0,("reply_trans2: %s in getting secondary trans2 response.\n",
4328 (smb_read_error == READ_ERROR) ? "error" : "timeout" ));
4332 /* Revise total_params and total_data in case
4333 they have changed downwards */
4334 if (SVAL(inbuf, smb_tpscnt) < total_params)
4335 total_params = SVAL(inbuf, smb_tpscnt);
4336 if (SVAL(inbuf, smb_tdscnt) < total_data)
4337 total_data = SVAL(inbuf, smb_tdscnt);
4339 num_params = SVAL(inbuf,smb_spscnt);
4340 param_off = SVAL(inbuf, smb_spsoff);
4341 param_disp = SVAL(inbuf, smb_spsdisp);
4342 num_params_sofar += num_params;
4344 num_data = SVAL(inbuf, smb_sdscnt);
4345 data_off = SVAL(inbuf, smb_sdsoff);
4346 data_disp = SVAL(inbuf, smb_sdsdisp);
4347 num_data_sofar += num_data;
4349 if (num_params_sofar > total_params || num_data_sofar > total_data)
4353 if (param_disp + num_params > total_params)
4355 if ((param_disp + num_params < param_disp) ||
4356 (param_disp + num_params < num_params))
4358 if (param_disp > total_params)
4360 if ((smb_base(inbuf) + param_off + num_params >= inbuf + bufsize) ||
4361 (smb_base(inbuf) + param_off + num_params < smb_base(inbuf)))
4363 if (params + param_disp < params)
4366 memcpy( ¶ms[param_disp], smb_base(inbuf) + param_off, num_params);
4369 if (data_disp + num_data > total_data)
4371 if ((data_disp + num_data < data_disp) ||
4372 (data_disp + num_data < num_data))
4374 if (data_disp > total_data)
4376 if ((smb_base(inbuf) + data_off + num_data >= inbuf + bufsize) ||
4377 (smb_base(inbuf) + data_off + num_data < smb_base(inbuf)))
4379 if (data + data_disp < data)
4382 memcpy( &data[data_disp], smb_base(inbuf) + data_off, num_data);
4387 if (Protocol >= PROTOCOL_NT1) {
4388 SSVAL(outbuf,smb_flg2,SVAL(outbuf,smb_flg2) | 0x40); /* IS_LONG_NAME */
4391 /* Now we must call the relevant TRANS2 function */
4393 case TRANSACT2_OPEN:
4394 START_PROFILE_NESTED(Trans2_open);
4395 outsize = call_trans2open(conn, inbuf, outbuf, bufsize,
4396 ¶ms, total_params, &data, total_data, max_data_bytes);
4397 END_PROFILE_NESTED(Trans2_open);
4400 case TRANSACT2_FINDFIRST:
4401 START_PROFILE_NESTED(Trans2_findfirst);
4402 outsize = call_trans2findfirst(conn, inbuf, outbuf, bufsize,
4403 ¶ms, total_params, &data, total_data, max_data_bytes);
4404 END_PROFILE_NESTED(Trans2_findfirst);
4407 case TRANSACT2_FINDNEXT:
4408 START_PROFILE_NESTED(Trans2_findnext);
4409 outsize = call_trans2findnext(conn, inbuf, outbuf, length, bufsize,
4410 ¶ms, total_params, &data, total_data, max_data_bytes);
4411 END_PROFILE_NESTED(Trans2_findnext);
4414 case TRANSACT2_QFSINFO:
4415 START_PROFILE_NESTED(Trans2_qfsinfo);
4416 outsize = call_trans2qfsinfo(conn, inbuf, outbuf, length, bufsize,
4417 ¶ms, total_params, &data, total_data, max_data_bytes);
4418 END_PROFILE_NESTED(Trans2_qfsinfo);
4421 #ifdef HAVE_SYS_QUOTAS
4422 case TRANSACT2_SETFSINFO:
4423 START_PROFILE_NESTED(Trans2_setfsinfo);
4424 outsize = call_trans2setfsinfo(conn, inbuf, outbuf, length, bufsize,
4425 ¶ms, total_params, &data, total_data, max_data_bytes);
4426 END_PROFILE_NESTED(Trans2_setfsinfo);
4429 case TRANSACT2_QPATHINFO:
4430 case TRANSACT2_QFILEINFO:
4431 START_PROFILE_NESTED(Trans2_qpathinfo);
4432 outsize = call_trans2qfilepathinfo(conn, inbuf, outbuf, length, bufsize,
4433 ¶ms, total_params, &data, total_data, max_data_bytes);
4434 END_PROFILE_NESTED(Trans2_qpathinfo);
4436 case TRANSACT2_SETPATHINFO:
4437 case TRANSACT2_SETFILEINFO:
4438 START_PROFILE_NESTED(Trans2_setpathinfo);
4439 outsize = call_trans2setfilepathinfo(conn, inbuf, outbuf, length, bufsize,
4440 ¶ms, total_params, &data, total_data, max_data_bytes);
4441 END_PROFILE_NESTED(Trans2_setpathinfo);
4444 case TRANSACT2_FINDNOTIFYFIRST:
4445 START_PROFILE_NESTED(Trans2_findnotifyfirst);
4446 outsize = call_trans2findnotifyfirst(conn, inbuf, outbuf, length, bufsize,
4447 ¶ms, total_params, &data, total_data, max_data_bytes);
4448 END_PROFILE_NESTED(Trans2_findnotifyfirst);
4451 case TRANSACT2_FINDNOTIFYNEXT:
4452 START_PROFILE_NESTED(Trans2_findnotifynext);
4453 outsize = call_trans2findnotifynext(conn, inbuf, outbuf, length, bufsize,
4454 ¶ms, total_params, &data, total_data, max_data_bytes);
4455 END_PROFILE_NESTED(Trans2_findnotifynext);
4457 case TRANSACT2_MKDIR:
4458 START_PROFILE_NESTED(Trans2_mkdir);
4459 outsize = call_trans2mkdir(conn, inbuf, outbuf, length, bufsize,
4460 ¶ms, total_params, &data, total_data, max_data_bytes);
4461 END_PROFILE_NESTED(Trans2_mkdir);
4464 case TRANSACT2_GET_DFS_REFERRAL:
4465 START_PROFILE_NESTED(Trans2_get_dfs_referral);
4466 outsize = call_trans2getdfsreferral(conn,inbuf,outbuf,length, bufsize,
4467 ¶ms, total_params, &data, total_data, max_data_bytes);
4468 END_PROFILE_NESTED(Trans2_get_dfs_referral);
4470 case TRANSACT2_IOCTL:
4471 START_PROFILE_NESTED(Trans2_ioctl);
4472 outsize = call_trans2ioctl(conn,inbuf,outbuf,length, bufsize,
4473 ¶ms, total_params, &data, total_data, max_data_bytes);
4474 END_PROFILE_NESTED(Trans2_ioctl);
4477 /* Error in request */
4478 DEBUG(2,("Unknown request %d in trans2 call\n", tran_call));
4481 END_PROFILE(SMBtrans2);
4482 srv_signing_trans_stop();
4483 return ERROR_DOS(ERRSRV,ERRerror);
4486 /* As we do not know how many data packets will need to be
4487 returned here the various call_trans2xxxx calls
4488 must send their own. Thus a call_trans2xxx routine only
4489 returns a value other than -1 when it wants to send
4493 srv_signing_trans_stop();
4497 END_PROFILE(SMBtrans2);
4498 return outsize; /* If a correct response was needed the
4499 call_trans2xxx calls have already sent
4500 it. If outsize != -1 then it is returning */
4504 srv_signing_trans_stop();
4507 END_PROFILE(SMBtrans2);
4508 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);