Multi-Level-Security: Mit DB2 einfacher als mit Oracle 10g

25.10.2006 von Heinz Axel Pürner
Die steigenden Anforderungen an Datensicherheit haben zu neuen Lösungen bei den Datenbankherstellern geführt. So hat IBM aktuell in DB2 9.1 ein "Label Based Access Control" eingeführt. Hier ein Vergleich, was DB2 und Oracle 10g in dieser Hinsicht leisten.

Strengere gesetzliche Regelungen und weitergehende, geschäftlich begründete Benutzeranforderungen an den Schutz von Informationen führen dazu, dass Daten über die bisherigen Absätze hinaus geschützt und ihre Nutzung nachgewiesen werden müssen. Dieses führt zu mehrstufigen Sicherheitsverfahren (Multi-Level-Security), die die Klassifikation von Objekten (Daten) und Subjekten (Benutzern) basierend auf einem System von hierarchischen Sicherheitsstufen und nicht hierarchischen Sicherheitskategorien erlauben. Dabei sollen unautorisierte Benutzer am Zugriff gehindert und an der Herabstufung der Sicherheitsklassifikation von Daten gehindert werden.

Der klassische Ansatz im Standard-SQL kennt nur die Vergabe von Berechtigungen auf Objektebene, nicht aber auf der Ebene von Zeilen oder Spalten und auch nicht in Abhängigkeit von den Dateninhalten. Zwar kann man mit Hilfe von Datensichten Zeilen und Spalten ausblenden, bei Zeilen auch in Abhängigkeit von Datenwerten, aber diesen Möglichkeiten sind starre Grenzen gesetzt. Außerdem steigt mit wachsenden Anforderungen an die Zugriffssteuerung die Komplexität der Objektstrukturen erheblich an.

Ein weit verbreiteter Ansatz zur Implementierung der Sicherheitskonzepte ist die Realisierung dieser Anforderungen im Anwendungs-Code: Hier können beliebige Anforderungen flexibel, aber mit entsprechendem Aufwand individuell umgesetzt werden. Wird aber die Anwendung umgangen oder wird über andere Werkzeuge auf die Daten zugegriffen, so sind die implementierten Berechtigungssteuerungen nicht wirksam. Beliebt ist es in diesem Zusammenhang auch, vom Anwendungs-Server mit internen Benutzer-IDs auf die Datenbank zuzugreifen. Diese Benutzer-IDs verfügen dann über den vollen Berechtigungsumfang für den Zugriff auf die Daten, unabhängig davon, welche Berechtigungen der reale Benutzer am Bildschirm eigentlich hätte. Werden diese Benutzer-IDs gehackt (missbräuchlich oder fahrlässig bekannt), so ist die Datenbank offen wie ein Scheunentor!

Der Lösungsansatz

Ein Weg, ein mehrstufiges Sicherheitssystem zu realisieren, ist die Nutzung von Kennsätzen (Labels). Die Kennsätze oder Labels beinhalten die Klassifikation der Daten entsprechend ihrer Sensitivität (Object Labels) oder die Berechtigungen des Benutzers (Subject Labels). Über diese Labels werden lesende und schreibende Zugriffe auf der Ebene von Zeilen und Spalten der Tabellen einer Datenbank gesteuert. Dazu werden die Labels der Daten und der Benutzer miteinander verglichen.

Ein Sicherheitsadministrator erstellt Sicherheitsrichtlinien (Policies) und definiert die Kennsätze für Objekte und Benutzer. Die führenden Hersteller von Datenbank-Management-Systemen Oracle und IBM bieten heute Kennsatz-gesteuerte Sicherheitslösungen als Bestandteil ihrer Datenbankprodukte an. Die Lösungen sind ohne eigenen Programmieraufwand durch den Anwender nutzbar.

Die Vorteile dieser Sicherheitsverfahren sind:

Generelle Vorgehensweise

Die Sicherheitsanforderungen müssen durch Analyse der Anwendungen, der verarbeiteten Informationen und der Benutzeranforderungen bestimmt werden. Die Ergebnisse werden in einem Sicherheitskonzept festgehalten. Aus der Analyse der verarbeiteten Informationen ergibt sich die Klassifikation der Daten bezogen auf ihre Sensitivität. Für die Benutzer werden die Zugriffskriterien ermittelt und die Kennsätze festgelegt.

