smb_trans2_query_fs_information.c revision fc724630b14603e4c1147df68b7bf45f7de7431f
/*
* 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
* or http://www.opensolaris.org/os/licensing.
* 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 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
/*
* SMB: trans2_query_fs_information
*
* This transaction requests information about a filesystem on the server.
*
* Client Request Value
* ================================== =================================
*
* WordCount; 15
* TotalParameterCount; 2 or 4
* MaxSetupCount; 0
* SetupCount; 1 or 2
* Setup[0]; TRANS2_QUERY_FS_INFORMATION
*
* Parameter Block Encoding Description
* ================================== =================================
*
* USHORT Information Level; Level of information requested
*
* The filesystem is identified by Tid in the SMB header.
*
* MaxDataCount in the transaction request must be large enough to
* accommodate the response.
*
* The encoding of the response parameter block depends on the
* InformationLevel requested. Information levels whose values are greater
* than 0x102 are mapped to corresponding calls to
* NtQueryVolumeInformationFile calls by the server. The two levels below
* 0x102 are described below. The requested information is placed in the
* Data portion of the transaction response.
*
* InformationLevel Value
*
* ============================= ======
*
* SMB_INFO_ALLOCATION 1
* SMB_INFO_VOLUME 2
* SMB_QUERY_FS_VOLUME_INFO 0x102
* SMB_QUERY_FS_SIZE_INFO 0x103
* SMB_QUERY_FS_DEVICE_INFO 0x104
* SMB_QUERY_FS_ATTRIBUTE_INFO 0x105
*
* The following sections describe the InformationLevel dependent encoding
* of the data part of the transaction response.
*
* 4.1.6.1 SMB_INFO_ALLOCATION
*
* Data Block Encoding Description
* =================== ================================================
*
* ULONG idFileSystem; File system identifier. NT server always
* returns 0
* ULONG cSectorUnit; Number of sectors per allocation unit
* ULONG cUnit; Total number of allocation units
* ULONG cUnitAvail; Total number of available allocation units
* USHORT cbSector; Number of bytes per sector
*
* 4.1.6.2 SMB_INFO_VOLUME
*
* Data Block Encoding Description
* =================== ================================================
*
* ULONG ulVsn; Volume serial number
* UCHAR cch; Number of characters in Label
* STRING Label; The volume label
*
* 4.1.6.3 SMB_QUERY_FS_VOLUME_INFO
*
* Data Block Encoding Description
* =================== ================================================
*
* LARGE_INTEGER Volume Creation Time
* ULONG Volume Serial Number
* ULONG Length of Volume Label in bytes
*
* BYTE Reserved
*
* BYTE Reserved
*
* STRING Label; The volume label
*
* 4.1.6.4 SMB_QUERY_FS_SIZE_INFO
*
* Data Block Encoding Description
* =================== ================================================
*
* LARGE_INTEGER Total Number of Allocation units on the Volume
* LARGE_INTEGER Number of free Allocation units on the Volume
* ULONG Number of sectors in each Allocation unit
*
* ULONG Number of bytes in each sector
*
* 4.1.6.5 SMB_QUERY_FS_DEVICE_INFO
*
* Data Block Encoding Value
* ==================== ===============================================
*
* ULONG DeviceType; Values as specified below
* ULONG Characteristics of the device; Values as
* specified below
*
* For DeviceType, note that the values 0-32767 are reserved for the
* exclusive use of Microsoft Corporation. The following device types are
* currently defined:
*
* FILE_DEVICE_BEEP 0x00000001
*
* FILE_DEVICE_CD_ROM 0x00000002
* FILE_DEVICE_CD_ROM_FILE_SYST 0x00000003
* EM
* FILE_DEVICE_CONTROLLER 0x00000004
* FILE_DEVICE_DATALINK 0x00000005
* FILE_DEVICE_DFS 0x00000006
* FILE_DEVICE_DISK 0x00000007
* FILE_DEVICE_DISK_FILE_SYSTEM 0x00000008
* FILE_DEVICE_FILE_SYSTEM 0x00000009
* FILE_DEVICE_INPORT_PORT 0x0000000a
* FILE_DEVICE_KEYBOARD 0x0000000b
* FILE_DEVICE_MAILSLOT 0x0000000c
* FILE_DEVICE_MIDI_IN 0x0000000d
* FILE_DEVICE_MIDI_OUT 0x0000000e
* FILE_DEVICE_MOUSE 0x0000000f
* FILE_DEVICE_MULTI_UNC_PROVID 0x00000010
* ER
* FILE_DEVICE_NAMED_PIPE 0x00000011
* FILE_DEVICE_NETWORK 0x00000012
* FILE_DEVICE_NETWORK_BROWSER 0x00000013
* FILE_DEVICE_NETWORK_FILE_SYS 0x00000014
* TEM
* FILE_DEVICE_NULL 0x00000015
* FILE_DEVICE_PARALLEL_PORT 0x00000016
* FILE_DEVICE_PHYSICAL_NETCARD 0x00000017
* FILE_DEVICE_PRINTER 0x00000018
* FILE_DEVICE_SCANNER 0x00000019
* FILE_DEVICE_SERIAL_MOUSE_POR 0x0000001a
* T
* FILE_DEVICE_SERIAL_PORT 0x0000001b
* FILE_DEVICE_SCREEN 0x0000001c
* FILE_DEVICE_SOUND 0x0000001d
* FILE_DEVICE_STREAMS 0x0000001e
* FILE_DEVICE_TAPE 0x0000001f
* FILE_DEVICE_TAPE_FILE_SYSTEM 0x00000020
* FILE_DEVICE_TRANSPORT 0x00000021
* FILE_DEVICE_UNKNOWN 0x00000022
* FILE_DEVICE_VIDEO 0x00000023
* FILE_DEVICE_VIRTUAL_DISK 0x00000024
* FILE_DEVICE_WAVE_IN 0x00000025
* FILE_DEVICE_WAVE_OUT 0x00000026
* FILE_DEVICE_8042_PORT 0x00000027
* FILE_DEVICE_NETWORK_REDIRECT 0x00000028
* OR
* FILE_DEVICE_BATTERY 0x00000029
* FILE_DEVICE_BUS_EXTENDER 0x0000002a
* FILE_DEVICE_MODEM 0x0000002b
* FILE_DEVICE_VDM 0x0000002c
*
* Some of these device types are not currently accessible over the network
* and may never be accessible over the network. Some may change to be
*
* accessible over the network. The values for device types that may never
* be accessible over the network may be redefined to be just reserved at
* some date in the future.
*
* Characteristics is the sum of any of the following:
*
* FILE_REMOVABLE_MEDIA 0x00000001
* FILE_READ_ONLY_DEVICE 0x00000002
* FILE_FLOPPY_DISKETTE 0x00000004
* FILE_WRITE_ONE_MEDIA 0x00000008
* FILE_REMOTE_DEVICE 0x00000010
* FILE_DEVICE_IS_MOUNTED 0x00000020
* FILE_VIRTUAL_VOLUME 0x00000040
*
* 4.1.6.6 SMB_QUERY_FS_ATTRIBUTE_INFO
*
* Data Block Encoding Description
* =================== ================================================
*
* ULONG File System Attributes; possible values
* described below
* LONG Maximum length of each file name component in
* number of bytes
* ULONG Length, in bytes, of the name of the file system
*
* STRING Name of the file system
*
* Where FileSystemAttributes is the sum of any of the following:
*
* FILE_CASE_SENSITIVE_SEARCH 0x00000001
* FILE_CASE_PRESERVED_NAMES 0x00000002
* FILE_PRSISTENT_ACLS 0x00000004
* FILE_FILE_COMPRESSION 0x00000008
* FILE_VOLUME_QUOTAS 0x00000010
* FILE_DEVICE_IS_MOUNTED 0x00000020
* FILE_VOLUME_IS_COMPRESSED 0x00008000
*
* 4.1.6.7 Errors
*
* ERRSRV/invnid - TID was invalid
* ERRSRV/baduid - UID was invalid
* ERRHRD/ERRnotready - the file system has been removed
* ERRHRD/ERRdata - disk I/O error
* ERRSRV/ERRaccess - user does not have the right to perform this
* operation
* ERRSRV/ERRinvdevice - resource identified by TID is not a file system
*/
#include <smbsrv/smb_incl.h>
#include <smbsrv/smb_fsops.h>
#include <smbsrv/smbinfo.h>
char ntfs[] = "NTFS";
/*
* smb_com_trans2_query_fs_information
*
* The fsid provides a system-wide unique file system ID.
* fsid.val[0] is the 32-bit dev for the file system of the share root
* smb_node.
* fsid.val[1] is the file system type.
*/
smb_sdrc_t
smb_com_trans2_query_fs_information(struct smb_request *sr, struct smb_xa *xa)
{
int rc;
uint32_t flags;
char *encode_str;
uint64_t max_int;
unsigned short infolev;
struct statvfs64 df;
int sect_per_unit, length;
uint32_t total_units, avail_units;
smb_tree_t *tree;
smb_node_t *snode;
char *fsname = "NTFS";
fsid_t fsid;
tree = sr->tid_tree;
if (!STYPE_ISDSK(tree->t_res_type)) {
smbsr_error(sr, NT_STATUS_ACCESS_DENIED, ERRDOS, ERRnoaccess);
return (SDRC_ERROR);
}
if (smb_mbc_decodef(&xa->req_param_mb, "w", &infolev) != 0)
return (SDRC_ERROR);
snode = tree->t_snode;
fsid = SMB_NODE_FSID(snode);
switch (infolev) {
case SMB_INFO_ALLOCATION:
if ((rc = smb_fsop_statfs(sr->user_cr, snode, &df)) != 0) {
smbsr_errno(sr, rc);
return (SDRC_ERROR);
}
max_int = (uint64_t)UINT_MAX;
if (df.f_blocks > max_int)
df.f_blocks = max_int;
if (df.f_bavail > max_int)
df.f_bavail = max_int;
total_units = (uint32_t)df.f_blocks;
avail_units = (uint32_t)df.f_bavail;
length = 512;
sect_per_unit = df.f_frsize >> 9;
if (avail_units > total_units)
avail_units = 0;
(void) smb_mbc_encodef(&xa->rep_data_mb, "llllw",
0, /* file system ID. NT rets 0 */
sect_per_unit, /* sectors/unit */
total_units, /* total units */
avail_units, /* avail units */
length); /* bytes/sector */
break;
case SMB_INFO_VOLUME:
length = strlen(tree->t_volume);
encode_str = "%lbs";
(void) smb_mbc_encodef(&xa->rep_data_mb, encode_str, sr,
fsid.val[0], length, tree->t_volume);
break;
case SMB_QUERY_FS_VOLUME_INFO:
if ((sr->smb_flg2 & SMB_FLAGS2_UNICODE) ||
(sr->session->native_os == NATIVE_OS_WIN95)) {
length = mts_wcequiv_strlen(tree->t_volume);
encode_str = "%qllb.U";
} else {
length = strlen(tree->t_volume);
encode_str = "%qllb.s";
}
/*
* NT has the "supports objects" flag set to 1.
*/
(void) smb_mbc_encodef(&xa->rep_data_mb, encode_str, sr,
0ll, /* Volume creation time */
fsid.val[0], /* Volume serial number */
length, /* label length */
0, /* Supports objects */
tree->t_volume);
break;
case SMB_QUERY_FS_SIZE_INFO:
if ((rc = smb_fsop_statfs(sr->user_cr, snode, &df)) != 0) {
smbsr_errno(sr, rc);
return (SDRC_ERROR);
}
length = 512;
sect_per_unit = df.f_frsize >> 9;
if (df.f_bavail > df.f_blocks)
df.f_bavail = 0;
(void) smb_mbc_encodef(&xa->rep_data_mb, "qqll",
df.f_blocks, /* total units */
df.f_bavail, /* avail units */
sect_per_unit, /* sectors/unit */
length); /* bytes/sector */
break;
case SMB_QUERY_FS_DEVICE_INFO:
(void) smb_mbc_encodef(&xa->rep_data_mb, "ll",
FILE_DEVICE_FILE_SYSTEM,
FILE_DEVICE_IS_MOUNTED);
break;
case SMB_QUERY_FS_ATTRIBUTE_INFO:
if ((sr->smb_flg2 & SMB_FLAGS2_UNICODE) ||
(sr->session->native_os == NATIVE_OS_WINNT) ||
(sr->session->native_os == NATIVE_OS_WIN2000) ||
(sr->session->native_os == NATIVE_OS_WIN95) ||
(sr->session->native_os == NATIVE_OS_MACOS)) {
length = mts_wcequiv_strlen(fsname);
encode_str = "%lllU";
sr->smb_flg2 |= SMB_FLAGS2_UNICODE;
} else {
length = strlen(fsname);
encode_str = "%llls";
}
flags = FILE_CASE_PRESERVED_NAMES;
if (tree->t_flags & SMB_TREE_UNICODE_ON_DISK)
flags |= FILE_UNICODE_ON_DISK;
if (tree->t_flags & SMB_TREE_SUPPORTS_ACLS)
flags |= FILE_PERSISTENT_ACLS;
if ((tree->t_flags & SMB_TREE_CASEINSENSITIVE) == 0)
flags |= FILE_CASE_SENSITIVE_SEARCH;
if (tree->t_flags & SMB_TREE_STREAMS)
flags |= FILE_NAMED_STREAMS;
if (smb_announce_quota)
flags |= FILE_VOLUME_QUOTAS;
(void) smb_mbc_encodef(&xa->rep_data_mb, encode_str, sr,
flags,
MAXNAMELEN, /* max name */
length, /* label length */
fsname);
break;
default:
smbsr_error(sr, 0, ERRDOS, ERRunknownlevel);
return (SDRC_ERROR);
}
return (SDRC_SUCCESS);
}