Chciałbym napisać zapytanie na SQL 2008, które zgłosi wszystkich użytkowników, którzy mają dostęp do określonej bazy danych lub obiektów w bazie danych, takich jak tabele, widoki i procedury składowane, bezpośrednio lub z powodu ról itp. To raport zostanie wykorzystany do celów audytu bezpieczeństwa. Nie jestem pewien, czy ktoś ma zapytanie, które całkowicie spełni moje potrzeby, ale mam nadzieję, że coś takiego da mi dobry początek. Albo SQL 2008, 2005 lub 2000 zrobi, prawdopodobnie mogę przekonwertować w razie potrzeby.
191
Odpowiedzi:
To mój pierwszy trzask przy zapytaniu, oparty na sugestiach Andomara. To zapytanie ma na celu przedstawienie listy uprawnień, które użytkownik zastosował bezpośrednio do konta użytkownika lub poprzez role, które użytkownik ma.
źródło
login_token
zmieniono nauser_token
Oto pełna wersja zapytania Jeremy z sierpnia 2011 r. Z uwzględnieniem zmian sugerowanych przez Brada (październik 2011 r.) I iw.kuchin (maj 2012 r.):
[ObjectType]
i[ObjectName]
dla schematów.[ObjectType]
lepiej używaćobj.type_desc
tylko dlaOBJECT_OR_COLUMN
klasy uprawnień. We wszystkich innych przypadkach użyjperm.[class_desc]
.IMPERSONATE
uprawnienia.sys.login_token
zesys.server_principals
jak pokaże także SQL Logowania nie tylko te Windows.sys
i INFORMACJE_SCHEMA.Mam nadzieję, że uratuje to kogoś jeszcze godzinę lub dwie osoby.
:)
źródło
sys.login_token
niesys.server_principals
jest obsługiwany , ani nie trzeba go zastępowaćsys.user_token
Począwszy od SQL Server 2005, możesz do tego używać widoków systemu. Na przykład to zapytanie zawiera listę wszystkich użytkowników w bazie danych z ich prawami:
Pamiętaj, że użytkownik może również mieć uprawnienia poprzez rolę. Na przykład
db_data_reader
rola przyznajeselect
prawa do większości obiektów.źródło
select * from sys.database_principals where type_desc = 'EXTERNAL_GROUP'
), podczas gdy zaakceptowana odpowiedź nie, nawet po naprawieniusys.user_token
.SELECT PrincipalName = p.[name], p.[type_desc], dp.[permission_name], dp.[state_desc], CASE dp.class_desc WHEN 'DATABASE' THEN DB_NAME(dp.major_id) WHEN 'SCHEMA' THEN SCHEMA_NAME(dp.major_id) WHEN 'OBJECT_OR_COLUMN' THEN CONCAT_WS('.', OBJECT_SCHEMA_NAME(dp.major_id), OBJECT_NAME(dp.major_id), c.[name]) END FROM sys.database_principals AS p LEFT OUTER JOIN sys.database_permissions AS dp ON p.principal_id = dp.grantee_principal_id LEFT OUTER JOIN sys.columns AS c ON dp.major_id = c.[object_id] AND dp.minor_id = c.column_id
Nie mogę skomentować zaakceptowanej odpowiedzi, więc dodam tutaj kilka komentarzy:
sys.objects
tabela referencyjna zawiera tylko obiekty o zasięgu schematu. Aby uzyskać informacje o obiektach „wyższego poziomu” (tj. Schematach w naszym przypadku), musisz użyćsys.schemas
tabeli.[ObjectType]
lepiej jest używaćobj.type_desc
tylko doOBJECT_OR_COLUMN
klasy uprawnień. We wszystkich innych przypadkach użyjperm.[class_desc]
IMPERSONATE
. Aby uzyskać informacje o podszywaniu się, należyLEFT JOIN
jesys.database_principals
włączyćperm.major_id = imp.principal_id
sys.login_token
zesys.server_principals
jak pokaże także SQL Logowania nie tylko te Okienka'G'
do dozwolonych głównych typów, aby umożliwić grupy Windowssys
iINFORMATION_SCHEMA
wynikową tabelę, ponieważ ci użytkownicy są wykorzystywani tylko do obsługiZamieszczę pierwszy fragment skryptu ze wszystkimi proponowanymi poprawkami, inne części również powinny zostać zmienione:
źródło
sysadmin
+securityadmin
są mapowane tak, jakdbo
dla każdej bazy danych na serwerze + istnieje pozwolenie na serwer,CONTROL SERVER
które może zostać przyznane użytkownikowi. Zezwolenie to daje prawie takie same prawa jak istnieniesysadmin
.Niesamowity skrypt Jeremy i współautorzy! Dzięki!
Mam mnóstwo użytkowników, więc uruchomienie tego dla wszystkich użytkowników było koszmarem. Nie mogłem dodawać komentarzy, więc publikuję cały skrypt ze zmianami. Dodałem zmienną + klauzulę, dzięki czemu mogę wyszukiwać w nazwie użytkownika wszystko, co pasuje do 5 znaków (lub wszystkich użytkowników, gdy pozostaną puste). Nic specjalnego, ale pomyślałem, że będzie to pomocne w niektórych przypadkach użycia.
źródło
W innych odpowiedziach, które widziałem, brakuje niektórych uprawnień, które są możliwe w bazie danych. Pierwsze zapytanie w poniższym kodzie uzyska uprawnienia na poziomie bazy danych dla wszystkiego , co nie jest obiektem systemowym. Generuje również odpowiednie instrukcje GRANT. Drugie zapytanie otrzymuje wszystkie role.
Tę operację należy uruchomić dla każdej bazy danych, ale jest ona zbyt długa, aby używać jej ze sp_MSforeachdb. Jeśli chcesz to zrobić, musisz dodać go do głównej bazy danych jako systemową procedurę składowaną.
Aby uwzględnić wszystkie możliwości, musisz mieć skrypt sprawdzający uprawnienia na poziomie serwera.
AKTUALIZACJA: Poniższe zapytania będą pobierać uprawnienia na poziomie serwera i członkostwa.
źródło
Oto moja wersja, dostosowana od innych. Spędziłem właśnie 30 minut, próbując sobie przypomnieć, jak to wymyśliłem, a odpowiedź @Jeremy'ego wydaje się być główną inspiracją. Nie chciałem aktualizować odpowiedzi Jeremy'ego, na wypadek, gdy wprowadziłem błędy, więc zamieszczam tutaj swoją wersję.
Sugeruję sparowanie pełnego skryptu z inspiracją zaczerpniętą z wtyczki T-SQL Kennetha Fishera: Jakie uprawnienia ma dany użytkownik? : Umożliwi to udzielenie odpowiedzi na pytania dotyczące zgodności / audytu oddolnie, a nie odgórnie.
Aby zrozumieć, co to obejmuje, rozważ
Contoso\DB_AdventureWorks_Accounting
grupę Windows AD Group z członkiemContoso\John.Doe
. John.Doe uwierzytelnia się w AdventureWorks za pośrednictwem server_principalContoso\DB_AdventureWorks_Logins
Windows AD Group. Jeśli ktoś zapyta: „Jakie uprawnienia ma John.Doe?”, Nie możesz odpowiedzieć na to pytanie za pomocą poniższego skryptu. Musisz następnie iterować każdy wiersz zwrócony przez poniższy skrypt i dołączyć go do powyższego skryptu. (Konieczne może być również znormalizowanie nieaktualnychname
wartości poprzez wyszukiwanie identyfikatora SID u dostawcy usługi Active Directory).Oto skrypt, który nie zawiera takiej logiki wyszukiwania wstecznego.
źródło
źródło
Powyższa procedura przechowywana GetPermissions jest dobra, jednak używa Sp_msforeachdb, co oznacza, że ulegnie awarii, jeśli Twoja instancja SQL ma nazwy baz danych zawierające spacje lub myślniki oraz inne znaki, które nie są najlepszymi praktykami. Stworzyłem wersję, która unika używania Sp_msforeachdb i zawiera również dwie kolumny wskazujące 1 - jeśli Login jest loginem sysadmin (IsSysAdminLogin) i 2 - jeśli login jest użytkownikiem osieroconym (IsEmptyRow).
źródło
you can use [] to resolve it. sp_msforeachdb ' use [?] select db_name()'
zakładam, że jego odpowiedź miała być komentarzem, ale ponieważ jego konto nie spełnia minimalnej reputacji, zamiast tego opublikował odpowiedź.Próbowałem prawie wszystkich z nich, ale szybko zauważyłem, że niektórych brakuje, zwłaszcza użytkowników sysadmin. Taka dziura nie będzie dobrze wyglądać w nadchodzącym audycie, więc to właśnie wymyśliłem
źródło
Z powodu niskiej liczby przedstawicieli nie może odpowiedzieć tym osobom, które proszą o uruchomienie tego na wielu bazach danych / serwerach SQL.
Utwórz zarejestrowaną grupę serwerów i przeprowadź do nich zapytanie, a następnie przewiń bazy danych:
Ten wątek ogromnie pomógł mi wszystkim podziękować!
źródło
DB_NAME()
i przechowywanie danych wyjściowych w tabeli tymczasowej, aby uniknąć skończenia wielu zestawów wyników. Dzięki!Wielkie dzięki za niesamowite skrypty kontrolne.
Zdecydowanie polecam dla użytkowników korzystających z audytu niesamowite procedury składowane Kenneth Fisher ( b | t ):
źródło
Proste zapytanie, które pokazuje tylko, czy jesteś SysAdmin, czy nie:
źródło
Niestety nie mogłem skomentować posta Seana Rose'a z powodu niewystarczającej reputacji, jednak musiałem zmienić część „publicznego” skryptu, ponieważ nie pokazywał on uprawnień o zasięgu SCHEMA z powodu (INNER) JOIN przeciwko sys. przedmioty Po tym, jak został zmieniony na POŁĄCZENIE W LEWO, musiałem dodatkowo zmienić logikę klauzuli WHERE, aby pominąć obiekty systemowe. Moje poprawione zapytanie o publiczne perms znajduje się poniżej.
źródło
Jeśli chcesz sprawdzić dostęp do baz danych dla konkretnego loginu, skorzystaj z tego prostego skryptu, jak poniżej:
sys.sp_helplogins @LoginNamePattern = 'Domena \ login' - nazwa systemu
źródło
--ok, moja kolej, aby wesprzeć, ciesz się
Ten nagłówek raportu dynamicznie pobiera nazwę wystąpienia SQL, datę \ czas i nazwę konta, z którego korzysta raport, wszystkie rzeczy, o których dobry biegły rewident będzie chciał wiedzieć. :)
Uwaga - jeśli masz rozszerzoną właściwość o nazwie „środowisko” w głównej bazie danych, wartość (cokolwiek użyjesz: PreProd, Programowanie, Produkcja, DR itp.) Zostanie uwzględniona w nagłówku raportu.
KONIEC
- świetny do zapisania jako przechowywany proc
źródło