Die technische Implementierung erfolgt in den Schritten:

  1. Definition von Policy und deren Komponenten;

  2. Definition der Daten-Labels;

  3. Definition der Benutzer-Labels;

  4. Anwenden der Policy auf die Objekte (Tabellen);

  5. Erzeugen der konkreten Label-Werte in den Objekten.

In den folgenden Abschnitten werden die Implementierungen der Kennsatz-gesteuerten Sicherheit in DB2 UDB for LUW und Oracle näher betrachtet.

DB2 UDB V9.1 LBAC

Abfrage der Mitarbeitertabelle im DB2 Command Editor.

Zu den neuen Funktionen in DB2 for LUW Version 9 zählt auch die Berechtigungssteuerung Label Based Access Control (LBAC). Dazu gehört unter anderem ein neues Berechtigungsprofil, der Security Administrator (SECAM). Nur der Security Administrator definiert die Sicherheitsrichtlinien (Security Policies), die Kennsätze (Labels) und vergibt oder widerruft Label-Berechtigungen. Dazu ist kein anderes Profil befugt, auch nicht der Systemadministrator (SYSADM). Er ordnet die Sicherheitsrichtlinien den Objekten (Tabellen) zu. Ein Objekt kann nur eine Sicherheitsrichtlinie besitzen.

Die Security Policies bestehen aus Komponenten, die jeweils eines der Kriterien abbilden, nach denen der Zugriff gesteuert wird. Solche Kriterien können Vertraulichkeitsstufen von Daten, Abteilungszugehörigkeit oder Niederlassungsort sein. Für die Komponenten stehen drei Strukturen zur Verfügung:

Eine Security Policy kann aus maximal 16 Komponenten bestehen.

Die Security Labels können Tabellenzeilen oder Tabellenspalten zugeordnet werden. Durch den Vergleich der Labels von Daten und Benutzern wird festgestellt, ob diese zum Zugriff berechtigt sind. Ist ein Benutzer nicht zum Zugriff berechtigt, behandelt DB2 die Daten in einem solchen Fall, als ob sie nicht existieren. Auch Funktionen wie COUNT() oder SUM() berücksichtigen nur die Daten, für deren Zugriff der Benutzer berechtigt ist. Greift allerdings ein Benutzer auf Spalten zu, für die er nicht berechtigt ist, erhält er eine Fehlermeldung.

Oracle 10g

Die Definition von Komponenten im Oracle Policy Manager (OPM) von Oracle 10g.

Oracle verfügt schon länger über weitergehende Lösungsansätze zur Datensicherheit. Bereits in der Version 8 stellte Oracle mit seiner Technik der Virtual Private Database (VPD) einen Werkzeugkasten (Toolkit) zur Implementierung von individuellen Zugriffskontrollen vor. Einfach dargestellt ermöglicht VPD für definierte Tabellen die automatische Generierung von Prädikaten, die den WHERE-Klauseln der SQL-Befehle eines Benutzers von diesem unbemerkt hinzugefügt werden. Zur Nutzung von VPD müssen eigene Routinen in Oracle erstellt werden.

In der Version 9 hat Oracle mit OLS (Oracle Label Security) eine fertige Lösung mit Security Labels auf Basis der VPD-Technik zur Verfügung gestellt. Sie erfordert keine individuelle Programmierung mehr. Leider findet man bei Oracle mehr als einen Begriff für diese Sicherheitsfunktionen. Neben VPD wird auch der Begriff Fine Grained Access Control (FGAC) verwendet oder von Row Level Security (RLS) gesprochen.

Auch in Oracle werden Sicherheitsrichtlinien (Policies) und Komponenten definiert. Allerdings bestehen bei Oracle die Security Labels aus drei Komponenten:

Die Definition von Daten-Labels im Oracle Policy Manager (OPM) von Oracle 10g.

Zur Verwaltung der Label Security besitzt Oracle die Rolle LBAC_DBA, die der User-ID des Sicherheitsadministrators zugeordnet werden kann. Außerdem wird bei Aktivierung der Label Security in der Datenbank die User-ID LBACSYS als Eigentümer der entsprechenden Objekte definiert. Im Gegensatz zu DB2 stehen in Oracle die Systemadministratoren - bei Anmeldung als SYSDBA - oberhalb der Label Security. Sie haben also uneingeschränkten Zugriff auf die sonst durch Labels geschützten Daten.

