Tracciare le query
Quando si tracciano le query eseguite, viene trovata la query seguente che elenca le cartelle sulle unità una per una.
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
La funzione principale utilizzata è sys.dm_os_enumerate_filesystem
, per ogni cartella aperta, passa a un livello più profondo, un esempio di secondo livello:
select @Path = N'D:\Data\'
Per accessi regolari
Per accessi regolari è facile come negare le autorizzazioni di selezione su questo TVF per rendere l'utente non in grado di elencare le cartelle.
DENY SELECT ON master.sys.dm_os_enumerate_filesystem TO [Domain\LoginName]
Quando si tenta di selezionare un backup, l'utente dovrebbe visualizzare questo messaggio:
L'utente sarà quindi in grado di vedere solo le lettere di unità.
Per utenti contenuti
Per l'utente contenuto, negare direttamente la selezione sul TVF non funziona
L'utente contenuto può eseguire correttamente l'esempio di query successivo
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
E .... questo non funziona:
use [PartialDb]
GO
DENY SELECT ON [sys].[dm_os_enumerate_filesystem] TO [PartialUser];
GO
Messaggio 4629, livello 16, stato 10, riga 34 Le autorizzazioni per le viste del catalogo con ambito server o le procedure archiviate di sistema o le procedure memorizzate estese possono essere concesse solo quando il database corrente è master.
Le istruzioni seguenti funzionano ma non limitano l'utente, anche se non fa parte del dbrole
ruolo
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];
Che cosa funziona? In teoria
Poiché l'utente contenuto utilizza l'account guest / ruolo pubblico per connettersi e selezionare da DMV (il ruolo pubblico ha accesso a determinati oggetti per impostazione predefinita), potremmo provare a limitare il ruolo pubblico.
Questo non è l'ideale a causa di una serie di motivi. Ad esempio, nega> concedi e, di conseguenza, solo i membri nel sysadmin
ruolo potranno selezionare da questo TVF.
Un'altra cosa importante da notare è che cambiare il ruolo utente / pubblico dell'ospite può avere effetti collaterali sconosciuti sull'istanza o su determinate funzionalità.
USE MASTER
GO
DENY SELECT ON [sys].[dm_os_enumerate_filesystem] TO public;
GO
La modifica delle autorizzazioni pubbliche / guest non è uno scenario ideale.
Ad esempio, la disabilitazione dell'utente guest può interrompere il database msdb .
Riesecuzione della selezione nel contesto dell'utente contenuto:
Messaggio 229, livello 14, stato 5, riga 7 L'autorizzazione SELECT è stata negata sull'oggetto "dm_os_enumerate_filesystem", database "mssqlsystemresource", schema "sys".
Potrebbe esserci o meno un modo per aggirare questo approccio tutt'altro che ideale, non l'ho trovato.
Un esempio delle autorizzazioni del ruolo pubblico:
Questi sono concessi per un motivo, poiché tali funzionalità potrebbero rompersi quando si negano / revocano questi oggetti. Procedi con cautela.
Altre informazioni sull'utente ospite / ruolo pubblico qui