Śledzenie zapytań
Podczas śledzenia wykonanych zapytań znajduje się poniższe zapytanie, które wyświetla kolejno foldery na dyskach.
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
Główną zastosowaną funkcją jest to sys.dm_os_enumerate_filesystem
, że do każdego otwieranego folderu idzie on poziom głębiej, przykład drugiego poziomu:
select @Path = N'D:\Data\'
Do regularnego logowania
W przypadku zwykłego logowania jest to tak proste, jak odmowa wyboru uprawnień w tym TVF, aby użytkownik nie mógł wyświetlić listy folderów.
DENY SELECT ON master.sys.dm_os_enumerate_filesystem TO [Domain\LoginName]
Próbując wybrać kopię zapasową, użytkownik powinien zobaczyć ten komunikat:
Użytkownik będzie wtedy widział tylko litery dysków.
Dla zamkniętych użytkowników
W przypadku zamkniętego użytkownika odmowa wyboru bezpośrednio w TVF nie działa
Zawarty użytkownik może pomyślnie uruchomić następny przykład zapytania
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
I .... to nie działa:
use [PartialDb]
GO
DENY SELECT ON [sys].[dm_os_enumerate_filesystem] TO [PartialUser];
GO
Msg 4629, poziom 16, stan 10, wiersz 34 Uprawnienia do widoków katalogu o zasięgu serwera lub systemowych procedur przechowywanych lub rozszerzonych procedur przechowywanych można przyznać tylko wtedy, gdy bieżąca baza danych jest nadrzędna.
Poniższe instrukcje działają, ale nie ograniczają użytkownika, nawet jeśli nie jest to częścią dbrole
roli
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];
Co działa W teorii
Ponieważ zawarty użytkownik używa konta gościa / roli publicznej do łączenia się i wybierania spośród dmv, (rola publiczna domyślnie ma dostęp do niektórych obiektów), możemy spróbować ograniczyć rolę publiczną.
Nie jest to idealne rozwiązanie z wielu powodów. Na przykład odmów> dotuj, w wyniku czego tylko członkowie w sysadmin
roli będą mogli wybierać z tego TVF.
Inną ważną rzeczą, na którą należy zwrócić uwagę, jest to, że zmiana roli gościa / roli publicznej może mieć nieznane skutki uboczne dla instancji lub niektórych funkcji.
USE MASTER
GO
DENY SELECT ON [sys].[dm_os_enumerate_filesystem] TO public;
GO
Zmiana uprawnień publicznych / gości nie jest idealnym scenariuszem.
Na przykład wyłączenie użytkownika-gościa może uszkodzić bazę danych msdb .
Uruchom ponownie zaznaczenie w kontekście zawartego użytkownika:
Msg 229, poziom 14, stan 5, wiersz 7 Odmówiono uprawnienia SELECT do obiektu „dm_os_enumerate_filesystem”, baza danych „mssqlsystemresource”, schemat „sys”.
Może być lub może być sposób na obejście tego dalekiego od idealnego podejścia, nie znalazłem go.
Przykład uprawnień roli publicznej:
Są one przyznawane z określonego powodu, ponieważ niektóre funkcje mogą ulec awarii podczas odmowy / odwołania tych obiektów. Postępuj ostrożnie.
Więcej informacji na temat roli gościa / roli publicznej tutaj
USE MASTER; DENY SELECT ON [sys].[dm_os_enumerate_fixed_drives] TO public; DENY SELECT ON [sys].[dm_os_enumerate_filesystem] TO public; USE msdb; DENY SELECT ON msdb.dbo.backupset TO public;
Jak dotąd nie napotkałem na to problemów, ale nie przeprowadziłem też intensywnych testów.Ciągle znajduję więcej tabel, które przeciekają informacje o innych bazach danych, dlatego postanowiłem opublikować ten zbiór rzeczy, które blokuję, do roli publicznej. Wydaje się, że nie wpływają one na funkcjonalność db, choć nie biorę za to odpowiedzialności, ponieważ używam tylko niewielkiego podzbioru tego, co faktycznie oferuje SQL Server. Może być tak, że psuje to coś, czego nie jestem świadomy.
źródło