Zur Unterstützung bei der Einrichtung und Pflege der Sicherheitsrichtlinien verfügt Oracle mit dem OPM (Oracle Policy Manager) über ein grafisches Werkzeug, mit dem in den meisten Fällen die Definitionen komfortabel und ohne Kenntnis der Befehlssyntax angelegt werden können.

Implementierungsbeispiel

Statt theoretischer Erläuterungen über die Unterschiede zwischen den Implementierungen in DB2 for LUW und Oracle soll ein einfaches Beispiel die Funktionsweise von Kennsatz-gesteuerter Sicherheit sowie die Vor- und Nachteile der jeweiligen Implementierungen deutlich machen. Grundlage des Beispiels sind zwei Tabellen, eine zu schützende Mitabeitertabelle und eine zugehörige Abteilungstabelle.

Die Mitarbeitertabelle hat folgende Struktur:

CREATE TABLE "MITARBEITER"
("PNR" integer NOT NULL primary key,
"NAME" char(24) NOT NULL,
"VORNAME" char(24) NOT NULL,
"TITEL" char(16),
"GEBDAT" DATE NOT NULL,
"BERUFSBEZ" char(24),
"TELEFON" integer NOT NULL,
"ABTEILUNG" smallint,
"EINSTDAT" DATE NOT NULL,
"TARIFGRUPPE" char(4),
"GRUNDGEHALT" dec(10, 2),
"ZULAGE" dec(10, 2) DEFAULT 0,
"L_BONUS" dec(10, 2) DEFAULT 0,
"STRASSE" char(24) NOT NULL,
"PLZ" char(8) NOT NULL,
"WOHNORT" char(24) NOT NULL,
FOREIGN KEY("ABTEILUNG") REFERENCES "ABTEILUNG"("AID"));

Die Abteilungstabelle:

CREATE TABLE "ABTEILUNG"
("AID" smallint NOT NULL primary key,
"ABTBEZ" char(16) NOT NULL,
"MANAGER" integer,
"STANDORT" char(16) );

Die Mitarbeitertabelle enthält neben den Stammdaten wie Adresse oder Geburtsdatum auch die Tarif- und Gehaltsdaten. Sie darf nur von den Mitarbeitern der Personalabteilung HR gepflegt werden. Dabei haben aber normale Sachbearbeiter keinen Zugriff auf die Daten der leitenden Angestellten. Auch die außertariflich bezahlten Angestellten werden nur von ausgewählten Sachbearbeitern bearbeitet. Üblicherweise ist der Zugriff der anderen Sachbearbeiter auch auf die Ihnen zugeordneten Abteilungen beschränkt. Das heißt, der Sachbearbeiter HR_SB3 darf beispielsweise nur die Tarifangestellten der Abteilungen ITD und ITZ bearbeiten. Zusätzlich zu den Mitarbeitern der Personalabteilung dürfen auch die Abteilungs- und Bereichsleiter die Daten ihrer Mitarbeiter inklusive Gehaltsdaten lesen. Die Geschäftsführung hat lesenden Zugriff auf alle Mitarbeiterdaten.

Stellvertretend für die Personalmitarbeiter und Manager des Unternehmens werden folgende Benutzer angenommen:

Die normalen Berechtigungen im DB2 können zwar den lesenden oder ändernden Zugriff auf Tabellen steuern, nicht aber in Abhängigkeit von Spalteninhalten:

GRANT SELECT ON TABLE HR.ABTEILUNG TO USER GF1;
GRANT SELECT ON TABLE HR.MITARBEITER TO USER GF1;
GRANT SELECT ON TABLE HR.ABTEILUNG TO USER FE_MAN;
GRANT SELECT ON TABLE HR.MITARBEITER TO USER FE_MAN;
GRANT SELECT ON TABLE HR.ABTEILUNG TO USER IT_MAN;
GRANT SELECT ON TABLE HR.MITARBEITER TO USER IT_MAN;
GRANT SELECT,INSERT,UPDATE,DELETE ON TABLE HR.ABTEILUNG TO USER HR_SB2;
GRANT SELECT,INSERT,UPDATE,DELETE ON TABLE HR.MITARBEITER TO USER HR_SB2;
GRANT SELECT,INSERT,UPDATE,DELETE ON TABLE HR.ABTEILUNG TO USER HR_SB1;
GRANT SELECT,INSERT,UPDATE,DELETE ON TABLE HR.MITARBEITER TO USER HR_SB1;
GRANT SELECT,INSERT,UPDATE,DELETE ON TABLE HR.ABTEILUNG TO USER HR_GL;
GRANT SELECT,INSERT,UPDATE,DELETE ON TABLE HR.MITARBEITER TO USER HR_GL;

