クエリのトレース
実行されたクエリをトレースすると、ドライブ上のフォルダを1つずつ一覧表示する以下のクエリが見つかります。
declare @Path nvarchar(255)
declare @Name nvarchar(255)
select @Path = N'D:\'
select @Name = null;
create table #filetmpfin (Name nvarchar(255) NOT NULL, IsFile bit NULL, FullName nvarchar(300) not NULL)
declare @FullName nvarchar(300)
if exists (select 1 from sys.all_objects where name = 'dm_os_enumerate_filesystem' and type = 'IF' and is_ms_shipped = 1)
begin
if (@Name is null)
begin
insert #filetmpfin select file_or_directory_name, 1 - is_directory, full_filesystem_path from sys.dm_os_enumerate_filesystem(@Path, '*') where [level] = 0
end
if (NOT @Name is null)
begin
if(@Path is null)
select @FullName = @Name
else
select @FullName = @Path + convert(nvarchar(1), serverproperty('PathSeparator')) + @Name
create table #filetmp3 ( Exist bit NOT NULL, IsDir bit NOT NULL, DirExist bit NULL )
insert #filetmp3 select file_exists, file_is_a_directory, parent_directory_exists from sys.dm_os_file_exists(@FullName)
insert #filetmpfin select @Name, 1-IsDir, @FullName from #filetmp3 where Exist = 1 or IsDir = 1
drop table #filetmp3
end
end
else
begin
if(@Name is null)
begin
if (right(@Path, 1) = '\')
select @Path= substring(@Path, 1, len(@Path) - charindex('\', reverse(@Path)))
create table #filetmp (Name nvarchar(255) NOT NULL, depth int NOT NULL, IsFile bit NULL )
insert #filetmp EXECUTE master.dbo.xp_dirtree @Path, 1, 1
insert #filetmpfin select Name, IsFile, @Path + '\' + Name from #filetmp f
drop table #filetmp
end
if(NOT @Name is null)
begin
if(@Path is null)
select @FullName = @Name
else
select @FullName = @Path + '\' + @Name
if (right(@FullName, 1) = '\')
select @Path= substring(@Path, 1, len(@FullName) - charindex('\', reverse(@FullName)))
create table #filetmp2 ( Exist bit NOT NULL, IsDir bit NOT NULL, DirExist bit NULL )
insert #filetmp2 EXECUTE master.dbo.xp_fileexist @FullName
insert #filetmpfin select @Name, 1-IsDir, @FullName from #filetmp2 where Exist = 1 or IsDir = 1
drop table #filetmp2
end
end
SELECT
Name AS [Name],
IsFile AS [IsFile],
FullName AS [FullName]
FROM
#filetmpfin
ORDER BY
[IsFile] ASC,[Name] ASC
drop table #filetmpfin
使用される主な機能はsys.dm_os_enumerate_filesystem
、開かれたフォルダごとに、1つ下のレベルに進み、2番目のレベルの例です。
select @Path = N'D:\Data\'
通常のログインの場合
通常のログインの場合、このTVFの選択権限を拒否するのと同じくらい簡単で、ユーザーはフォルダーを一覧表示できません。
DENY SELECT ON master.sys.dm_os_enumerate_filesystem TO [Domain\LoginName]
バックアップを選択しようとすると、次のメッセージが表示されます。
その後、ユーザーはドライブ文字のみを表示できます。
封じ込めユーザー向け
包含ユーザーの場合、TVFでの選択の拒否は直接機能しません
含まれているユーザーは次のクエリの例を正常に実行できます
declare @Path nvarchar(255)
declare @Name nvarchar(255)
select @Path = N'D:\'
select file_or_directory_name, 1 - is_directory, full_filesystem_path from sys.dm_os_enumerate_filesystem(@Path, '*') where [level] = 0
そして...これはうまくいきません:
use [PartialDb]
GO
DENY SELECT ON [sys].[dm_os_enumerate_filesystem] TO [PartialUser];
GO
メッセージ4629、レベル16、状態10、行34サーバースコープのカタログビュー、システムストアドプロシージャ、または拡張ストアドプロシージャのアクセス許可は、現在のデータベースがマスターである場合にのみ付与できます。
以下のステートメントは機能しますが、dbrole
役割の一部でなくても、ユーザーを制限しません
DENY VIEW DATABASE STATE TO [PartialUser];
DENY VIEW DEFINITION ON SCHEMA :: information_schema TO [PartialUser];
DENY VIEW DEFINITION ON SCHEMA :: sys TO [PartialUser];
DENY SELECT ON SCHEMA :: information_schema TO [PartialUser];
DENY SELECT ON SCHEMA :: sys TO [PartialUser];
何が機能しますか? 理論的には
含まれているユーザーはゲストアカウント/パブリックロールを使用して接続し、dmvから選択するため(パブリックロールはデフォルトで特定のオブジェクトにアクセスできます)、パブリックロールを制限してみることができます。
これはいくつかの理由により理想的ではありません。たとえば、deny> grantとすると、sysadmin
ロールのメンバーのみがこのTVFから選択できます。
注意すべきもう1つの重要な点は、ゲストユーザー/パブリックロールを変更すると、インスタンスまたは特定の機能に未知の副作用が生じる可能性があることです。
USE MASTER
GO
DENY SELECT ON [sys].[dm_os_enumerate_filesystem] TO public;
GO
パブリック/ゲスト権限を変更することは理想的なシナリオではありません。
たとえば、ゲストユーザーを無効にすると、msdbデータベースが破損する可能性があります。
含まれているユーザーのコンテキストで選択を再実行します。
メッセージ229、レベル14、状態5、行7オブジェクト 'dm_os_enumerate_filesystem'、データベース 'mssqlsystemresource'、スキーマ 'sys'に対するSELECT権限が拒否されました。
理想的なアプローチから遠く離れている方法があるかもしれないし、ないかもしれません、私はそれを見つけていません。
パブリックロールの権限の例:
これらは、これらのオブジェクトを拒否または取り消すと特定の機能が機能しなくなる可能性があるため、許可されます。注意して続行してください。
ゲストユーザー/パブリックロールの詳細については、こちらをご覧ください