Відстеження запитів
Під час відстеження виконаних запитів нижче знайдено запит, який перераховує папки на накопичувачах одна за одною.
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
, що для кожної папки, що відкривається, вона йде на рівень глибше, приклад другого рівня:
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
Msg 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, (загальнодоступна роль має доступ до певних об'єктів за замовчуванням), ми можемо спробувати обмежити публічну роль.
Це не ідеально через низку причин. Наприклад, відмовити> надавати, і в результаті лише учасники sysadmin
ролі зможуть вибрати з цього ТВФ.
Ще одна важлива річ, яку слід зазначити, це те, що зміна ролі гостя користувача / громадськості може мати невідомі побічні ефекти на екземпляр або певні функції.
USE MASTER
GO
DENY SELECT ON [sys].[dm_os_enumerate_filesystem] TO public;
GO
Зміна дозволів громадськості та гостей не є ідеальним сценарієм.
Наприклад, відключення гостьового користувача може зламати базу даних msdb .
Поновлення вибору в контексті користувача, що міститься:
Msg 229, рівень 14, стан 5, рядок 7 Дозвіл SELECT відмовлено в об'єкті "dm_os_enumerate_filesystem", базі даних "mssqlsystemresource", схемі "sys".
Може бути, а може і не бути способу, який би не був ідеальним підходом, я не знайшов.
Приклад дозволів громадської ролі:
Вони надаються з причини, оскільки такі функції можуть порушитися при відмові / відкликанні цих об'єктів. Продовжуйте обережно.
Більше інформації про гостьового користувача / громадську роль тут