Mit LBAC oder OLS kann der Zugriff auf Daten auch inhaltlich gesteuert werden, allerdings abhängig von einer speziellen Spalte (Security Label), die mit entsprechenden Werten gefüllt werden muss. Zur Steuerung über Kennsätze muss zunächst eine Sicherheitsrichtlinie definiert werden, die in diesem Beispiel zwei Komponenten besitzt. Eine Komponente bildet die tarifliche Eingruppierung ab, die andere die Aufbauorganisation des Unternehmens für die Abteilungszugehörigkeit.

Für die Sicherheitsstufen nach Tarifzugehörigkeit entscheiden wir uns für eine einfache Hierarchie (in DB2 "array", in Oracle "level"), was den Vorteil hat, dass der Benutzer mit höherem Berechtigungsumfang auch die niedrigeren Stufen sehen kann. Zum Beispiel sieht ein Sachbearbeiter mit Stufe "AT" auch die Tarifangestellten. Zur Abbildung der Aufbau-Organisation unseres Beispielunternehmens reicht die einfache Hierarchie nicht, sondern nur die komplexe Hierarchiebildung einer Baumstruktur (in DB2 "tree", in Oracle "group").

Implementierung in DB2

IBM hat die bekannten SQL-Befehle wie CREATE, GRANT oder REVOKE zur Implementierung der LBAC-Funktionalität erweitert. Das grafische Werkzeug für den Administrator, das Control Center, unterstützt bisher nicht Definitionen der LBAC-Funktionalitäten.

Policy-Definitionen werden vom Security-Administrator (SECAM) getroffen:

create security label component perstarif array['lta','at','tarif'];
create security label component betorg tree(
'GF' root,
'IT' under 'GF',
'PRO' under 'GF',
'VM' under 'GF',
'ADM' under 'GF',
'ITZ' under 'IT',
'ITD' under 'IT',
'FE' under 'PRO',
'PRD1' under 'PRO',
'PRD2' under 'PRO',
'VK' under 'VM',
'MA' under 'VM',
'HR' under 'ADM',
'EK' under 'ADM',
'RW' under 'ADM');
create security policy persdat components perstarif, betorg with db2lbacrules;

In DB2 müssen erst die Komponenten definiert werden, dann die Policy. Die möglichen sinnvollen Wertekombinationen der Security Policy mit ihren Komponenten können als Labels definiert und unter dem Label-Namen angesprochen werden. Zur Vergabe von Label-Berechtigungen an Benutzer müssen diese Labels definiert werden.

create security label persdat.alles component perstarif 'lta', component betorg 'GF';
grant security label persdat.alles to user gf1 for read access;
create security label persdat.hrgl component perstarif 'lta', component betorg 'GF';
grant security label persdat.hrgl to user hr_gl for all access;
create security label persdat.hrb1 component perstarif 'at', component betorg 'GF';
grant security label persdat.hrb1 to user hr_sb2 for all access;
create security label persdat.hrb2 component perstarif 'tarif', component betorg 'GF';
grant security label persdat.hrb2 to user hr_sb1 for all access;
create security label persdat.it component perstarif 'at', component betorg 'IT';
grant security label persdat.it to user it_man for read access;
create security label persdat.fe component perstarif 'at', component betorg 'FE';
grant security label persdat.fe to user fe_man for read access;

Die HR-Sachbearbeiter mit höherer Berechtigungsstufe und HR-Gruppenleiter können im ersten Ansatz nur Mitarbeiter auf ihrer Berechtigungsstufe neu aufnehmen. Um auch (vertretungsweise) andere Mitarbeiter bearbeiten zu können, benötigen sie eine Write-down-Berechtigung:

grant exemption on rule db2lbacwritearray writedown for persdat to user hr_gl;

Die definierte Policy muss der Tabelle zugeordnet werden. Außerdem muss die Tabelle um die Label-Spalte erweitert und mit den gewünschten Datenwerten gefüllt werden. Das kann der Datenbank-Administrator durchführen, der dazu allerdings eine Ausnahmeberechtigung (Exemption) benötigt:

