Mit der SQL-Anweisung REVOKE kann ein Benutzer Privilegien wieder entziehen, die er als Grantor erteilt hat. Um konsistenten Zugriffschutz zu gewährleisten, verlangt SQL die Einhaltung bestimmter Regeln bei der Rücknahme von Privilegien.
Die SQL-Anweisung REVOKE lässt sich schematisch wie folgt darstellen:
REVOKE
Privileg(ien) ON
Objekt FROM
Grantee(s) { CASCADE | RESTRICT
}
Mit REVOKE entzieht ein Benutzer den „Grantees“ die angegebenen „Privilegien“. „Objekt“ kann je nach Privileg eine Tabelle oder eine Datenbank bzw. eine Storage Group sein. Ein Privileg darf einem Grantee nur von dem Benutzer entzogen werden, der ihm dieses Privileg zuvor als Grantor erteilt hat.
Mit REVOKE ... FROM PUBLIC kann ein Benutzer ein bestimmtes Privileg allen anderen Benutzern entziehen, wenn er es zuvor als Grantor mit GRANT... TO PUBLIC erteilt hat.
Mit REVOKE ... RESTRICT kann ein Benutzer die angegebenen Privilegien den Grantees nur entziehen, wenn die Grantees die Privilegien nicht an andere Benutzer weitergegeben haben oder wenn diese anderen Benutzer die Privilegien nicht mehr besitzen. Gibt es noch solche weitergegebenen Privilegien, dann werden die mit REVOKE angegebenen Privilegien nicht entzogen und es erfolgt eine Fehlermeldung.
Mit REVOKE ... CASCADE dagegen kann ein Benutzer den Grantees die angegebenen Privilegien in jedem Fall entziehen. Dabei werden außerdem alle Privilegien entzogen, die auf Grund der angegebenen Privilegien von den Grantees an andere Benutzer weitergegeben wurden.
Der Benutzer kann mit Hilfe der Tabellen des INFORMATION_SCHEMA ermitteln, in welcher Reihenfolge die Privilegien mit REVOKE ... RESTRICT entzogen werden müssen. Das INFORMATION_SCHEMA beschreibt in den Tabellen TABLE_PRIVILEGES, COLUMN_PRIVILEGES, USAGE_PRIVILEGES und CATALOG_PRIVILEGES, welche Privilegien welchen Berechtigungsschlüsseln zugeordnet sind.
Da mit einer REVOKE ... CASCADE-Anweisung unter Umständen sehr viele Privilegien entzogen und auch Views (siehe "Privilegien entziehen mit der SQL-Anweisung REVOKE") und Referenzbedingungen (siehe "Privilegien entziehen mit der SQL-Anweisung REVOKE") gelöscht werden können, empfiehlt es sich, sich auch vor einem REVOKE ... CASCADE einen Überblick über bestehende Privilegien in den Tabellen des INFORMATION_SCHEMA zu verschaffen.
Wie bereits erwähnt, werden zwei ansonsten identische Privilegien, die einem Grantee C von zwei verschiedenen Grantoren A und B erteilt wurden, als voneinander verschieden angesehen.
A hat z.B. dasselbe Privileg einmal an C und einmal „WITH GRANT OPTION“ an B weitergegeben; B seinerseits gibt dieses Privileg ebenfalls an C weiter. Entzieht nun A dem Grantee C dieses Privileg mit REVOKE
Privileg ON
Objekt FROM C RESTRICT
, dann besitzt C immer noch das von B erteilte Privileg. Erst wenn auch B dieses Privileg dem Grantee C entziehen würde, ist es C entzogen.
Entzieht stattdessen nun A zusätzlich dem Grantee B mit REVOKE
Privileg ON
Objekt FROM B CASCADE
das Privileg, dann besitzen B und C das Privileg nicht mehr.
Im Folgenden wird das Entziehen von Privilegien mit REVOKE anhand eines einfachen Beispiels erläutert.
Ein Privileg kann allgemein identifiziert werden durch
(Grantor, Grantee, Aktion, Objekt, [WITH GRANT OPTION]).
Es liegt folgende Ausgangssituation vor:
Bild 10: Weitergabe eines Privilegs
Der Eigentümer O des Schemas hat dem Benutzer A das Tabellen-Privileg SELECT auf der Tabelle COMPANY mit der Klausel „WITH GRANT OPTION“ (im Beispiel als WGO abgekürzt) erteilt. Dieses Privileg ist dann beschrieben durch (O, A, SELECT, COMPANY, WGO), siehe Bild 10:
Dieses Privileg hat Benutzer A an Benutzer B „WITH GRANT OPTION“ weitergegeben. B wiederum hat das Privileg an C weitergegeben, C an D und D schließlich an E. B, C und D haben das Privileg jeweils „WITH GRANT OPTION“ erteilt.
Somit bestehen folgende Privilegien:
(O, A, SELECT, COMPANY, WGO)
(A, B, SELECT, COMPANY, WGO)
(B, C, SELECT, COMPANY, WGO)
(C, D, SELECT, COMPANY, WGO)
(D, E, SELECT, COMPANY, WGO)
In Bild 10 wird die Tatsache „Benutzer B hat das Privileg von Benutzer A erhalten“ dadurch verdeutlicht, dass B direkt unter A liegt. Eine Linie zwischen zugehörigen Privilegien drückt aus, dass A das Privileg B noch nicht entzogen hat.
D entzieht nun E das Privileg mit der Anweisung:
REVOKE SELECT ON company FROM E RESTRICT
Nachdem der REVOKE erfolgreich durchgeführt wurde, besitzt E nicht mehr das Privileg (D, E, SELECT, COMPANY, WGO), siehe Bild 11.
Bild 11: Entzug des Privilegs (D,E,SELECT,COMPANY,WGO)
Analog könnte nun D das Privileg durch C entzogen werden, anschließend könnte C das Privileg durch B entzogen werden, usw.. Voraussetzung dafür, dass D dem Benutzer E das Privileg erfolgreich entziehen kann, ist, dass nicht weitere Benutzer dasselbe Privileg von E erhalten haben und noch besitzen. In Bild 10 und Bild 11 drückt sich dies wie folgt aus: Von E bzw. D führen keine Linien zu einem Benutzer unterhalb von E bzw. D.
Vermeidung abgetrennter Privilegien
In der im Bild 11 dargestellten Situation möchte A nun B das Privileg entziehen. Der folgende unzulässige REVOKE wird jedoch abgewiesen:
REVOKE SELECT ON company FROM B RESTRICT
Die Ausführung des REVOKE hätte nämlich zu folgender Situation geführt:
Bild 12: Hypothetische Situation: abgetrennte Privilegien
C hat weiterhin das von B erteilte Privileg (B, C, SELECT, COMPANY, WGO). B selbst besitzt das ihm von A erteilte Privileg (A, B, SELECT, COMPANY, WGO) nicht mehr, d.h. das Privileg (B, C, SELECT, COMPANY, WGO) in Bild 12 ist gleichsam „abgetrennt“. Damit ist aber auch das auf Grund des abgetrennten Privilegs (B, C, SELECT, COMPANY, WGO) erteilte Privileg (C, D, SELECT, COMPANY, WGO) abgetrennt.
In Bild 12 sind abgetrennte Privilegien so gekennzeichnet:
Es gibt von einem solchen Privileg keine Verbindungslinie mehr nach oben zu einem Privileg oder es gibt eine Verbindungslinie nach oben zu einem abgetrennten Privileg.
Allgemein heißt ein erteiltes und noch bestehendes Privileg abgetrennt (englisch „abandoned“), wenn das Privileg noch existiert, aber der Grantor dieses Privileg nicht mehr besitzt. Jedes Privileg, das sich aus einem abgetrennten Privileg ableitet, heißt ebenfalls abgetrennt. Der Begriff des abgetrennten Privilegs bezeichnet eine rein hypothetische Situation, da SESAM/SQL das Entstehen von abgetrennten Privilegien bei REVOKE verhindert.
Bei REVOKE ... RESTRICT verhindert SESAM/SQL das Entstehen von abgetrennten Privilegien, indem es einen REVOKE ... RESTRICT abweist, dessen Ausführung zu einem abgetrennten Privileg führen würde. Vor jedem REVOKE ... RESTRICT sollte sich der Benutzer daher vergewissern, ob ein Entziehen eines bestimmten Privilegs zu abgetrennten Privilegien führen und deshalb abgewiesen würde. Solche Privilegien müssen zuvor mit REVOKE ... RESTRICT durch den Benutzer entzogen werden, der dieses Privileg als Grantor erteilt hat.
Die Ausführung eines REVOKE ... CASCADE kann dagegen nie zu einer Situation führen, in der abgetrennte Privilegien entstehen können. Deswegen wird ein REVOKE ... CASCADE auch nie aus diesem Grund abgewiesen. Entzieht nämlich z.B. in der in Bild 10 dargestellten Situation Grantor A dem Grantee B mit REVOKE SELECT ON company FROM B CASCADE
das SELECT-Privileg, dann werden automatisch in einer Art „Kettenreaktion“ ebenfalls alle Privilegien entzogen, die auf Grund des an B „WITH GRANT OPTION“ vergebenen Privilegs von anderen Grantees vergeben wurden: Zunächst entzieht Grantor D dem Grantee E das Privileg (D, E, SELECT, COMPANY, WGO), dann Grantor C dem Grantee D das Privileg (C, D, SELECT, COMPANY, WGO), usw. Auf diese Weise kann es nie zu abgetrennten Privilegien kommen.
Die beiden folgenden Beispiele beschreiben Situationen, in denen abgetrennte Privilegien entstehen bzw. nicht entstehen würden.
Bild 13: Von zwei Benutzern erteiltes Privileg (C, D, SELECT, COMPANY, WGO)
Bild 13 veranschaulicht folgende Ausgangssituation: C hat von zwei verschiedenen Benutzern (Grantor A und Grantor B) das ansonsten gleiche Privileg erhalten. C hat seinerseits dieses Privileg an D weitergegeben. Nun möchte A dem Benutzer C das zuvor erteilte Privileg (A, C, SELECT, COMPANY, WGO) entziehen.
Zu diesem Zweck gibt A die Anweisung: REVOKE SELECT ON company FROM C RESTRICT
Der REVOKE ist erfolgreich. Bild 14 zeigt die Situation nach ausgeführtem REVOKE.
Bild 14: Entzug des Privilegs (A, C, SELECT, COMPANY, WGO)
Es würde kein abgetrenntes Privileg entstehen, da Benutzer C weiterhin das von B erteilte Privileg (B, C, SELECT, COMPANY, WGO) besitzt. Erst beim Versuch von B, C dieses Privileg zu entziehen, würde der entsprechende REVOKE ( REVOKE SELECT ON company FROM C RESTRICT
) abgewiesen. Wäre der REVOKE erfolgreich, hätte dies ein abgetrenntes Privileg (C, D, SELECT, COMPANY, WGO) zur Folge.
Das nächste Beispiel geht von folgender Situation aus (siehe Bild 15): Zwei Benutzer C1 und C2 haben dasselbe Privileg von zwei verschiedenen Benutzern erhalten (C1 von Grantor A, C2 von Grantor B). C1 erteilte daraufhin dem Benutzer D das Privileg (C1, D, SELECT, COMPANY, WGO), C2 erteilte D das Privileg (C2, D, SELECT, COMPANY, WGO).
Bild 15: Privilegien (C1, D, SELECT, COMPANY, WGO) und (C2, D, SELECT, COMPANY, WGO)
Der Versuch von A, dem Benutzer C1 das Privileg (A, C1, SELECT, COMPANY, WGO) mit REVOKE SELECT ON company FROM C1 RESTRICT
zu entziehen, wird abgewiesen, da andernfalls das dem Benutzer D von C1 erteilte Privileg (C1, D, SELECT, COMPANY, WGO) abgetrennt wäre. In Bild 16 ist dargestellt, zu welchem Ergebnis die (unzulässige) Ausführung des REVOKE führen würde.
Bild 16: Hypothetische Situation: abgetrenntes Privileg (C1,D,SELECT,COMPANY,WGO)
Die beiden letzten Beispiele ( Bild 13 und Bild 14 sowie Bild 15 und Bild 16) verdeutlichen nochmals, warum ein REVOKE ... RESTRICT immer dann abgewiesen wird, wenn seine Ausführung zu einem abgetrennten Privileg führen würde.
Neben dem Begriff „abgetrennte“ Privilegien gibt es die Begriffe „abgetrennte“ Referenzbedingungen und „abgetrennte“ Views.
Vermeidung abgetrennter Referenzbedingungen
Der Begriff „abgetrennte“ Referenzbedingungen soll an folgender Situation erläutert werden.
Der Eigentümer A einer Basistabelle T möchte einem Benutzer B ein zuvor mit GRANT für diese Tabelle erteiltes Tabellen-Privileg REFERENCES mit REVOKE ... RESTRICT entziehen, obwohl eine von diesem Benutzer definierte Referenzbedingung für Spalten der Tabelle noch nicht mit ALTER TABLE ... DROP CONSTRAINT gelöscht worden ist. Die REVOKE ... RESTRICT-Anweisung wird abgewiesen.
Wäre die REVOKE ... RESTRICT-Anweisung erfolgreich, dann gäbe es noch eine Referenzbedingung auf der Tabelle T, für die das zugehörige Tabellen-Privileg REFERENCES nicht mehr existiert. Die Referenzbedingung wäre somit „abgetrennt“.
Mit einem entsprechenden REVOKE ... CASCADE kann Eigentümer A dagegen Benutzer B das REFERENCES-Privileg auch dann entziehen, wenn noch eine Referenzbedingung auf Spalten der Tabelle T definiert ist. Der REVOKE ... CASCADE führt implizit eine ALTER TABLE...DROP CONSTRAINT-Anweisung für diese Referenzbedingung aus.
Vermeidung abgetrennter Views
Neben abgetrennten Privilegien und abgetrennten Referenzbedingungen gibt es auch den Begriff des „abgetrennten“ Views. Der Begriff soll an folgender Ausgangssituation erläutert werden:
Der Eigentümer eines Schemas A vergibt als Grantor das Tabellen-Privileg SELECT für bestimmte Tabellen seines Schemas an den Eigentümer des Schemas B. Der Eigentümer von B erzeugt mit CREATE VIEW einen View VB, dem diese Tabellen zu Grunde liegen.
Der Eigentümer von A möchte nun mit der REVOKE ... RESTRICT-Anweisung dem Eigentümer von B das Privileg SELECT entziehen. Die REVOKE ... RESTRICT-Anweisung wird jedoch abgewiesen. Wäre der REVOKE ... RESTRICT erfolgreich, dann könnte der Eigentümer von B, d.h. der Eigentümer von VB, weiterhin über VB auf die VB zu Grunde liegenden
Tabellen des Schemas A zugreifen, obwohl der Eigentümer von B für diese Tabellen das Tabellen-Privileg SELECT nicht mehr besitzt und so nicht mehr direkt auf die Tabellen zugreifen darf und deshalb nicht einmal mehr den View VB definieren dürfte.
Es gäbe somit eine View-Definition, obwohl für die entsprechende CREATE VIEW-Anweisung keine Berechtigung mehr besteht. Der Definition des Views VB ist somit die Berechtigung entzogen, der View ist „abgetrennt“. Allgemein heißt ein View abgetrennt, wenn dem Eigentümer des View das Tabellen-Privileg SELECT für eine der dem View zu Grunde liegenden Tabellen entzogen ist.Eine REVOKE ... RESTRICT-Anweisung, die zu einem abgetrennten View führen würde, wird stets abgewiesen. Vor jedem REVOKE ... RESTRICT sollte der Benutzer daher sicherstellen, dass alle Views mit der SQL-Anweisung DROP VIEW gelöscht wurden, für deren Definition ein Privileg SELECT Voraussetzung war, das nun mit REVOKE entzogen werden soll.
Entzieht im obigen Beispiel der Eigentümer von A dem Eigentümer von B das Privileg mit einem REVOKE ... CASCADE, dann werden alle abhängigen Views gelöscht. Der REVOKE ... CASCADE entzieht nämlich nicht nur dem Eigentümer von B das SELECT-Privileg für die Tabellen seines Schemas A, sondern führt implizit die folgende Anweisung durch:
DROP VIEW B.V
B CASCADE
Dadurch werden der View VB und alle Views gelöscht, die den View VB in ihrer Definition verwenden.