Ich bin ein Programmierer, kein dba ... Ich weiß gerade genug, um gefährlich zu sein.
Ich habe eine Datenbank mit einem älteren Benutzer geerbt, der ein Datenbankbesitzer für die Datenbank ist. Wir können die Berechtigung dieses Benutzers für vorhandene Tabellen, Schemas usw. aus geschäftlichen Gründen nicht anpassen, aber einige neue Tabellen werden erstellt, und ich möchte nur, dass dieser Benutzer SELECT-Zugriff darauf hat.
Für diesen Benutzer wurden Berechtigungen für diese Tabellen festgelegt, sodass alles VERWEIGERT wird, mit Ausnahme von SELECT, das auf GRANT festgelegt ist.
Wenn dieser Benutzer (dbadmin) jedoch versucht, ein SELECT für eine dieser Tabellen (AccountingAudit) auszuführen, tritt folgender Fehler auf:
The SELECT permission was denied on the object 'AccountingAudit', database 'billing', schema 'dbo'.
Ich habe diese SQL ausgeführt, um zu sehen, welche Berechtigungen für diese Tabelle / diesen Benutzer festgelegt sind:
select object_name(major_id) as object,
user_name(grantee_principal_id) as grantee,
user_name(grantor_principal_id) as grantor,
permission_name,
state_desc
from sys.database_permissions
Und das bekomme ich zurück:
AccountingAudit dbadmin dbo ALTER DENY
AccountingAudit dbadmin dbo CONTROL DENY
AccountingAudit dbadmin dbo DELETE DENY
AccountingAudit dbadmin dbo INSERT DENY
AccountingAudit dbadmin dbo REFERENCES DENY
AccountingAudit dbadmin dbo SELECT GRANT
AccountingAudit dbadmin dbo TAKE OWNERSHIP DENY
AccountingAudit dbadmin dbo UPDATE DENY
AccountingAudit dbadmin dbo VIEW DEFINITION DENY
AccountingAudit dbadmin dbo VIEW CHANGE TRACKING DENY
Scheint, als sollte es funktionieren, oder?
Der SELECT-Aufruf, den ich mache, ist ein sehr einfaches SELECT * FROM AccountingAudit aus SSMS. Ich mache kein spezielles sp_executesql oder ähnliches.
Ich habe versucht, die Erlaubnis explizit zu erteilen:
GRANT SELECT ON [dbo].AccountingAudit TO dbadmin
Dies hat keine Auswirkung (warum sollte es so sein, die obige Abfrage zeigt bereits, dass es gewährt wird! ;-)
Ich habe durch stackoverflow.com und anderswo gesucht und kann nichts finden, was ich noch nicht ausprobiert habe. Ich frage mich, ob es etwas damit zu tun hat, wie die Schemas eingerichtet sind. (Zu diesem Zeitpunkt weiß ich sehr wenig über Schemata.)
Irgendwelche Ideen? Vielen Dank!
quelle
Verwenden Sie die
sp_DBPermissions
gespeicherte Prozedur von Ken Fisher , um die Berechtigungen anzuzeigen.DENY CONTROL
nicht auf die Tabelle angewandt, zusätzlich zu dem gemeinsamenDENY SELECT
,DENY INSERT
,DENY UPDATE
,DENY DELETE
undDENY REFERENCES
.SELECT
Anweisung Funktionen mit Tabellenwert enthält, stellen Sie sicher, dass entweder eineEXECUTE AS OWNER
Funktion mit Tabellenwert oder eine Funktion mit Tabellenwert vorhanden istGRANT EXECUTE
(und neinDENY EXECUTE
!). Wenn dies der Fall ist, lesen Sie die Fehlermeldung genauer durch, da sie wahrscheinlich nicht besagt, dass die SELECT-Berechtigung für die Tabelle verweigert wurde, sondern dass etwas über EXECUTE verweigert wird.Wenn der Benutzer ein AD-Benutzer oder eine AD-Gruppe ist, verwenden Sie das folgende Skript, um die Benutzer zu ermitteln
login_token
:Schauen Sie sich den tatsächlichen Ausführungsplan an. Wenn sich der Fehler in einer gespeicherten Prozedur mit befindet
SET NOCOUNT ON;
, gibt Ihnen der tatsächliche Ausführungsplan einen Einblick, den Sie möglicherweise nicht beachten, wenn Sie nur auf die Registerkarte Nachrichten in SSMS schauen, da "Betroffene Zeilen" möglicherweise außerhalb Ihrer Kontrolle liegen.Sie können die Anweisung als gespeicherte Prozedur und SSMS "View Object Dependencies" kompilieren sowie die von Svetlana Golovko auf verschiedene Arten beschriebenen Tricks , um SQL Server- Objektabhängigkeiten zu finden
Verwenden Sie das SQL Server Profiler-Sicherheitsereignis "Audit Schema Object Access Event" und die Spalten "TextData" und "Success", um zu verfolgen, für welche Objekte SQL Server Berechtigungen auswertet. - Ich habe Situationen gesehen, in denen zwei Zeilen für dieses Ereignis ausgegeben werden und ein Wert "Erfolg = 1" und der andere "Erfolg = 0" anzeigt. In diesem Szenario besteht die einzige Lösung, die ich gefunden habe, darin, den Server neu zu starten. Selbst das Ausführen
repadmin /syncall
hat das Problem nicht behoben , ebenso wenig wie das Starten und Stoppen der Anwendung (und damit des Verbindungspools).Bestimmen Sie die effektiven Berechtigungen für die Anmeldung:
Wenn der Benutzer an einen AD-Benutzer oder eine AD-Gruppe gebunden ist, sollten Sie die Ausführung
repadmin /syncall
in Betracht ziehen, um zu erzwingen, dass alle in Active Directory vorgenommenen Änderungen auf Ihren Domänencontrollern synchronisiert werden. - Wenn jemand eine gute Möglichkeit kennt, die aktuellen Werte von zwei Domänencontrollern zu vergleichen, lassen Sie es mich bitte wissen.Versuchen Sie, alle aktiven Verbindungen für diesen Benutzer zu beenden, bevor Sie einen harten Neustart des gesamten Systems in Betracht ziehen. Der Grund dafür ist, dass der Benutzer sein Windows-Token vom Domänencontroller erhält, der seine Gruppen enthält. Das Token wird erst aktualisiert, wenn der Benutzer ein neues Token erhält - normalerweise durch Abmelden und anschließendes erneutes Anmelden.
Starten Sie das System hart neu. Es hat bei mir funktioniert. Immer noch nicht 100% sicher warum noch. Tun Sie dies nur, wenn Sie die Zeit überleben können! Seien Sie vorsichtig, wenn Sie dies tun, während Sie große herausragende Transaktionen haben!
quelle