alter table mitarbeiter add security policy persdat;
alter table mitarbeiter add column ma_class db2securitylabel;

Wenn die Tabelle um die Label-Spalte erweitert worden ist, können die Labels für die Daten erzeugt werden. Zum Beispiel:

update mitarbeiter
set ma_class = seclabel('PERSDAT','lta:IT')
where tarifgruppe ='lta' and abteilung = 2;
update mitarbeiter
set ma_class = seclabel('PERSDAT','tarif:ITZ')
where tarifgruppe not in('lta','at')
and abteilung = 21;

Anschließend kann das Setzen der Labels kontrolliert werden. Die Labels werden mit der Funktion seclabel_to_char() lesbar gemacht:

select pnr,name, tarifgruppe, abteilung, seclabel_to_char('PERSDAT', ma_class) from mitarbeiter;

Das Ergebnis:

10 HAAS lta 1 lta:GF
20 THOMPSON lta 2 lta:IT
30 KWAN lta 3 lta:GF
50 GEYER lta 4 lta:GF
60 STERN at 21 at:ITZ
70 PULASKI at 31 at:FE
90 HENDERSON at 22 at:ITD
100 Roosevelt lta 51 lta:HR
110 LUCCHESSI at 41 at:VK
120 Quintana tg6 1 lta:GF
130 Connery tg5 32 tarif:PRD1
140 Graham tg5 32 tarif:PRD1
150 ADAMSON tg5 21 tarif:ITZ
160 PIANKA tg5 21 tarif:ITZ
170 YOSHIMURA tg5 21 tarif:ITZ
180 Monroe tg5 21 tarif:ITZ
190 WALKER tg5 21 tarif:ITZ
200 BROWN tg5 21 tarif:ITZ
210 JONES tg5 21 tarif:ITZ
220 Lopez tg5 21 tarif:ITZ
230 JEFFERSON tg5 31 tarif:FE
240 MARINO tg5 31 tarif:FE
250 SMITH tg5 31 tarif:FE
260 JOHNSON tg5 31 tarif:FE
270 PEREZ tg5 31 tarif:FE
280 SCHNEIDER tg4 22 tarif:ITD
290 PARKER tg3 22 tarif:ITD
300 SMITH tg4 22 tarif:ITD
310 SETRIGHT tg4 22 tarif:ITD
320 MEHTA tg5 51 tarif:HR
330 LEE tg5 51 tarif:HR
340 Ullrich tg5 51 tarif:HR
2010 HEMMINGER at 41 at:VK
2120 ORLANDO tg5 53 tarif:RW
2140 NATZ tg5 33 tarif:PRD2
2170 YAMAMOTO tg5 21 tarif:ITZ
2220 JOHN tg5 21 tarif:ITZ
2240 MONTEVERDE tg5 31 tarif:FE
2280 SCHWARTZ tg4 22 tarif:ITD
2310 SPRINGER tg4 22 tarif:ITD
2330 WONG tg5 51 tarif:HR
2340 ALONZO tg5 51 tarif:HR

Fragt nun der Manager der Abteilung F/E (Forschung und Entwicklung) die Tabelle ohne einschränkende Bedingungen ab, so erhält er trotzdem nur die Mitarbeiter seiner Abteilung angezeigt:

select pnr, name, gebdat, abtbez, grundgehalt
from hr.mitarbeiter, hr.abteilung

where aid = abteilung
70 PULASKI 26.05.1953 FE +36170,00
2240 MONTEVERDE 31.03.1954 FE +28760,00
270 PEREZ 26.05.1953 FE +27380,00
260 JOHNSON 05.10.1936 FE +17250,00
250 SMITH 12.11.1939 FE +19180,00
240 MARINO 31.03.1954 FE +28760,00
230 JEFFERSON 30.05.1935 FE +22180,00

In der Personalabteilung findet der Gruppenleiter HR_GL so alle Firmenmitarbeiter vom leitenden bis zum tariflich bezahlten Angestellten und der Sachbearbeiter HR_SB2 alle außer- und tariflich bezahlten.

Implementierung in Oracle

