Traçage des requêtes
Lors du suivi des requêtes exécutées, la requête ci-dessous répertorie les dossiers sur les lecteurs un par un.
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 fonction principale utilisée est sys.dm_os_enumerate_filesystem
, pour chaque dossier ouvert, elle va plus loin, un exemple de deuxième niveau:
select @Path = N'D:\Data\'
Pour les connexions régulières
Pour les connexions régulières, il est aussi simple que de refuser les autorisations de sélection sur ce TVF pour empêcher l'utilisateur de répertorier les dossiers.
DENY SELECT ON master.sys.dm_os_enumerate_filesystem TO [Domain\LoginName]
Lorsqu'il essaie de sélectionner une sauvegarde, l'utilisateur devrait voir ce message:
L'utilisateur ne pourra alors voir que les lettres de lecteur.
Pour les utilisateurs confinés
Pour l'utilisateur confiné, refuser directement la sélection sur le TVF ne fonctionne pas
L'utilisateur contenu peut exécuter avec succès l'exemple de requête suivant
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
Et .... cela ne fonctionne pas:
use [PartialDb]
GO
DENY SELECT ON [sys].[dm_os_enumerate_filesystem] TO [PartialUser];
GO
Msg 4629, niveau 16, état 10, ligne 34 Les autorisations sur les vues de catalogue étendues au serveur ou les procédures stockées système ou les procédures stockées étendues ne peuvent être accordées que lorsque la base de données actuelle est maître.
Les instructions ci-dessous fonctionnent mais ne restreignent pas l'utilisateur, même si cela ne fait pas partie du dbrole
rôle
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];
Qu'est-ce qui fonctionne? En théorie
Étant donné que l'utilisateur contenu utilise le compte invité / le rôle public pour se connecter et sélectionner parmi les dmv, (le rôle public a accès à certains objets par défaut), nous pourrions essayer de restreindre le rôle public.
Ce n'est pas idéal pour plusieurs raisons. Par exemple, refuser> accorder et par conséquent, seuls les membres du sysadmin
rôle pourront sélectionner dans ce TVF.
Une autre chose importante à noter est que la modification du rôle d'utilisateur invité / public peut avoir des effets secondaires inconnus sur l'instance ou certaines fonctionnalités.
USE MASTER
GO
DENY SELECT ON [sys].[dm_os_enumerate_filesystem] TO public;
GO
La modification des autorisations publiques / invité n'est pas un scénario idéal.
Par exemple, la désactivation de l'utilisateur invité peut casser la base de données msdb .
Relancez la sélection dans le contexte de l'utilisateur contenu:
Msg 229, niveau 14, état 5, ligne 7 L'autorisation SELECT a été refusée sur l'objet 'dm_os_enumerate_filesystem', base de données 'mssqlsystemresource', schéma 'sys'.
Il peut y avoir ou non un moyen de contourner cette approche loin d'être idéale, je ne l'ai pas trouvée.
Un exemple des autorisations du rôle public:
Celles-ci sont accordées pour une raison, car de telles fonctionnalités peuvent se casser lors du refus / de la révocation de ces objets. Procéder avec prudence.
Plus d'informations sur le rôle d'utilisateur invité / public ici