smb_trans2_query_file_info.c revision 55bf511df53aad0fdb7eb3fa349f0308cc05234c
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
/*
* SMB: trans2_query_file_information
*
* This request is used to get information about a specific file or
* subdirectory given a handle to it.
*
* Client Request Value
* ========================== ==========================================
*
* WordCount 15
* MaxSetupCount 0
* SetupCount 1
* Setup[0] TRANS2_QUERY_FILE_INFORMATION
*
* Parameter Block Encoding Description
* ========================== ==========================================
*
* USHORT Fid; Handle of file for request
* USHORT InformationLevel; Level of information requested
*
* The available information levels, as well as the format of the response
* are identical to TRANS2_QUERY_PATH_INFORMATION.
*/
#include <smbsrv/smb_vops.h>
#include <smbsrv/smb_incl.h>
#include <smbsrv/smb_fsops.h>
/*
* smb_com_trans2_query_file_information
*
* Observation of Windows 2000 indicates the following:
*
* 1) If a file is opened with delete-on-close create options, the
* delete-on-close status returned by the Trans2QueryFileInfo will not
* be set. The delete-on-close status will only be set when the above
* file handle is closed.
*
* 2) If a file is not opened with delete-on-close create options but the
* delete-on-close is set via Trans2SetFileInfo/DispositionInfo, the
* delete-on-close status returned by Trans2QueryFileInfo will be set
* immediately.
*/
int
{
static smb_attr_t pipe_attr;
int filename_len = 0;
unsigned char delete_on_close = 0;
unsigned char is_dir = 0;
/*
* buffer for mangled name and shortname are allocated
* much higher than required space. Optimization
* here should be performed along with mangled_name & shortname
* of query path information.
*/
char *mangled_name = 0;
&infolev) != 0) {
/* NOTREACHED */
}
/* NOTREACHED */
}
case SMB_FTYPE_DISK:
{
/*
* The node is only valid for SMB_FTYPE_DISK files.
*/
/*
* For some reason NT will not show the security tab in the root
* directory of a mapped drive unless the filename length is
* greater than one.
* This may be a NT vs Windows9x UNICODE check.
* So we hack the length here to persuade NT to show the tab. It
* should be safe because of the null terminator character.
*/
/* be careful here we need od_name now rather than node_name */
/* do we want to use node_name in the case of softlinks ?? */
filename_len = 2;
is_dir = 1;
} else {
is_dir = 0;
}
}
break;
case SMB_FTYPE_MESG_PIPE:
{
/*
* The pipe is only valid for SMB_FTYPE_MESG_PIPE files.
*/
delete_on_close = 0;
is_dir = 0;
}
break;
default:
/* NOTREACHED */
break;
}
if (infolev > SMB_INFO_PASSTHROUGH)
switch (infolev) {
case FileAccessInformation:
break;
case SMB_INFO_STANDARD:
? "YYYllw" : "yyyllw"),
dattr);
break;
case SMB_INFO_QUERY_EA_SIZE:
? "YYYllwl" : "yyyllwl"),
dattr, 0);
break;
case SMB_INFO_QUERY_ALL_EAS:
break;
case SMB_INFO_IS_NAME_VALID:
break;
/*
* NT includes 6 undocumented bytes at the end of this
* response, which are required by NetBench 5.01.
* Similar change in smb_trans2_query_path_information.c.
*/
dattr);
break;
/*
* Add 2 bytes to pad data to long. It is
* necessary because Win2k expects the padded bytes.
*/
is_dir);
break;
case SMB_QUERY_FILE_EA_INFO:
break;
case SMB_QUERY_FILE_NAME_INFO:
/*
* It looks like NT doesn't know what to do with the name "."
* so we convert it to "\\" to indicate the root directory.
*
* If the leading \ is missing, add it.
*/
filename = "\\";
filename_len = 2;
} else if (*namep != '\\') {
namep);
} else {
}
break;
case SMB_QUERY_FILE_ALL_INFO:
/*
* The reply of this information level on the
* wire doesn't match with protocol specification.
* This is what spec. needs: "TTTTwqqlbbqllqqll"
* But this is actually is sent on the wire:
* "TTTTw6.qqlbb2.l"
* So, there is a 6-byte pad between Attributes and
* AllocationSize. Also there is a 2-byte pad After
* Directory field. Between Directory and FileNameLength
* there is just 4 bytes that it seems is AlignmentRequirement.
* There are 6 other fields between Directory and
* AlignmentRequirement in spec. that aren't sent
* on the wire.
*/
0);
break;
/*
* Conform to the rule used by Windows NT/2003 servers.
* Shortname is created only if either the
* filename or extension portion of a file is made up of
* mixed case. This is handled in os/libnt/nt_mangle_name.c.
*
* If the shortname is generated, it will be returned as
* the alternative name. Otherwise, converts the original
* name to all upper-case and returns it as the alternative
* name. This is how Windows NT/2003 servers behave. However,
* Windows 2000 seems to preserve the case of the original
* name, and returns it as the alternative name.
*/
alt_nm_ptr = (*mangled_name == 0) ?
break;
{
/* NOT REACHED */
}
if (SMB_IS_STREAM(node)) {
} else {
}
break;
}
dsize, 0, 0, 0, 0);
break;
default:
/* NOTREACHED */
break;
}
return (SDRC_NORMAL_REPLY);
}
/*
* smb_encode_stream_info
*
* This function encodes the streams information for both T2QueryFileInfo
* and T2QueryPathInfo. The rules about how to do this are not documented.
* They have been derived using observed NT behaviour and the IR's listed
* below.
*
* IR101680: ArcServe2000 problem. ArcServe doesn't like the null-
* stream data on directories that don't have any associated streams.
*
* IR103484 and KB article Q234765: Citrix problem. If there are no
* streams, only return the unnamed stream data if the target is a
* file. The Citrix Metaframe cdm.sys driver crashes the Windows server,
* on which it's running, if it receives the unexpected stream data
* for a directory.
*
* If there are streams, on files or directories, we need to return
* to see if there is a comment stream. If we don't provide the
* information, the client won't try to access the comment stream.
*
* If the target is a file:
* 1. If there are no named streams, the response should still contain
* an entry for the unnamed stream.
* 2. If there are named streams, the response should contain an entry
* for the unnamed stream followed by the entries for the named
* streams.
*
* If the target is a directory:
* 1. If there are no streams, the response is complete. Directories
* do not report the unnamed stream.
* 2. If there are streams, the response should contain entries for
* those streams but there should not be an entry for the unnamed
* stream.
*
* Note that the stream name lengths exclude the null terminator but
* the field lengths (i.e. next offset calculations) need to include
* the null terminator and be padded to a multiple of 8 bytes. The
* last entry does not seem to need any padding.
*/
void
struct smb_request *sr,
{
char *stream_name;
int is_dir;
struct fs_stream_info *stream_info;
struct fs_stream_info *stream_info_next;
int rc = 0;
int done = 0;
char *fname;
if (is_dir == 0) {
stream_name = "::$DATA";
next_offset = 0;
}
/* No named streams, we're done */
return;
}
if (is_dir == 0) {
stream_name = "::$DATA";
/*
* Offset calculation:
* 2 dwords + 2 quadwords => 4 + 4 + 8 + 8 => 24
*/
}
while (!done) {
/*
* Named streams.
*/
stream_info->name);
next_offset = 0;
pad = 0;
/*
* this is a little kludgy, since we use a cookie now and last
* packet does not have a pad we need to check the next item
* before we encode the current one
*/
stream_info_next->name[0] = 0;
if (cookie == 0x7FFFFFFF) {
done = 1;
} else {
if (cookie == 0) {
break;
}
next_offset += pad;
}
sizeof (struct fs_stream_info));
}
}
/*
* smb_pad_align
*
* Returns the number of bytes required to get pad an offset to the
* specified alignment.
*/
{
if (pad != 0)
return (pad);
}