Während IBM die LBAC-Funktionalität als Erweiterungen der bekannten SQL-Befehle implementiert hat, hat Oracle sich für eine Implementierung mit PL/SQL-Routinen entschieden. Grundsätzlich können die Definitionen im Policy Manager (OPM) ohne Kenntnis der Routinen getroffen werden. Zum Vergleich mit der DB2-Lösung finden Sie hier jedoch auch die Prozedur-Aufrufe.

Das Definieren der OLS Security Policy erfolgt bei gleichzeitiger Angabe der Label-Spalte:

BEGIN
SA_SYSDBA.CREATE_POLICY(
policy_name => 'PERSDAT'
,column_name => 'MA_CLASS'
,default_options => 'ALL_CONTROL,HIDE'
);
END;
/

Da die Komponenten einer Policy vorgegeben sind, können gleich die Komponentenwerte definiert werden. In unserem Beispiel wird die Komponente Compartment nicht benutzt, sondern nur Level und Group.

Definieren der Levels:

BEGIN
SA_COMPONENTS.CREATE_LEVEL(
policy_name => 'PERSDAT'
,level_num => 1000
,short_name => 'TARIF'
,long_name => 'TARIFLICH'
);
SA_COMPONENTS.CREATE_LEVEL(
policy_name => 'PERSDAT'
,level_num => 2000
,short_name => 'AT'
,long_name => ' AUSSERTARIFLICH'
);
SA_COMPONENTS.CREATE_LEVEL(
policy_name => 'PERSDAT'
,level_num => 4000
,short_name => 'LTA'
,long_name => 'LEITENDE ANGESTELLTE'
);
END;
/

Definieren der Gruppen:

BEGIN
SA_COMPONENTS.CREATE_GROUP(
policy_name => 'PERSDAT'
,group_num => 0
,short_name => 'GF'
,long_name => 'GESCHAEFTSFUEHRUNG'
,parent_name => NULL
);
SA_COMPONENTS.CREATE_GROUP(
policy_name => 'PERSDAT'
,group_num => 20
,short_name => 'IT'
,long_name => 'INFOTECHNOLOGIE'
,parent_name => 'GF'
);
SA_COMPONENTS.CREATE_GROUP(
policy_name => 'PERSDAT'
,group_num => 30
,short_name => 'PROD'
,long_name => 'PRODUKTION'
,parent_name => 'GF'
);
:::::
SA_COMPONENTS.CREATE_GROUP(
policy_name => 'PERSDAT'
,group_num => 200
,short_name => 'ITZ'
,long_name => 'IT ZENTRAL'
,parent_name => 'IT'
);
SA_COMPONENTS.CREATE_GROUP(
policy_name => 'PERSDAT'
,group_num => 210
,short_name => 'ITD'
,long_name => 'IT DEZENTRAL'
,parent_name => 'IT'
);
END;
/

Wie in DB2 können die möglichen sinnvollen Werte-Kombinationen der Security Policy mit ihren Komponenten als Labels definiert werden. In Oracle werden ihnen numerische Label-Tags zugeordnet, die so gewählt werden können, dass sie für Gruppierung oder Sortierung in Auswertungen nutzbar sind.

Definition von Daten-Labels:

BEGIN
SA_LABEL_ADMIN.CREATE_LABEL(
policy_name => 'PERSDAT'
,label_tag => 1
,label_value => 'LTA::GF'
,data_label => TRUE
);
SA_LABEL_ADMIN.CREATE_LABEL(
policy_name => 'PERSDAT'
,label_tag => 2
,label_value => 'LTA::IT'
,data_label => TRUE
);
:::
SA_LABEL_ADMIN.CREATE_LABEL(
policy_name => 'PERSDAT'
,label_tag => 10
,label_value => 'AT::ITZ'
,data_label => TRUE
);
SA_LABEL_ADMIN.CREATE_LABEL(
policy_name => 'PERSDAT'
,label_tag => 11
,label_value => 'AT::MA'
,data_label => TRUE
);
:::
SA_LABEL_ADMIN.CREATE_LABEL(
policy_name => 'PERSDAT'
,label_tag => 20
,label_value => 'TARIF::EK'
,data_label => TRUE
);
SA_LABEL_ADMIN.CREATE_LABEL(
policy_name => 'PERSDAT'
,label_tag => 21
,label_value => 'TARIF::FE'
,data_label => TRUE
);
END;
/

Definition der Benutzer-Label und deren Zuordnung zu User-IDs:

