Empfangen von "Die SELECT-Berechtigung wurde für das Objekt verweigert", obwohl sie erteilt wurde

10

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!

Mason G. Zhwiti
quelle

Antworten:

10

Ich bin mir hier nicht sicher, aber ich werde auf einem Ast ausgehen. Ich denke, Ihr Problem könnte in Ihrer DENY CONTROLAkte liegen. Siehe hier ungefähr auf halber Strecke:

Das Verweigern der CONTROL-Berechtigung für eine Datenbank verweigert implizit die CONNECT-Berechtigung für die Datenbank. Ein Principal, dem die CONTROL-Berechtigung für eine Datenbank verweigert wurde, kann keine Verbindung zu dieser Datenbank herstellen.

Mir ist klar, dass dieses Beispiel für eine Datenbank gilt, aber nehmen Sie es noch eine granulare Ebene. A DENY CONTROLauf einem Tisch wird vermutlich alle Berechtigungen verweigern . Tun Sie a REVOKE CONTROL, um das loszuwerden und zu sehen, ob das Ihr Problem behebt.

In diesem Fall müssen Sie den Benutzer in eine Datenbankrolle einfügen oder ihm die expliziten Berechtigungen für die Tabelle verweigern.

Thomas Stringer
quelle
1
Vielen Dank! Anfangs habe ich beim Experimentieren festgestellt, dass sie SELECT auswählen können, wenn CONTROL nicht verweigert wird. Aber beim Lesen von BOL hatte ich dies falsch interpretiert, um zu bedeuten, dass ich dem Benutzer die volle Kontrolle über die Tabelle gab. Ich sehe jetzt, dass ich, solange ich ihnen die KONTROLLE nicht verweigere, die anderen Berechtigungen (EINFÜGEN, LÖSCHEN usw.) auf der Ebene VERWEIGERN behalten und die gewünschten Berechtigungsstufen erreichen kann. Vielen Dank!
Mason G. Zhwiti
Dies ist eine Subtilität, die ich, obwohl ich mein Problem nicht gelöst habe, positiv bewertet habe und die meiner Meinung nach am meisten übersehen würde. Unabhängig davon habe ich festgestellt, dass bei Verwendung von Active Directory-Gruppen, wenn Sie die Gruppenmitgliedschaft geändert haben, repadmin / syncall nicht unbedingt Probleme behebt, und ich habe festgestellt, dass ein Neustart des Servers das Problem behoben hat. Immer noch auf der Suche nach einem weniger Vorschlaghammer-Ansatz.
John Zabroski
0
  1. Verwenden Sie die sp_DBPermissionsgespeicherte Prozedur von Ken Fisher , um die Berechtigungen anzuzeigen.

    1. Achten Sie darauf , DENY CONTROLnicht auf die Tabelle angewandt, zusätzlich zu dem gemeinsamen DENY SELECT, DENY INSERT, DENY UPDATE, DENY DELETEund DENY REFERENCES.
    2. Wenn die SELECTAnweisung Funktionen mit Tabellenwert enthält, stellen Sie sicher, dass entweder eine EXECUTE AS OWNERFunktion mit Tabellenwert oder eine Funktion mit Tabellenwert vorhanden ist GRANT EXECUTE(und nein DENY 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.
  2. Wenn der Benutzer ein AD-Benutzer oder eine AD-Gruppe ist, verwenden Sie das folgende Skript, um die Benutzer zu ermitteln login_token:

EXECUTE AS LOGIN = 'EXAMPLEDOMAIN\JOHN.DOE';
SELECT * FROM sys.login_token;
REVERT;
  1. 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.

    1. Suchen Sie nach Triggern oder Zeittabellen.
  2. 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

  3. 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 /syncallhat das Problem nicht behoben , ebenso wenig wie das Starten und Stoppen der Anwendung (und damit des Verbindungspools).

  4. Bestimmen Sie die effektiven Berechtigungen für die Anmeldung:

-- '<domain>\<username>' is a domain user in the group you wish to test
EXECUTE AS LOGIN = '<domain>\<username>';
SELECT * FROM fn_my_permissions('Database.Schema.Table', 'OBJECT');
REVERT;
  1. Wenn der Benutzer an einen AD-Benutzer oder eine AD-Gruppe gebunden ist, sollten Sie die Ausführung repadmin /syncallin 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.

  2. 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.

  3. 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!

John Zabroski
quelle