Ich möchte eine Abfrage auf einem SQL 2008 schreiben, die alle Benutzer meldet, die Zugriff auf eine bestimmte Datenbank oder Objekte in der Datenbank haben, z. B. Tabellen, Ansichten und gespeicherte Prozeduren, entweder direkt oder aufgrund von Rollen usw. Dies Der Bericht würde für Sicherheitsüberprüfungszwecke verwendet. Ich bin mir nicht sicher, ob jemand eine Anfrage hat, die meinen Anforderungen vollständig entspricht, aber hoffentlich etwas, das mir einen guten Start ermöglicht. Entweder SQL 2008, 2005 oder 2000 reicht aus, ich kann wahrscheinlich nach Bedarf konvertieren.
191
Antworten:
Dies ist mein erster Riss bei einer Anfrage, basierend auf Andomars Vorschlägen. Diese Abfrage soll eine Liste von Berechtigungen bereitstellen, die ein Benutzer entweder direkt auf das Benutzerkonto oder über Rollen des Benutzers angewendet hat.
quelle
login_token
geändert inuser_token
Hier ist eine vollständige Version von Jeremys Abfrage vom August 2011 mit den von Brad (Oktober 2011) und iw.kuchin (Mai 2012) vorgeschlagenen Änderungen:
[ObjectType]
und[ObjectName]
für Schemata.[ObjectType]
es besser ist , zu verwenden ,obj.type_desc
nur fürOBJECT_OR_COLUMN
Berechtigungsklasse. Für alle anderen Fälle verwendenperm.[class_desc]
.IMPERSONATE
Berechtigungen.sys.login_token
durch,sys.server_principals
da auch SQL- Anmeldungen angezeigt werden, nicht nur Windows-Anmeldungen.sys
und INFORMATION_SCHEMA ausschließen.Hoffentlich rettet dies jemand anderem ein oder zwei Stunden seines Lebens.
:)
quelle
sys.login_token
nochsys.server_principals
unterstützt und muss durchsys.user_token
Ab SQL Server 2005 können Sie dafür Systemansichten verwenden. Diese Abfrage listet beispielsweise alle Benutzer in einer Datenbank mit ihren Rechten auf:
Beachten Sie, dass ein Benutzer auch über eine Rolle Rechte haben kann. Beispielsweise
db_data_reader
gewährt die Rolleselect
Rechte für die meisten Objekte.quelle
select * from sys.database_principals where type_desc = 'EXTERNAL_GROUP'
), wohingegen akzeptierte Antworten dies auch nach dem Reparieren nicht tunsys.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
Ich kann die akzeptierte Antwort nicht kommentieren, daher füge ich hier einige Kommentare hinzu:
sys.objects
enthält nur Objekte mit Schemabereich. Um Informationen über "übergeordnete" Objekte (in unserem Fall Schemata) zu erhalten, müssen Sie diesys.schemas
Tabelle verwenden.[ObjectType]
es ist besser,obj.type_desc
nur für dieOBJECT_OR_COLUMN
Berechtigungsklasse zu verwenden. Für alle anderen Fälle verwendenperm.[class_desc]
IMPERSONATE
. Um Informationen über Identitätswechsel zu erhalten, sollte manLEFT JOIN
mitsys.database_principals
anperm.major_id = imp.principal_id
sys.login_token
mitsys.server_principals
wie sie zeigen auch SQL - Anmeldungen, nicht nur diejenigen von Windows'G'
zulässige Haupttypen hinzufügen , um Windows-Gruppen zuzulassensys
undINFORMATION_SCHEMA
aus der resultierenden Tabelle ausschließen, da diese Benutzer nur für den Dienst verwendet werdenIch werde das erste Skript mit allen vorgeschlagenen Korrekturen veröffentlichen. Andere Teile sollten ebenfalls geändert werden:
quelle
sysadmin
+securityadmin
werden wiedbo
für jede Datenbank auf dem Server zugeordnet + es gibt ServerberechtigungenCONTROL SERVER
, die dem Benutzer erteilt werden könnten. Diese Erlaubnis gibt fast die gleichen Rechte wie seinsysadmin
.Tolles Drehbuch Jeremy und Mitwirkende! Vielen Dank!
Ich habe eine Menge Benutzer, daher war es ein Albtraum, dies für alle Benutzer auszuführen. Ich konnte keine Kommentare hinzufügen, daher veröffentliche ich das gesamte Skript mit den Änderungen. Ich habe eine Variable + where-Klausel hinzugefügt, damit ich nach allem suchen kann, was mit bis zu 5 Zeichen im Benutzernamen übereinstimmt (oder nach allen Benutzern, wenn sie leer bleiben). Nichts Besonderes, aber ich dachte, es wäre in einigen Anwendungsfällen hilfreich.
quelle
Bei den anderen Antworten, die ich gesehen habe, fehlen einige Berechtigungen, die in der Datenbank möglich sind. Die erste Abfrage im folgenden Code erhält die Berechtigung auf Datenbankebene für alles , was kein Systemobjekt ist. Es werden auch die entsprechenden GRANT-Anweisungen generiert. Die zweite Abfrage erhält alle Rollen-Mitgliedschaften.
Dies muss für jede Datenbank ausgeführt werden, ist jedoch zu lang, um mit sp_MSforeachdb verwendet zu werden. Wenn Sie dies tun möchten, müssen Sie es als gespeicherte Systemprozedur zur Master-Datenbank hinzufügen.
Um alle Möglichkeiten abzudecken, benötigen Sie außerdem ein Skript, das die Berechtigungen auf Serverebene überprüft.
UPDATE: Mit den folgenden Abfragen werden Berechtigungen und Mitgliedschaften auf Serverebene abgerufen.
quelle
Hier ist meine Version, angepasst von anderen. Ich habe gerade 30 Minuten damit verbracht, mich daran zu erinnern, wie ich darauf gekommen bin, und @Jeremys Antwort scheint die Hauptinspiration zu sein. Ich wollte Jeremys Antwort nicht aktualisieren, nur für den Fall, dass ich Fehler einführte, also poste ich meine Version hier.
Ich schlage vor, das vollständige Skript mit einer Inspiration aus Kenneth Fischers T-SQL-Dienstag zu kombinieren: Welche Berechtigungen hat ein bestimmter Benutzer? : Auf diese Weise können Sie Compliance- / Prüfungsfragen von unten nach oben und nicht von oben nach unten beantworten.
Betrachten Sie die
Contoso\DB_AdventureWorks_Accounting
Windows AD-Gruppe mit Mitglied, um zu verstehen, was dies abdecktContoso\John.Doe
. John.Doe authentifiziert sich bei AdventureWorks über dieContoso\DB_AdventureWorks_Logins
Windows AD-Gruppe server_principal . Wenn Sie jemand fragt: "Welche Berechtigungen hat John.Doe?", Können Sie diese Frage nicht mit dem folgenden Skript beantworten. Sie müssen dann jede vom folgenden Skript zurückgegebene Zeile durchlaufen und mit dem obigen Skript verknüpfen. (Möglicherweise müssen Sie auch veraltetename
Werte normalisieren, indem Sie die SID in Ihrem Active Directory-Anbieter nachschlagen.)Hier ist das Skript, ohne eine solche Reverse-Lookup-Logik zu integrieren.
quelle
quelle
Die oben beschriebene gespeicherte GetPermissions-Prozedur ist gut, verwendet jedoch Sp_msforeachdb. Dies bedeutet, dass sie unterbrochen wird, wenn Ihre SQL-Instanz Datenbanknamen enthält, die Leerzeichen oder Bindestriche und andere nicht bewährte Zeichen enthalten. Ich habe eine Version erstellt, die die Verwendung von Sp_msforeachdb vermeidet und außerdem zwei Spalten enthält, die 1 angeben - wenn die Anmeldung eine Sysadmin-Anmeldung ist (IsSysAdminLogin) und 2 - wenn die Anmeldung ein verwaister Benutzer ist (IsEmptyRow).
quelle
you can use [] to resolve it. sp_msforeachdb ' use [?] select db_name()'
ich davon aus, dass seine Antwort als Kommentar gedacht war, aber da sein Konto den Mindest-Ruf nicht erfüllt, hat er stattdessen eine Antwort gepostet.Ich habe fast alles versucht, aber ich habe schnell bemerkt, dass einige fehlten, insbesondere Sysadmin-Benutzer. Ein solches Loch zu haben, wird in unserem bevorstehenden Audit nicht gut aussehen, also habe ich mir das ausgedacht
quelle
Aufgrund der geringen Wiederholungszahl können die Personen, die darum bitten, dies auf mehreren Datenbanken / SQL-Servern auszuführen, nicht damit antworten.
Erstellen Sie eine registrierte Servergruppe und fragen Sie sie alle ab und bewegen Sie sich einfach durch die Datenbanken:
Dieser Thread hat mir massiv geholfen, mich bei allen zu bedanken!
quelle
DB_NAME()
und die Ausgabe in einer temporären Tabelle zu verwenden und zu speichern, um zu vermeiden, dass mehrere Ergebnismengen angezeigt werden. Vielen Dank!Vielen Dank für die tollen Audit-Skripte.
Ich empfehle dringend, für Audit-Benutzer fantastische gespeicherte Prozeduren von Kenneth Fisher ( b | t ) zu verwenden:
quelle
Eine einfache Abfrage, die nur anzeigt, ob Sie ein SysAdmin sind oder nicht:
quelle
Leider konnte ich den Sean Rose-Beitrag aufgrund unzureichender Reputation nicht kommentieren, musste jedoch den "öffentlichen" Rollenteil des Skripts ändern, da er aufgrund des (INNER) JOIN gegen sys keine SCHEMA-Berechtigungen zeigte. Objekte. Nachdem dies in LEFT JOIN geändert wurde, musste ich die WHERE-Klausel-Logik weiter ändern, um Systemobjekte wegzulassen. Meine geänderte Anfrage für die öffentlichen Dauerwellen ist unten.
quelle
Wenn Sie den Zugriff auf Datenbanken für eine bestimmte Anmeldung überprüfen möchten, verwenden Sie dieses einfache Skript wie folgt:
sys.sp_helplogins @LoginNamePattern = 'Domain \ login' - sysname
quelle
- Ich bin an der Reihe, einen Beitrag zu leisten, viel Spaß
Dieser Berichtsheader erfasst dynamisch den Namen der SQL-Instanz, das Datum und die Uhrzeit sowie den Kontonamen, unter dem der Bericht ausgeführt wird. Dies sind alles Dinge, die ein guter Prüfer wissen möchte. :) :)
Hinweis - Wenn Sie eine erweiterte Eigenschaft namens "Umgebung" in der Master-Datenbank haben, wird der Wert (was auch immer Sie verwenden: PreProd, Entwicklung, Produktion, DR usw.) in den Berichtskopf aufgenommen.
ENDE
- großartig, um als gespeicherter Prozess zu speichern
quelle