BEGIN
SA_USER_ADMIN.SET_USER_LABELS(
policy_name => 'PERSDAT'
,user_name => 'GF1'
,max_read_label => 'LTA::GF'
);
SA_USER_ADMIN.SET_USER_LABELS(
policy_name => 'PERSDAT'
,user_name => 'HR_GL'
,max_read_label => 'LTA::GF'
);
SA_USER_ADMIN.SET_USER_LABELS(
policy_name => 'PERSDAT'
,user_name => 'FE_MAN'
,max_read_label => 'AT::FE'
);
SA_USER_ADMIN.SET_USER_LABELS(
policy_name => 'PERSDAT'
,user_name => 'HR_SB2'
,max_read_label => 'AT::GF'
);
:::
SA_USER_ADMIN.SET_USER_LABELS(
policy_name => 'PERSDAT'
,user_name => 'HR_SB3'
,max_read_label => 'TARIF::IT'
);
END;
/

Zuordnung der Policy zur Tabelle:

BEGIN
SA_POLICY_ADMIN.APPLY_TABLE_POLICY(
policy_name => 'PERSDAT'
,schema_name => 'HR'
,table_name => 'MITARBEITER'
,table_options => NULL
,label_function => NULL
,predicate => NULL
);
END;
/

Erzeugen der Label-Werte in der Tabelle:

update hr.mitarbeiter
set ma_class = char_to_label('PERSDAT','lta::IT')
where tarifgruppe ='lta' and abteilung = 2;
update hr.mitarbeiter
set ma_class = char_to_label('PERSDAT','tarif::ITZ')
where tarifgruppe not in('lta','at') and abteilung = 21;
update hr.mitarbeiter
set ma_class = char_to_label('PERSDAT','at::VK')
where tarifgruppe ='at' and abteilung = 41;
Anschliessend kann das Setzen der Labels kontrolliert werden. Die Labels werden mit der Funktion label_to_char() lesbar gemacht:
select pnr,name, tarifgruppe, abteilung,
substr(label_to_char(ma_class),1,16) seclabel

from hr.mitarbeiter;

Ergebnis:

10 HAAS lta 1 LTA::GF
20 THOMPSON lta 2 LTA::IT
30 KWAN lta 3 LTA::GF
50 GEYER lta 4 LTA::GF
60 STERN at 21 AT::ITZ
70 PULASKI at 31 AT::FE
90 HENDERSON at 22 AT::ITD
100 Roosevelt lta 51 LTA::HR
110 LUCCHESSI at 41 AT::VK
130 QUINTANA tg6 1 LTA::GF
140 Graham tg5 32 TARIF::PRD1
150 ADAMSON tg5 21 TARIF::ITZ
160 PIANKA tg5 21 TARIF::ITZ
170 YOSHIMURA tg5 21 TARIF::ITZ
180 Monroe tg5 21 TARIF::ITZ
190 WALKER tg5 21 TARIF::ITZ
200 BROWN tg5 21 TARIF::ITZ
210 JONES tg5 21 TARIF::ITZ
220 Lopez tg5 21 TARIF::ITZ
230 JEFFERSON tg5 31 TARIF::FE
240 MARINO tg5 31 TARIF::FE
250 SMITH tg5 31 TARIF::FE
260 JOHNSON tg5 31 TARIF::FE
270 PEREZ tg5 31 TARIF::FE
280 SCHNEIDER tg4 22 TARIF::ITD
290 PARKER tg3 22 TARIF::ITD
300 SMITH tg4 22 TARIF::ITD
310 SETRIGHT tg4 22 TARIF::ITD
320 MEHTA tg5 51 TARIF::HR
330 LEE tg5 51 TARIF::HR
340 Ullrich tg5 51 TARIF::HR
2010 HEMMINGER at 41 AT::VK
2120 ORLANDO tg5 53 AT::RW
2140 NATZ tg5 33 TARIF::PRD2
2170 YAMAMOTO tg5 21 TARIF::ITZ
2220 JOHN tg5 21 TARIF::ITZ
2240 MONTEVERDE tg5 31 TARIF::FE
2280 SCHWARTZ tg4 22 TARIF::ITD
2310 SPRINGER tg4 22 TARIF::ITD
2330 WONG tg5 51 TARIF::HR
2340 ALONZO tg5 51 TARIF::HR

120 Connery tg5 32 TARIF::PRD1

Fragt der Manager der Abteilung F/E (Forschung und Entwicklung) die Tabelle ohne einschränkende Bedingungen ab, so erhält er auch hier nur die Mitarbeiter seiner Abteilung angezeigt:

select pnr, name, gebdat, abtbez, grundgehalt
from hr.mitarbeiter, hr.abteilung
where aid = abteilung;
2240 MONTEVERDE 31-MAR-54 FE 28760
270 PEREZ 26-MAY-53 FE 27380
260 JOHNSON 05-OCT-36 FE 17250
250 SMITH 12-NOV-39 FE 19180
240 MARINO 31-MAR-54 FE 28760
230 JEFFERSON 30-MAY-35 FE 22180
70 PULASKI 26-MAY-53 FE 36170

Erweiterung des Beispiels

Bisher wurden die Zeilen als Einheit betrachtet und gegen unbefugten Zugriff geschützt. Allerdings sind die Spalten nicht von gleicher Sensitivität: Angaben wie Namen, Telefonnummer oder Abteilungszugehörigkeit könnten allen Firmenangehörigen zugänglich gemacht werden, die Gehaltsdaten aber nur den Sachbearbeitern der Personalabteilung. Das heißt, die Sicherheitseinstufung erfolgt auf Spalten- und Zeilenebene.

In DB2 können mit LBAC auch Spalten durch Vorgabe eines festen Labels geschützt werden. Zum Beispiel können die Spalten Tarifgruppe, Grundgehalt, Zulage und L_Bonus durch Labels für alle Mitarbeiter außerhalb der Personalabteilung gesperrt werden. Greifen nicht berechtigte Mitarbeiter auf diese Spalten zu, so erhalten sie eine Fehlermeldung. Zusätzlich werden die Zeilen noch nach den bisher definierten Kriterien geschützt, so dass weiterhin Manager nur die Mitarbeiter ihrer Abteilung selektieren können.

In Oracle können die Label-Prüfungen auf bestimmte Spalten beschränkt werden, so dass ein Anwender alle Zeilen lesen kann, wenn er nur die ungeschützten Spalten aufruft. Werden die geschützten Spalten selektiert, gelten die Label-Berechtigungen, und es werden nur die Zeilen angezeigt, für die der Benutzer bezogen auf die geschützten Spalten auch berechtigt wurde. Die Realisierung dieser Funktion ist aber nicht mehr mit Hilfe des Policy Managers möglich, sondern muss direkt über die Prozedur-Aufrufe definiert werden. Ein Schutz von Spalten zusätzlich zu dem Schutz auf Zeilenebene ist in OLS nicht vorgesehen, kann aber durch Eigenprogrammierung mit VPD auch realisiert werden.

Fazit

Das Beispiel zeigt, wie einfach mit den Kennsatz-gesteuerten Sicherheitsrichtlinien fein abgestimmte, von den Datenwerten abhängige Zugriffsrechte definiert werden können. Der Vorteil dieser Implementierungen ist, dass sie nicht oder kaum noch (Oracle) umgangen werden können.

Das Beispiel führt bei DB2 und Oracle zu gleichen Ergebnissen. Die Art wie es in DB2 oder Oracle zu definieren ist, ist unterscheidet sich allerdings erheblich. Auf der Ebene der Befehlszeile sind die Definitionen in DB2 einfacher zu formulieren als in Oracle. Oracle besitzt dafür aber ein grafisches Werkzeug, das DB2 nicht bieten kann. Mit diesem Werkzeug lassen sich die Definitionen anlegen, ohne dass der Sicherheitsadministrator ein Oracle-Spezialist mit profunden SQL-Kenntnissen sein muss.

DB2 verfügt mit maximal 16 Komponenten einer Policy und dem Schutz von Zeilen und Spalten standardmäßig über deutlich mehr Möglichkeiten als Oracle mit drei Komponenten und keinem Schutz von Spalten im Standard. Andererseits ist es in Oracle möglich, die Standard-Anwendung OLS zu verlassen und über die VPD-Routinen eine individuelle, beliebig komplexe Sicherheitslösung zu implementieren.

Abschliessend muss noch darauf hingewiesen werden, die diese wichtigen Sicherheitsfunktionen bei beiden Herstellern den Enterprise-Editionen vorbehalten sind. Für mehr Sicherheit verlangen die Hersteller auch mehr Geld. (ue)