Oseto Oracle Security Tool Studienarbeit von Michael Tiedge Betreuer: Dr. H. H. Brüggemann Dipl. Math. Thomas Esser Hannover, den 3. April 2000 2 Inhaltsverzeichnis 1 Einleitung 1.1 Aufgabenstellung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.2 Gliederung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.3 Entwicklungsumgebung . . . . . . . . . . . . . . . . . . . . . . . . . 11 11 11 11 I 13 Oracle 2 Das Rechtekonzept 2.1 Das Schema im Überblick . . . . . . . . . . . . . . . . . . . . . . . 2.1.1 Nutzer und Rollen . . . . . . . . . . . . . . . . . . . . . . . 2.1.2 Schema Objekte . . . . . . . . . . . . . . . . . . . . . . . . 2.1.3 Prozeduren, Funktionen, Pakete und Trigger . . . . . . . . 2.1.4 Objekt-Privilegien . . . . . . . . . . . . . . . . . . . . . . . 2.1.5 System-Privilegien . . . . . . . . . . . . . . . . . . . . . . . 2.1.6 SYSOPER und SYSDBA . . . . . . . . . . . . . . . . . 2.1.7 Nutzer-Profile und Ressourcen . . . . . . . . . . . . . . . . 2.2 Die Implementierung des Schemas . . . . . . . . . . . . . . . . . . 2.2.1 Die Klassen User, Role und die Assoziation user profile 2.2.2 Die Klasse Object . . . . . . . . . . . . . . . . . . . . . . . 2.2.3 Die Klasse ObjPriv . . . . . . . . . . . . . . . . . . . . . 2.2.4 Die Klasse SysPriv . . . . . . . . . . . . . . . . . . . . . . 2.2.5 Die Assoziation granted obj priv . . . . . . . . . . . . . . 2.2.6 Die Assoziationen granted sys priv und granted role . 2.2.7 Die Assoziation is default role . . . . . . . . . . . . . . . 2.2.8 Die Assoziation ts quota . . . . . . . . . . . . . . . . . . . 2.2.9 Die Assoziation is dependend . . . . . . . . . . . . . . . . 2.2.10 Die Klasse Resources . . . . . . . . . . . . . . . . . . . . . 2.2.11 Die Klasse Profile und die Assoziation user profile . . . 2.2.12 Diverse Nutzerobjekte . . . . . . . . . . . . . . . . . . . . . 2.3 Vordefinierte Nutzer und Rollen . . . . . . . . . . . . . . . . . . . . 2.3.1 Nutzer SYS . . . . . . . . . . . . . . . . . . . . . . . . . . 2.3.2 Nutzer SYSTEM . . . . . . . . . . . . . . . . . . . . . . . 2.3.3 Nutzergruppe PUBLIC . . . . . . . . . . . . . . . . . . . . 2.3.4 Rollen CONNECT und RESOURCE . . . . . . . . . . . 2.3.5 Rolle DBA . . . . . . . . . . . . . . . . . . . . . . . . . . 2.4 Zugang INTERNAL . . . . . . . . . . . . . . . . . . . . . . . . . 2.5 Merkwürdigkeiten . . . . . . . . . . . . . . . . . . . . . . . . . . . 3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15 15 15 17 17 18 18 18 18 19 19 19 20 21 21 21 22 22 22 22 23 23 24 24 24 24 25 25 25 25 4 II INHALTSVERZEICHNIS Die Applikation 27 3 Konzept 4 Bedienung 4.1 Installation und Programmstart . . . . . . . . . 4.2 Nach dem Programmstart . . . . . . . . . . . . 4.2.1 Die Menüleiste . . . . . . . . . . . . . . 4.2.2 Die Wekzeugleiste . . . . . . . . . . . . 4.2.3 Der Verzeichnisbaum und die Sichtfläche 4.3 Aufbau einer Verbindung . . . . . . . . . . . . 4.4 Nach dem Verbindungsaufbau . . . . . . . . . 4.4.1 Der Verzeichnisbaum und die Sichtfläche 4.5 Die Informationssichten . . . . . . . . . . . . . 4.5.1 Die User-Sicht . . . . . . . . . . . . . . 4.5.2 Die Role-Sicht . . . . . . . . . . . . . . 4.5.3 Die Object-Sicht . . . . . . . . . . . . . 4.5.4 Die Object-Selector-Sicht . . . . . . . . 4.5.5 Die System-Privileges-Sicht . . . . . . . 29 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31 31 31 31 32 32 33 34 34 35 35 36 36 36 36 5 Implementierung 5.1 Das Paket dbis.appl.oseto . . . . . . . . . . . . . . . . . . 5.1.1 Die Klasse Oseto . . . . . . . . . . . . . . . . . . . . 5.1.2 Die Klasse Global . . . . . . . . . . . . . . . . . . . . 5.2 Das Paket dbis.appl.oseto.view . . . . . . . . . . . . . . . 5.2.1 Die Klasse AbstractViewModel . . . . . . . . . . . . . 5.2.2 Die Klasse AbstractViewContainerModel . . . . . . . 5.2.3 Die Klasse AbstractViewModelThreaded . . . . . . . 5.2.4 Die Klasse AbstractRecursiveQueryView . . . . . . . 5.2.5 Die Unterklasse AbstractRecursiveQueryView.Task 5.2.6 Die Klasse SqlTableView . . . . . . . . . . . . . . . . 5.2.7 Die Klasse SqlTupleView . . . . . . . . . . . . . . . . 5.3 Das Paket dbis.appl.oseto.common . . . . . . . . . . . . . . 5.3.1 Die Klasse MyTableModel . . . . . . . . . . . . . . . . 5.3.2 Die Klasse MySortedTableModel . . . . . . . . . . . . 5.3.3 Die Klasse SqlTableModel . . . . . . . . . . . . . . . 5.3.4 Die Klasse SqlJTable . . . . . . . . . . . . . . . . . . 5.3.5 Die Klasse SqlTupleJTable . . . . . . . . . . . . . . . 5.3.6 Die Klasse ErrorWindow . . . . . . . . . . . . . . . . . 5.3.7 Die Klasse InfoWindow . . . . . . . . . . . . . . . . . 5.3.8 Die Klasse DBHandler . . . . . . . . . . . . . . . . . . 5.3.9 Die Klasse ConnectionSettings . . . . . . . . . . . . 5.3.10 Die Klasse JBlinker . . . . . . . . . . . . . . . . . . . 5.4 Das Paket dbis.appl.oseto.oracle . . . . . . . . . . . . . 5.4.1 Die Klasse DBBrowser . . . . . . . . . . . . . . . . . . 5.4.2 Die Klasse DBBrowserItem . . . . . . . . . . . . . . . 5.4.3 Die Klasse ObjectView . . . . . . . . . . . . . . . . . 5.4.4 Die Klasse UserObjPrivsView . . . . . . . . . . . . . 5.4.5 Die Klasse UserObjPrivsView.Task . . . . . . . . . . 5.4.6 Weitere Sicht-Klassen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37 37 37 38 39 39 39 40 40 41 41 41 42 42 42 42 43 43 44 44 44 45 45 46 46 48 48 49 49 50 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6 Ausblick 55 7 Beispielschema 57 INHALTSVERZEICHNIS III Nachwort 5 65 6 INHALTSVERZEICHNIS Tabellenverzeichnis 2.1 2.2 2.3 2.4 2.5 2.6 2.7 2.8 2.9 2.10 2.11 2.12 2.13 2.14 Relation user$ (Auszug) . . . . . . . . . . Relation obj$ (Auszug) . . . . . . . . . . . Attribut obj$.type# . . . . . . . . . . . . Relation table privilege map . . . . . . . Relation system privilege map . . . . . . Relation objauth$ (Auszug) . . . . . . . . Relation sysauth$ (Auszug) . . . . . . . . Relation defrole$ . . . . . . . . . . . . . . Relation tsq$ (Auszug) . . . . . . . . . . . Mögliche Abhängigkeiten in dependency$ Relation dependency$ (Auszug) . . . . . . Relation resource map$ . . . . . . . . . . Relation profname$ . . . . . . . . . . . . . Relation profile$ . . . . . . . . . . . . . . . 7 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19 20 20 21 21 21 22 22 22 23 23 23 23 24 8 TABELLENVERZEICHNIS Abbildungsverzeichnis 2.1 Das Schema im Überblick . . . . . . . . . . . . . . . . . . . . . . . . 16 4.1 4.2 4.3 4.4 4.5 Hauptfenster nach dem Programmstart. . . . . . . . . . . . . . . . Bestätigungs-Dialogfenster nach erfolgreichem Verbindungsaufbau. Fehler-Dialogfenster nach gescheitertem Verbindungsaufbau. . . . . Dialogfenster für Verbindungseinstellungen. . . . . . . . . . . . . . Hauptfenster nach erfolgreichem Verbindungsaufbau. . . . . . . . . . . . . . 32 33 33 33 34 5.1 5.2 Die Klasse Oseto und enthaltene Klassen. . . . . . . . . . . . . . . . Der Zusammenhang zwischen den Sicht-Klassen . . . . . . . . . . . . 38 47 9 10 ABBILDUNGSVERZEICHNIS Kapitel 1 Einleitung 1.1 Aufgabenstellung In dieser Studienarbeit sollen die individuellen und strukturellen Datenbankrechte des Oracle-Datenbanksystems durch eine Applikation übersichtlich dargestellt werden. Dabei sollen insbesondere auch in jüngsten Oracle-Versionen eingeführte Konstrukte wie Prozeduren und Funktionen beachtet werden. Hierzu sollen zunächst alle Rechte-Informationen identifiziert, lokalisiert und untereinander in Beziehung gebracht werden. Diese herausgearbeiteten Information sollen in einem Diagramm übersichtlich dargestellt werden, welches dann als Grundlage für das Konzept der Applikation dienen soll. Um Untersuchungsergebnisse reproduzieren zu können, soll ein Skript erstellt werden, welches alle Kommandos zur Erstellung einer Test-Datenbank enthält. 1.2 Gliederung Diese Dokumentation ist in zwei große Abschnitte eingeteilt. Im ersten Abschnitt wird auf das Oracle-Rechtekonzept und dessen Implementierung eingegangen, im zweiten Teil wird die dazu erstellte Applikation (Oseto) vorgestellt und beschrieben. 1.3 Entwicklungsumgebung Die Applikation wurde in Java sowohl auf einem Linux-PC mit Java Development Kit 1.1.7B (Blackdown-Portierung) als auch unter Sun Solaris mit dem Java Development Kit 1.1.7 entwickelt. Als Datenbanksystem wurde sowohl eine Oracle-Standard-Edition 8.0.5.0.0 auf einem Linux-PC als auch eine Oracle-Enterprise-Edition 8.0.5.x.x auf Sun Solaris verwendet. Die Kommunikation zwischen der Applikation und dem Datenbanksystem findet vollständig über JDBC (Oracle thin client Version 8.0.5.2.0) statt. 11 12 KAPITEL 1. EINLEITUNG Teil I Oracle 13 Kapitel 2 Das Rechtekonzept Das Konzept und die Implementierung des Oracle-Rechteschemas wurden überwiegend direkt aus den Initialisierungsskripten für die Systemtabellen (sql.bsq) und Data-Dictionary-Views (insbesondere catalog.sql) erarbeitet. An einigen Stellen wurde schon in [5] Vorarbeit geleistet. 2.1 Das Schema im Überblick Für die Diagramme in diesem Kapitel wird die UML-Notation benutzt (unified modelling language [6]). Einen Überblick über die unter dem Aspekt Datenbankrechte relevanten Komponenten des Oracle-Schemas gibt Abbildung 2.1, S. 16. 2.1.1 Nutzer und Rollen Ein Oracle-Nutzer ist ein eindeutig definierter Name, durch den eine Verbindung zum Datenbankserver aufgebaut werden kann. Rollen sind benannte Mengen von System- und Objektprivilegien, die einem Nutzer oder einer anderen Rolle zugewiesen werden können. Rollen, die einem Nutzer zugewiesen sind, können zusätzlich als default roles gekenntzeichnet werden. Diese Rollen sind dann nach dem Aufbau einer Verbindung zum Datenbankserver aktiviert. 15 KAPITEL 2. DAS RECHTEKONZEPT 16 Role granted_role option {or} is_default_role {or} granted_sys_priv 0..* option profile_resources granted_role 0..* 0..* SysPriv Resources grantor 0..* 0..* grantor Profile User 1 user_profile 0..* grantor grantor {or} ts_quota owns ObjPriv 1 0..* Tablespace Object 0..* is_dependend option granted_obj_priv Abbildung 2.1: Das Schema im Überblick Index Table Cluster View Synonym Sequence Procedure Function Package PackageBody Trigger Type TypeBody TablePartition IndexPartition LOB Library Directory 2.1. DAS SCHEMA IM ÜBERBLICK 17 Anmerkung: In besonderen Fällen gibt es Unterschiede zwischen Privilegien, die einem Nutzer direkt oder indirekt über eine Rolle zugewiesen sind [2, 26-14]: • In benannten PL/SQL-Blöcken (s. 2.1.3, S. 17) werden die Rollen-Privilegien deaktiviert, falls der PL/SQL-Block – in einem Nutzerschema angelegt wurde, in dem ein referenziertes Objekt nicht liegt. – von einem anderen Nutzer ausgeführt werden kann. • In einigen DDL-Anweisungen (data definition language statements) werden über Rollen zugewiesene Privilegien ignoriert. Z.B. ist es einem Nutzer nicht möglich, eine Sicht auf eine Tabelle eines anderen Nutzers anzulegen, wenn er das SELECT-Privileg für diese Tabelle über eine Rolle zugewiesen bekommen hat. Diese käme einem mit ADMIN OPTION zugewiesenen SELECT-Privileg gleich, da es dann möglich wäre, Privilegien auf diese Sicht zu vergeben. 2.1.2 Schema Objekte Mit jedem Nutzer wird ein gleichnamiges Schema angelegt. Ein Schema ist eine benannte Menge von Datenbankobjekten (schema objects), die von einem Nutzer angelegt werden können. Anmerkung: Da jedem Nutzer nur sein gleichnamiges Schema zugeordnet ist, wird im folgenden nicht zwischen dem Nutzer und seinem Schema unterschieden. Folgende Schemaobjekte können von einem Nutzer mit entsprechenden Privilegien angelegt werden: index, table, cluster, view, synonym, sequence, procedure, function, package, package body, trigger, type, type body, library, directory. 2.1.3 Prozeduren, Funktionen, Pakete und Trigger Ein benannter PL/SQL-Block, z.B. Prozeduren, Funktionen, Pakete und Trigger, kann vom Eigentümer oder von einem Nutzer aufgerufen werden, der zu diesem Programmblock das Objektprivileg zur Ausführung (EXECUTE) besitzt, bzw. die Möglichkeit hat die Ausführung auszulösen (Trigger). Vor der Ausführung des PL/SQL-Blockes werden lediglich die öffentlichen Privilegien (PUBLIC) und die des Eigentümers des Programmblockes geprüft. Somit laufen diese PL/SQL-Blöcke sozusagen mit den Privilegien des Eigentümers ab. [2, 17-17, 18-17] Anmerkung: Mit Oracle 8.1.5 wird ein weiterer Modus eingeführt, in dem der Programmblock mit den Privilegien des aufrufenden Nutzers ausgeführt wird. [3, 18-9] Bei Paketen handelt es sich um eine Sammlung von Prozeduren, Funktionen und Cursorn - dennoch können Objekt-Privilegien nur für das gesamte Paket vergeben werden ([4, 4-448]). 18 KAPITEL 2. DAS RECHTEKONZEPT In besonderen Fällen werden bei der Ausführung eines benannten PL/SQLBlockes die über Rollen zugewiesenen Privilegien ignoriert, siehe 2.1.1, S. 15. 2.1.4 Objekt-Privilegien Ein Oracle-Objektprivileg ist ein Recht um eine bestimmte Aktion auf einem einzigen Objekt ausführen zu können. Um z.B. Anfragen auf eine bestimmte Tabelle ausführen zu können, benötigt ein Nutzer, dem diese Tabelle nicht gehört, entweder das Systemprivileg SELECT ANY TABLE, welches ihm Zugriff auf alle Tabellen ermöglicht, oder das Objektprivileg SELECT für diese spezielle Tabelle. Für bestimmte Oracle-Schemaobjekte gibt es allerdings u.U. nicht das gewünschte Objektprivileg, welches weitergegeben werden soll. Um z.B. einem Nutzer das Verändern eines Indexes zu ermöglichen, muß diesem das Systemprivileg ALTER ANY INDEX zugewiesen werden, wenn dieser den Index nicht besitzt. 2.1.5 System-Privilegien Ein Oracle-Systemprivileg ist ein Recht um eine bestimmte Aktion auszuführen, die im Gegensatz zu einem Objektprivileg nicht an ein bestimmtes Schemaobjekt gebunden ist. So gibt es z.B. Systemprivilegien um Sichten anlegen (CREATE VIEW) oder Anfragen auf alle Tabellen ausführen zu dürfen (SELECT ANY TABLE). 2.1.6 SYSOPER und SYSDBA SYSOPER und SYSDBA sind zunächst als System-Privilegien Eingetragen, d.h. sie können einem Nutzer zugewiesen werden. Hierbei handelt es sich aber nicht um ein normales Oracle-System-Privileg, sondern eher um eine besonderen Zugang. Beim Authentifizieren hat ein Nutzer mit einem dieser Privilegien die Möglichkeit, eine Verbindung mit besonderen Administrativen Privilegien aufzubauen. Unter anderem ermöglichen diese Zugangs-Privilegien direkten Zugriff auf Data-DictionaryObjekte, d.h. nicht indirekt über öffentliche Synonyme. ([1, 21-8]). 2.1.7 Nutzer-Profile und Ressourcen Ein Nutzer-Profil ist eine benannte Menge von Oracle-Systemressourcen, die einem Nutzer zugewiesen werden kann. Falls ein Nutzer kein bestimmtes Profil besitzt, ist ihm automatisch das DEFAULT-Profil zugewiesen. Wenn innerhalb eines Nutzer-Profils eine bestimmte Systemressource nicht festgelegt ist, wird auf die entsprechende Definition im DEFAULT-Profil zurückgegriffen. Anmerkung: Jeder Nutzer, dem das Systemprivileg ALTER PROFILE zugewiesen wurde, kann das DEFAULT-Profil verändern. Somit kann die Systemressourcen-Vergabe ähnlich komfortabel gehandhabt werden, wie die Privilegien-Vergabe durch Rollen - wobei aber keine hierarchische Anordnung der Profile möglich ist. Systemressourcen können als parametrisierte Systemprivilegien bezeichnet werden, die z.B. mögliche Verbindungsdauer oder Paßworteigenschaften näher festlegen. Ein detailierte Beschreibung der Oracle-Systemressourcen ist in [4, 4-267] zu finden. 2.2. DIE IMPLEMENTIERUNG DES SCHEMAS 2.2 2.2.1 19 Die Implementierung des Schemas Die Klassen User, Role und die Assoziation user profile Die Klassen User und Role sind durch die Relation user$ (s. Tabelle 2.1, S. 19) implementiert - d.h., daß sowohl Nutzer als auch Rollen in dieser Relation angelegt werden. Diese Entscheidung hat zur Konsequenz, daß eine Rolle und ein Nutzer mit dem selben Namen nicht gleichzeitig angelegt werden können. Um Rollen und Nutzer eindeutig voneinander unterscheiden zu können, ist das Attribut user$.type# vorhanden (0: Rolle, 1:Nutzer). Verschiedene Verfahren zur Nutzerauthentifikation (Paßwort, EXTERNALLY“, ” GLOBALLY“), werden durch einen entsprechenden Eintrag in user$.password ” gekennzeichnet: EXTERNAL“, GLOBAL“ oder das entsprechende verschlüssel” ” te Paßwort. Die Unterscheidung zwischen den beiden Identifikationszeichenfolgen und einem verschlüsselten Paßwort ist wahrscheinlich dadurch gewährleistet, daß die Länge eines verschlüsselten Paßwortes immer die maximal mögliche ist (30 Zeichen). Im Falle einer Rolle enthält user$.password entweder ein verschlüsseltes Paßwort oder NULL, falls diese nicht durch ein Paßwort geschützt ist. Durch das Attribut user$.defrole ist ein Teil der Assozation is default role (s. Abschnitt 2.2.7, S. 22) implementiert. Um die Standardrollen eines Nutzers zu bestimmen, kann das Attribut user$.defrole vier verschiedene Werte annehmen: • 0: der Nutzer hat keine Standardrollen • 1: alle zugewiesenen Rollen (granted role) sind Standardrollen • 2: nur die über is default role definierten Rollen sind Standardrollen • 3: alle zugewiesenen Rollen (granted role), mit Ausnahme der über is default role definierten, sind Standardrollen In diesen vier verschiedenen Werten spiegeln sich die vier verschiedenen Möglichkeiten wider, die von den Befehlen CREATE USER und ALTER USER bzgl. der Standardrollen-Vergabe geboten werden. Die Assoziation user profile ist durch das Attribut user$.resource$ implementiert. Dieses verweist über die entsprechende Nummer auf das Nutzerprofil (Referenz auf profile$.profile#, siehe Abschnitt 2.2.11, S. 23). Attribut user# name type# Typ number varchar2(30) number password defrole resource$ varchar(2) number number Kommentar Nutzer- bzw. Rollennummer Nutzer- bzw. Rollenname Typ des Eintrags: (0: Rolle, 1: Nutzer) Nutzeridentifikation Standardrollen Nutzerprofil Tabelle 2.1: Relation user$ (Auszug) 2.2.2 Die Klasse Object Die Klasse Object ist durch die Relation obj$ (s. Tabelle 2.2, S. 20) implementiert. 20 KAPITEL 2. DAS RECHTEKONZEPT In dieser Relation sind allgemeine Daten der sogenannten schema objects abgespeichert, d.h. für Datenbankobjekte die einen Eigentümer besitzen (Oraclenutzer), und für die Objektrechte zugewiesen werden können. Attribut obj# owner# name type# Typ number number varchar2(30) number Kommentar Objektnummer Objekteigentümer (Nutzernummer) Objektname Objekttyp für Spezialisierung Tabelle 2.2: Relation obj$ (Auszug) Die verschiedenen Objekttypen werden durch das Attribut obj$.type# (s. Tabelle 2.3, S. 20) unterschieden. type# 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 19 20 21 22 23 Bezeichnung NEXT OBJECTa index table cluster view synonym sequence procedure function package NON EXISTENTb package body trigger type type body table partition index partition lob library directory a Pseudo-Object, b Pseudo-Object um sich die nächste eindeutige Objekt-ID zu merken des Dependency-Managements (siehe. [2, 19.1]) Tabelle 2.3: Attribut obj$.type# 2.2.3 Die Klasse ObjPriv Die Klasse ObjPriv ist durch die Relation table privilege map (s. Tabelle 2.4, S. 21) implementiert. Diese Relation besitzt lediglich zwei Attribute (privilege, name), in der die Oracle-Objekt-Privilegien durch eine positive ganze Zahl und einen Namen definiert sind. Der Name dieser Relation ist irreführend, da hier auch andere Objekt-Privilegien neben Tabellen-Privilegien definiert sind (z.B. das execute-Privileg für das Ausführen von Prozeduren). 2.2. DIE IMPLEMENTIERUNG DES SCHEMAS Attribut privilege name Typ number varchar2(40) 21 Kommentar Objektprivileg-Nummer Objektprivileg-Bezeichnung Tabelle 2.4: Relation table privilege map 2.2.4 Die Klasse SysPriv Die Klasse SysPriv ist durch die Relation system privilege map (s. Tabelle 2.5, S. 21) implementiert. Diese Relation besitzt lediglich zwei Attribute (privilege, name), in der die Oracle-System-Privilegien durch eine negative ganze Zahl und einen Namen definiert sind. Anmerkung: Die Nummern der Systemprivilegien sind deshalb negativ definiert, um sie eindeutig von den Rollennummern unterscheiden zu können (s. Abschnitt 2.2.6, S. 21). Attribut privilege name Typ number varchar2(40) Kommentar Systemprivileg-Nummer Systemprivileg-Bezeichnung Tabelle 2.5: Relation system privilege map 2.2.5 Die Assoziation granted obj priv Die Assoziation granted obj priv ist durch die Relation objauth$ (s. Tabelle 2.6, S. 21) implementiert. In dieser Relation wird festgehalten, welche Objekt-Privilegien welchem Nutzer oder welcher Rolle zugewiesen sind. Attribut obj# grantor# grantee# Typ number number number privilege# option$ number number col# number Kommentar Objektnummer Nutzer, der das Recht vergeben hat Nutzer (bzw. Rolle), der das Recht zugewiesen bekommen hat Objektprivileg legt fest, ob das Recht weitergegeben werden darf legt im Falle einer Tabelle fest, ob das Privileg für die ganze Tabelle (col# = null) oder für eine bestimmte Spalte gilt (col# = Spaltennummer) Tabelle 2.6: Relation objauth$ (Auszug) 2.2.6 Die Assoziationen granted sys priv und granted role Die Assoziationen granted sys priv und granted role werden durch die Relation sysauth$ (s. Tabelle 2.7, S. 22) implementiert. 22 KAPITEL 2. DAS RECHTEKONZEPT An dieser Relation wird deutlich, weshalb die System-Privilegien durch eine eindeutige negative ganze Zahl definiert werden. In dem Attribut privilege# kann eine Rollennummer (positive ganze Zahl) oder ein System-Privileg (negative ganze Zahl) abgelegt werden. Attribut grantee# privilege# option$ Typ number number number Kommentar Nutzer (bzw. Rolle), der das Systemprivileg erhält Systemprivileg- oder Rollen-Nummer legt fest, ob das Systemrecht weitergegeben werden darf Tabelle 2.7: Relation sysauth$ (Auszug) 2.2.7 Die Assoziation is default role Die Assoziation is default role wird zum Teil durch die Relation defrole$ (s. Tabelle 2.8, S. 22) implementiert (s. Abschnitt 2.2.1, S. 19). Attribut user# role# Typ number number Kommentar Nutzer, der die Rolle zugewiesen bekommt zugewiesene Rolle Tabelle 2.8: Relation defrole$ 2.2.8 Die Assoziation ts quota Die Assoziation ts quota wird durch die Relation tsq$ (s. Tabelle 2.9, S. 22) implementiert. In dieser Relation werden die Tablespace-Quotas der Nutzer festgelegt. Attribut ts# user# grantor# blocks maxblocks Typ number number number number number Kommentar Tablespacenummer Nutzer, der die Quota erhält Nutzer, der die Quota zugewiesen hat Anzahl der belegten Blöcke Anzahl der maximal verfügbaren Blöcke Tabelle 2.9: Relation tsq$ (Auszug) 2.2.9 Die Assoziation is dependend Die Assoziation is dependend wird durch die Relation dependency$ (s. Tabelle 2.11, S. 23) implementiert. In Tabelle 2.10, S. 23 sind die durch Oracle automatisch verwalteten Abhängigkeiten aufgelistet. Näheres zum Dependency-Management unter [2, 19-1]. 2.2.10 Die Klasse Resources Die Klasse Resources wird durch die Relation resource map (s. Tabelle 2.12, S. 23) implementiert. Die Resource-Parameter werden durch eine Nummer (resource#) und einer Typkennzeichnung (type#) zusammen eindeutig definiert. 2.2. DIE IMPLEMENTIERUNG DES SCHEMAS abhängige Objekte View Procedure Function Package Package Body Trigger 23 referenzierte Objekte Table View Sequence Synonym Procedure Function Package (Specification) Tabelle 2.10: Mögliche Abhängigkeiten in dependency$ Attribut d obj# d timestamp order# p obj# name# Typ number date number number number Kommentar das abhängige Objekt das referenzierte Objekt Resource-Bezeichnung Tabelle 2.11: Relation dependency$ (Auszug) Attribut resource# type# name# Typ number number number Kommentar Resource-Nummer Resource-Typ Resource-Bezeichnung Tabelle 2.12: Relation resource map$ 2.2.11 Die Klasse Profile und die Assoziation user profile Die Klasse Profile wird durch die Relation profname$ (s. Tabelle 2.13, S. 23) implementiert. Hier wird jedes Profil durch eine Nummer (profile#) und eine Bezeichnung (name) definiert. Die Assoziation profile resources wird durch die Relation profile$ (s. Tabelle 2.14, S. 24) implementiert. Die Attribute resource# und type# referenzieren einen Resource-Parameter und das Attribut profile# ein Profil. Durch diese Implementierung ist es immer möglich, die Resource-Parameter eines Nutzerprofils durch direkten Zugriff auf die Relation profile$ zu bestimmen, da hier sowohl der Resource-Paramenter und dessen Wert festgelegt sind. Nur wenn der Name des Profils bzw. des Resource-Parameters von Interesse sind, muß noch auf entsprechende andere Relationen zugegriffen werden (profname$ bzw. resource map). Attribut profile# name Typ number varchar2(30) Kommentar Profilnummer Profilbezeichnung Tabelle 2.13: Relation profname$ 2.2.12 Diverse Nutzerobjekte Neben den Schema-Objekten, die über die obj$-Relation ihren Eigentümern zuzuordnen sind, gibt es noch andere Objekte“, die von Nutzern angelegt wer” 24 KAPITEL 2. DAS RECHTEKONZEPT Attribut profile# resource# type# limit# Typ number number number number Kommentar Profilnummer Resource-Nummer Resource-Typ Resource-Parameter-Wert Tabelle 2.14: Relation profile$ den können (der Nutzer wird in allen Fällen über ein Attribut namens owner# referenziert): • tablespaces (implementiert durch ts$) • constraints (implementiert durch con$) • database links (implementiert durch link$) • incremental export support (implementiert durch incexp) 2.3 Vordefinierte Nutzer und Rollen Folgende Nutzer und Rollen werden beim Initialisieren einer Datenbank automatisch angelegt (überwiegend durch das SQL-Skript sql.bsq“). ” 2.3.1 Nutzer SYS Der System-Nutzer SYS wird durch das Skript sql.bsq“ angelegt. Er besitzt ” alle essentiellen Data-Dictionary-Relationen und Sichten. Da die Rolle DBA automatisch durch den Nutzer SYS angelegt und somit auch SYS zugewiesen wird, erhält SYS alle System-Privilegien (s. Abschnitt 2.3.5, S. 25). Anmerkung: Der Nutzer SYS ist insofern ein normaler Oraclenutzer, daß er Systemprivilegien nur über den normalen Rechteweitergabemechanismus erlangt. Dieses läßt sich beim initialen Datenbankzustand durch Widerruf der DBA-Rolle überprüfen. Das Widerrufen der DBA-Rolle ist aber nicht zu empfehlen, da der normale Datenbankbetrieb, auch nach einer erneuten Zuweisung der DBA-Rolle, nicht mehr gewährleistet ist. 2.3.2 Nutzer SYSTEM Zusätzliche Schemaobjekte für administrative Aufgaben sollten unter dem NutzerAccount SYSTEM angelegt werden. Solche Arbeiten sollten aus Sicherheitsgründen nicht unter dem Nutzer-Account SYS durchgeführt werden. 2.3.3 Nutzergruppe PUBLIC PUBLIC ist die einzige Oracle-Nutzergruppe. Jeder Oracle-Nutzer gehört ihr an. Formal ist PUBLIC in der Systemtabelle user$ als Rolle mit der Nummer 1 eingetragen. Im Gegensatz zu einer normalen Rolle kann PUBLIC weder einem 2.4. ZUGANG INTERNAL 25 Nutzer noch einer anderen Rolle zugewiesen werden. Aber wie jeder anderen Rolle können PUBLIC System- und Objektprivilegien zugewiesen werden. Weiterhin besitzt PUBLIC alle Objekte, die durch eine CREATE PUBLIC Anweisung angelegt werden, d.h. synonyms und database links. Alle Objekt, die PUBLIC besitzt, sind für alle Datenbanknutzer sichtbar. Ebenso stehen die PUBLIC zugewiesenen Privilegien allen Datenbanknutzern zur Verfügung. Auch wenn jeder Nutzer der Gruppe PUBLIC angehört, wird die Zugehörigkeit nicht durch den Rollenzuweisungs-Mechanismus, sondern intern realisiert. 2.3.4 Rollen CONNECT und RESOURCE Diese Rollen werden standardmäßig für die Abwärtskompatibilität zu älteren Oracle-Versionen angelegt. 2.3.5 Rolle DBA Die Rolle DBA wird automatisch durch das SQL-Skipt sql.bsq“ angelegt. ” Ihr sind alle Systemprivilegien mit dem Recht zur Weitergabe (ADMIN OPTION) zugewiesen. Ebenfalls automatisch angelegt und zugewiesen werden die Rollen SELECT CATALOG ROLE, EXECUTE CATALOG ROLE und DELETE CATALOG ROLE. Anmerkung: Ein Nutzer (bzw. Rolle), der die DBA-Rolle erhält, bekommt ebenfalls das Systemprivileg UNLIMITED TABLESPACE explizit, d.h. nicht als Teil der DBA-Rolle, zugewiesen. Wenn diese Rolle widerrufen wird, wird die Zuweisung dieses System-Privilegs rückgängig gemacht. Dieser Mechanismus hat somit den interessanten Nebeneffekt, daß dieses Systemprivileg auf jeden Fall beim Widerrufen der DBARolle entfernt wird, auch wenn es dem Nutzer oder der Rolle schon vorher zugewiesen war. Falls die Export- und Importerweiterungen installiert sind (SQL-Skript cat” exp.sql“), sind der DBA-Rolle die Rollen EXP FULL DATABASE und IMP FULL DATABASE zugewiesen. [1, 21-12] 2.4 Zugang INTERNAL Hier handelt es sich, ähnlich wie bei SYSOPER oder SYSDBA, um einen besonderen Zugang mit administrativen Rechten. Ein Nutzer, der sich über diesen Zugang mit dem Datenbankserver verbinden möchte, muß z.B. das entsprechende Paßwort wissen oder ein entsprechender Betriebsystem-Nutzer sein [2, 5-3]:. 2.5 Merkwürdigkeiten Seiteneffekte beim Zuweisen und Widerrufen der DBA-Rolle, siehe Anmerkung in Abschnitt 2.3.5, S. 25: Das anschließende Widerrufen einer Zuweisung der DBARolle stellt unter Umständen nicht die ursprünglichen Zustand wieder her. Ein eventuell vorher vorhandenes UNLIMITED TABLESPACE Systemprivileg ist nach die Rollenwiderruf nicht mehr zugewiesen. 26 KAPITEL 2. DAS RECHTEKONZEPT Die Kennzeichnung verschiedener Nutzerauthentifikationen (Paßwort, EXTER” NAL“, GLOBAL“) findet über das Attribut user$.password statt, welches nor” malerweise das verschlüsselte Paßwort enthält (siehe Abschnitt 2.2.1, S. 19). Der interne Zuweisungsmechanismus für die Standardrollen eines Nutzers ist auffällig implementiert (siehe Abschnitt 2.2.1, S. 19). Durch die Implementierung der user$-Relation und die Multifunktionalität der Befehle GRANT und REVOKE haben Nutzer, Rollen und Systemprivilegien den gleichen Namensraum. Die Privilegienaktivierung bei Prozedur-, Funktions- bzw. Triggerausführung ist kontextabhängig (siehe Abschnitt 2.1.3, S. 17). Da sich beim Anlegen einer Rolle nicht gemerkt wird, wer die Rolle anlegt, kann man sich die Frage stellen, wieso dieser Nutzer automatisch das Recht hat, diese Rolle anderen Rollen oder Nutzern zuzuweisen. Daß der Nutzer diese Möglichkeit hat, wird dadurch sichergestellt, daß beim Anlegen der Rolle ihm automatisch diese zugewiesen wird mit dem Recht zur Weitergabe. In bestimmten Situationen gibt es Unterschiede zwischen direkt oder über Rollen indirekt zugewiesene Privilegien (2.1.1, S. 17). Teil II Die Applikation 27 Kapitel 3 Konzept Durch die Applikation soll dem Benutzer die Möglichkeit gegeben werden, schnell zu einem Überblick des Rechte-Zustandes der Datenbank zu gelangen. Er soll sich schnell über die Datenbanknutzer informieren können, deren Objekte, Rollen und Privilegien. Neben der Darstellung direkt zugewiesener Zugriffsrechte eines Datenbanknutzers, soll die Applikation auch über indirekte Zugriffsmöglichkeiten informieren, wie Zugriffsrechte durch Sichten, Prozeduren und Rollen. Ebenso soll die Applikation die umgekehrte Vorgehensweise unterstützen - d.h. von einem Datenbank-Objekt oder Privileg aus, direkte und indirekte Zugriffsmöglichkeiten der Datenbanknutzer darstellen. Weiterhin soll die Applikation ein reines “Lese”-Werkzeug sein - d.h., in der Oracle-Datenbank sollen keine Schreiboperationen und somit Veränderungen vorgenommen werden. Diese Vorgabe hat zur Konsequenz, daß z.B. keine Prozeduren angelegt werden können, die u.U. die Arbeitsgeschwindigkeit einiger Sichtmodule erhöht hätten. Letztendlich soll die Applikation sämtliche Informationen ausschließlich aus den Data-Dictionary-Views gewinnen. Hierdurch soll sichergestellt werden, daß bei Veränderungen der Systemtabellen in zukünftigen Oracle-Versionen die Applikation dennoch weiterverwendbar ist. Auch diese Vorgabe hat zur Folge, daß der OracleFunktionsumfang nur eingeschränkt zur Geschwindigkeitssteigerung benutzt werden kann. 29 30 KAPITEL 3. KONZEPT Kapitel 4 Bedienung 4.1 Installation und Programmstart Die Klassen der Applikation sind in einer Jar-Datei gepackt. Bei der Installation muß nur darauf geachtet werden, daß die Standard-Java-, die Swing- und die Oracle-JDBC-Klassen sowie die Oseto-Jar-Datei im Klassenpfad sind. Dann kann die Applikation durch java dbis.appl.oseto.Oseto gestartet werden. Das Starten der Applikation läßt sich durch ein kleines Shell-Skript vereinfachen, in dem der Klassenpfad gesetzt wird und die Applikation gestartet wird. Ein Beispiel-Startskript liegt bei (oseto.sh). 4.2 Nach dem Programmstart Nach dem Start von Oseto ist das Hauptfenster sichtbar (siehe Abbildung 4.1, S. 32). Das Hauptfenster besteht aus vier Bestandteilen: Die Menüleiste, die Werkzeugleiste, der Verzeichnisbaum und die Sichtfläche. 4.2.1 Die Menüleiste Die Menüleiste enthält die Menüs Connection“, Misc“ und Browse“. ” ” ” Das Menü Connection“ ” Connect versucht eine Verbindung mit den festgelegten Einstellungen (Settings) aufzubauen. Disconnect beendet die aktuelle Verbindung zum Datenbankserver. Settings öffnet das Dialogfenster für die Verbindungseinstellungen. Save Settings speichert die festgelegten Verbindungseinstellungen dauerhaft auf die lokale Festplatte (siehe 5.1.1, S. 37). Exit beendet die Applikation Das Menü Misc“ ” Query öffnet ein Anfragefenster, in dem SQL-Anfragen ausgeführt werden können. LogWindow öffnet das Logfenster, in dem die ausgeführten SQL-Anfragen aufgezeichnet werden. Clear LogWindow löscht den Inhalt des Logfensters. 31 32 KAPITEL 4. BEDIENUNG Abbildung 4.1: Hauptfenster nach dem Programmstart. Das Menü Browse“ ” Back zeigt die vorherige Sicht in der History an. Forward zeigt die folgende Sicht in der History an. Die History-Größe ist auf zehn Einträge beschränkt. 4.2.2 Die Wekzeugleiste Die Werkzeugleiste enthält folgende Knöpfe: Entspricht dem Menüpunkt Connecttion/Connect“ ” Entspricht dem Menüpunkt Connecttion/Disconnect“ ” Entspricht dem Menüpunkt Browse/Back“ ” Entspricht dem Menüpunkt Browse/Forward“ ” Entspricht dem Menüpunkt Misc/Query“ ” Entspricht dem Menüpunkt Misc/LogWindow“ ” 4.2.3 Der Verzeichnisbaum und die Sichtfläche Diese beiden Kompenenten sind erst nach dem Verbindungsaufbau zu einem Datenbankserver von Interesse (siehe Abschnitt 4.4, S. 34). Lediglich der Verzeichnisbaum verdeutlicht durch ein disconnected“, daß noch keine Verbindung aufgebaut ” wurde. 4.3. AUFBAU EINER VERBINDUNG 33 Abbildung 4.2: Bestätigungs-Dialogfenster nach erfolgreichem Verbindungsaufbau. Abbildung 4.3: Fehler-Dialogfenster nach gescheitertem Verbindungsaufbau. 4.3 Aufbau einer Verbindung Wenn schon zuvor Einstellungen zur Datenbankverbindung festgelegt wurden, kann durch Auswahl des Menüpunktes Connection/Connect“ oder durch Anklicken ” des ensprechenden Knopfes in der Werkzeugleiste ( ) eine Verbindung zum Datenbankserver aufgebaut werden. Der erfolgreiche oder gescheiterte Versuch eines Verbindungsaufbaus wird durch einen entsprechenden Info- bzw. Fehler-Dialog angezeigt (siehe Abbildung 4.2, S. 33 bzw. 4.3, S. 33). Einstellungen zum Verbindungsaufbau Durch Auswahl des Menüpunktes Connection/Settings“ wird das Dialogfenster ” für die Verbindungseinstellungen geöffnet (siehe Abbildung 4.4, S. 33). Dieser Dialog ermöglicht es, mehrere verschiedene Verbindungskonfigurationen zu verwalten. Jede dieser Konfiguration wird unter einem eindeutigem Stichwort (Dialogfeld name“) abgespeichert. Mit der Select-ComboBox kann man die ver” schiedenen Konfigurationen über die jeweiligen Stichworte auswählen. Eine neue Konfiguration kann durch Eingabe der Parameter in den jeweiligen Feldern und durch Betätigung des Add-Knopfes der Konfigurationsliste hinzugefügt werden. Eine ausgewählte Konfiguration kann durch Editieren der jeweiligen Felder und Betätigung des Change-Knopfes geändert werden. Schließlich kann eine ausgewählte Konfiguration durch Betätigung des DeleteKnopfes gelöscht werden. Durchgeführte Veränderungen an den Konfigurationen gelten zunächst nur für die aktuelle Sitzung - erst durch Auswahl des Menüpunktes Connection/Save Set” tings“ werden die Konfigurationen (mit Ausnahme des Paßwortes) dauerhaft auf Abbildung 4.4: Dialogfenster für Verbindungseinstellungen. 34 KAPITEL 4. BEDIENUNG die lokalen Festplatte gespeichert (siehe 5.1.1, S. 37). Bei einem Verbindungsaufbau gilt immer die ausgewählte Konfiguration bzw. es gelten die in den Feldern eingetragenen Parameter. Bei der Checkbox dbamode“ handelt es sich um einen Modus der Applikation, ” der nur dann einwandfrei läuft, wenn der Nutzer genügend administrative Rechte besitzt, z.B. die zugewiesene DBA-Rolle. Insbesondere muß der Nutzer Zugriff auf die DBA-Dictionary-Sichten haben. Im Normal-Modus greift die Anwendung lediglich auf Data-Dictionary-Sichten zu, die für jeden Oracle-Nutzer verfügbar sind - insbesondere die USER- und ALLSichten. 4.4 Nach dem Verbindungsaufbau Abbildung 4.5: Hauptfenster nach erfolgreichem Verbindungsaufbau. Nach erfolgreichem Aufbau einer Datenbankverbindung sollte das Hauptfenster wie in Abbildung 4.5, S. 34 aussehen. 4.4.1 Der Verzeichnisbaum und die Sichtfläche Public Group Nach Auswahl dieses Eintrags, wird auf der Sichtfläche die Pu” blic Group“-Sicht dargestellt, die Informationen über die öffentliche OracleGruppe (public) darstellt. Hierbei handelt es sich um eine vereinfachte User“” Sicht (siehe 4.5.1, S. 35). Users Nach Aufklappen dieses Zweiges werden alle Datenbanknutzer aufgelistet. Durch Auswahl eines Nutzer wird auf der Sichtfläche die User“-Sicht ange” zeigt (siehe 4.5.1, S. 35) Roles Nach Aufklappen dieses Zweiges werden alle Datenbankrollen aufgelistet. Durch Auswahl einer Rolle wird auf der Sichtfläche die Role“-Sicht angezeigt ” (siehe 4.5.2, S. 36). System Privileges Nach Aufklappen dieses Zweiges, werden alle Oracle-SystemPrivilegien angezeigt. Nach Anklicken eines Privilegs erscheint auf der Sichtfläche die “System-Privileges”-Sicht, die es dem Oseto-Nutzer ermöglicht, sich über vergebene Systemprivilegien zu informieren (siehe 4.5.5, S. 36). 4.5. DIE INFORMATIONSSICHTEN 35 Objects Dieser Eintrag läßt sich sowohl selbst auswählen als auch aufklappen. Nach Auswahl wird die Object Selector“-Sicht auf der Sichtfläche, ohne Aus” wahlparameter dargestellt (siehe Abschnitt 4.5.4, S. 36). Nach Aufklappen dieses Eintrags, werden sämtliche Schemaobjekt-Typen aufgelistet. Der Nutzer hat nun die Möglichkeit einer dieser Typen auszuwählen, worauf auf der Sichtfläche die Object Selector“-Sicht mit dem ausgewähltem Objekttyp als ” Auswahlparameter angezeigt wird. 4.5 Die Informationssichten 4.5.1 Die User-Sicht Diese Sicht stellt Informationen über einen Oracle-Nutzer dar. Sie zeigt zunächst nur den Namen des ausgewählten Nutzers an, enthält aber noch folgende Untersichten: UserInfo In dieser Sicht werden lediglich die Nutzerinformationen aus der Data-DictionarySicht DBA USERS dargestellt. RoleTree Diese Sicht stellt alle direkt und indirekt zugewiesenen Rollen des ausgewählten Nutzers als Verzeichnisbaum dar. Durch Doppelklicken einer Rolle, wird die Rollensicht mit der ausgewählten Rolle angezeigt (siehe 4.5.2, S. 36) Objects Diese Sicht listet alle Schemaobjekte auf, die dem ausgewählten Nutzer gehören. Durch Doppelklick auf einen Objektnamen oder einer Objektidentifikationsnummer (ID) wird die Object-Sicht mit dem entsprechenden Objekt angezeigt (siehe Abschnitt 4.5.3, S. 36). Durch Doppelklick auf einen Objekttyp, wird die ObjectSelector-Sicht mit dem entsprechenden Objecttyp als Auswahlparameter dargestellt (siehe Abschnitt 4.5.4, S. 36). ObjectPrivileges Diese Sicht zeigt zunächst die dem ausgewählten Nutzer direkt zugewiesenen Objektprivilegien an. Nach Betätigung das Start“-Knopfes werden auch die über ” Rollen indirekt zugewiesenen Objektprivilegien berechnet. Durch Betätigung des Stop“-Knopfes kann eine laufende Berechnung unter” brochen werden. Mehrfachzuweisungen über verschiedene Pfade werden ebenfalls aufgelistet. Der Zuweisungspfad wird in der Spalte path“ angezeigt. ” SystemPrivileges Diese Sicht entspricht weitestgehend der ObjectPrivileges-Sicht mit dem Unterschied, das hier die dem ausgewählten Nutzer zugewiesenen Systemprivilegien dargestellt werden. Quotas Diese Sicht stellt lediglich Informationen der den ausgewählten Nutzer zugewiesenen tablespace quotas aus der Sicht DBA TS QUOTAS dar. 36 KAPITEL 4. BEDIENUNG Profiles Diese Sicht zeigt das zugewiesene Profil und die dazugehörenden Oracle-Ressourcen an. Dependencies Diese Sicht stellt die Abhängigkeiten (dependencies) des Oracle DependencyManagements für die Schema-Objekte des Nutzers an. Weiterhin lassen sich auch die indirekten Abhängigkeiten auflösen. 4.5.2 Die Role-Sicht Diese Sicht stellt Informationen über eine Oracle-Rolle dar. Sie gleicht weitesgehend der User-Sicht, wobei aber nur folgende Untersichten vorhanden sind: • RoleTree • ObjectPrivileges • SystemPrivileges 4.5.3 Die Object-Sicht Diese Sicht stellt Informationen zu einem ausgewählten Schema-Objekt zu Verfügung. Auswahl ist entweder über die Nutzerobjekt-Sicht (4.5.1, S. 35) oder über die Object-Selector-Sicht (4.5.4, S. 36) möglich. In Abhängigkeit vom Typ des ausgewählten Schema-Objekts wird eine Reihe verschiedener Untersichten angezeigt. An dieser Stelle wird nicht weiter auf diese Untersichten eingegangen, da diese sehr selbsterklärend konzipiert sind. Eine Übersicht zur Anordnung der Sichten und eine jeweilige kurze Beschreibung ist im Abschnitt 5.4, S. 46 zu finden. 4.5.4 Die Object-Selector-Sicht Diese Sicht bietet die Möglichkeit, aus allen für den Nutzer verfügbaren Objekten eine Auswahl zu treffen. Hierzu kann der Nutzer die Auswahl durch Angabe des Namens, des Eigentümers und des Typs des Objekts einschränken. Durch Doppelklick eines ausgewählten Objekts wird zur Object-Sicht umgeschaltet. 4.5.5 Die System-Privileges-Sicht Nach Auswahl eines System-Privilegs erscheint diese Sicht, in der zunächst die Nutzer und Rollen aufgelistet werden, die dieses Privileg direkt zugewiesen bekommen haben. Nach Anklicken des Start-Knopfes werden auch alle anderen Rollen und Nutzer, die dieses Privileg indirekt über Rollen zugewiesen bekommen haben, angezeigt. In der Spalte “path” kann der Zuweisungspfad nachvollzogen werden. Kapitel 5 Implementierung Um den Rahmen dieser Dokumentation nicht zu sprengen, werden nur die wichtigsten Klassen dieser Applikation an dieser Stelle beschrieben. Bei der Beschreibung beschränke ich mich weiterhin nur auf die wichtigsten Attribute, Konstruktoren und Methoden. Die vollständige Beschreibung aller Klassen in vollem Umfang liegt als JavadocDokumentation vor. 5.1 Das Paket dbis.appl.oseto Bei dbis.appl.oseto handelt es sich um das Hauptpaket dieser Applikation. Es enthält direkt nur zwei Klassen und ansonsten mehrere Unterpakete. Bei den direkt enthaltenen Klassen handelt es sich um das ausführbare Oseto und um Global, das statische (globale) Objektreferenzen für die gesamte Applikation enthält. 5.1.1 Die Klasse Oseto Haupt-Klasse der Oseto-Applikation abgeleitet von JFrame. Einen Überblick über diese Klasse gibt die Abbildung 5.1, S. 38. Konstruktoren Oseto() Erzeugt eine neue Instanz der Oseto-Applikation. Methoden -saveProperties(): void Speichert Einstellungen der Applikation, wie Verbindungseinstellungen, dauerhaft in der Einstellungsdatei. Der Ort der permanenten Abspeicherung wird durch System.getProperty(‘‘user.home’’) bestimmt. -loadProperties(): void Lädt Einstellungen der Applikation, wie Verbindungseinstellungen, aus der Einstellungsdatei. -exit(): void Beendet die Applikation. +$main(args: String[]): void Startet die Applikation durch das Erzeugen einer Instanz der Oseto-Klasse. 37 38 KAPITEL 5. IMPLEMENTIERUNG Oseto JMenuBar DBHandler DBBrowser JToolBar ConnectionSettings LogWindow Abbildung 5.1: Die Klasse Oseto und enthaltene Klassen. 5.1.2 Die Klasse Global Global enthält statische Objektreferenzen und -instanzen, auf die, ohne großen Aufwand, andere Objekte zugreifen können sollen. Attribute +$DEBUG: boolean Debug-Modus an / aus. +$OPTION FILE NAME: String Name der Einstellungsdatei. +$setConnectionAction: Action Action zum Anzeigen des ConnectionSettings-Dialogs. +$exitAction: Action Action zum Beenden der Applikation. +$connectAction: Action Action zum Aufbau einer Datenbankverbindung. +$disconnectAction: Action Action zum Beenden einer Datenbankverbindung. +$queryAction: Action Action zum Erzeugen eines neuen Query-Fensters. +$saveSettingsAction: Action Action zum Abspeichern der Verbindungsparameter. +$logAction: Action Action zum Anzeigen des Log-Fensters. +$clearLogAction: Action Action zum Löschen des Log-Fensters. +$browseForwardAction: Action Action zum Anzeigen der nächsten Sicht in der History. +$browseBackAction: Action Action zum Anzeigen der vorherigen Sicht in der History. +$mainMenuBar: JMenuBar Die Mainmenu“-Leiste. ” +$mainToolBar: JToolBar Die Maintool“-Leiste. ” +$browser Der Browser. +$logWindow: LogWindow Das Log-Fenster. +$dbHandler: DBHandler Der Datenbank-Handler. 5.2. DAS PAKET DBIS.APPL.OSETO.VIEW 5.2 5.2.1 39 Das Paket dbis.appl.oseto.view Die Klasse AbstractViewModel Von dieser abstrakten Klasse müssen alle Sicht-Komponenten abgeleitet werden. Es werden elementare Funktionen zur Verfügung gestellt, wie das einfache Setzen und Lesen eines Parameterobjektes. Attribute #value: Object Parameterobjekt #refreshed: boolean Gibt an, ob die Darstellung der Sicht aktuell ist. #title: String Titel der Sicht. Methoden +setValue(value: Object): void Setzt das Parameterobjekt. +getValue(): Object Gibt Referenz auf das Parameterobjekt zurück. +refresh(): void Frischt die Darstellung der Sicht-Komponente bei Bedarf auf +reload(): void Frischt die Darstellung der Sicht-Komponente in jedem Falle auf. +setTitle(title: String): void Setzt den Namen der Sicht-Komponente. +getTitle(): String Gibt den Namen der Sicht-Komponente zurück. 5.2.2 Die Klasse AbstractViewContainerModel Eine erweiterte Version des AbstractViewModel, in der mehrere Untersichten durch eine TabbedPane verwaltet werden. Die Parameterübergabe wird automatisch an die Untersichten weitergeleitet. Die über die JTabbedPane ausgewählte Sicht wird automatisch (bei Bedarf: refresh()) aktualisiert. Attribute #containedViews: Vector Vektor, der alle Untersicht-Komponenten enthält. #tabbedPane: JTabbedPane Für das Anzeigen aller Untersicht-Komponenten. Konstruktoren AbstractViewContainerModel() Erzeugt eine neue Instanz dieser Klasse. Methoden +setValue(value: Object): void Setzen des Parameterobjektes für diese Sicht-Komponente und für die Untersicht-Komponenten. +reload(): void Erzwingt die Aktualisierung dieser Sicht-Komponente und der Untersicht-Komponenten. +addView(view: AbstractViewModel): void Fügt eine neue Untersicht-Komponente ein. 40 KAPITEL 5. IMPLEMENTIERUNG +removeView(view: AbstractViewModel): void Entfernt eine Untersicht-Komponente. +removeAllViews(): void Entfernt alle Untersicht-Komponenten. 5.2.3 Die Klasse AbstractViewModelThreaded Diese abstrakte Klasse stellt das Gerüst für eine Sicht zur Verfügung, in der ein längerer Prozess in einem Thread abgearbeitet werden soll. Konstruktoren AbstractViewModelThreaded() Erzeugt eine neue Instanz dieser Klasse. Methoden +setValue(value: Object): void Setzt das Parameterobjekt. Gegebenfalls wird ein laufender Prozess aufgefordert, sich zu beenden. +isStopRequested(): void Gibt zurück, ob der Thread aufgefordert wurde, sich zu beenden. +actionPerformed(e: ActionEvent): void Diese Methode wird regelmäßig durch den Timer während eines laufenden Prozesses aufgerufen. Hier wird dafür gesorgt, daß der “Blinker” in der Statuszeile blinkt. #setStatusLine(text: String): void Setzt den Text in der Statuszeile. #newTask(): void Diese Methode startet einen neuen Prozess. #startTask(): void Diese Methode wird aufgerufen, wenn ein neuer Prozess gestartet werden soll. #requestStopTask(): void Diese Methode wird aufgerufen, wenn eine laufender Prozess beendet werden soll. +taskHasStopped(): void Diese Methode muß vom Prozess aufgerufen werden, wenn er sich selbst beendet. 5.2.4 Die Klasse AbstractRecursiveQueryView Diese Klasse stellt eine Sicht zur Verfügung, in der in einem separatem Thread rekursive SQL-Anfragen ausgeführt werden können. Hierzu muß zunächst ein Startergebnis durch die Methode getStartList berechnet werden, welches auf jeden Fall bei Aktivierung der Sicht auch angezeigt wird. Bei Bedarf werden durch die Unterklasse Task auf dieses Startergebnis aufbauend iterativ weitere Berechnungen durchgeführt. Konstruktoren AbstractRecursiveQueryView() Erzeugt eine neue Instanz dieser Klasse. Methoden +cellDoubleClickedAt(row: int, col: int): void Wird aufgerufen, wenn eine Tabellenzelle doppelt angeklickt wurde. 5.2. DAS PAKET DBIS.APPL.OSETO.VIEW 5.2.5 41 Die Unterklasse AbstractRecursiveQueryView.Task Methoden #getTableHeader(): Vector Liefert den Tabellenkopf des berechneten Ergebnisses in Form eines String-Vektors. #getStartList(): Vector Diese Methode muß das Startergebnis berechnen, auf das aufbauend iterativ weitere Berechnungen durchgeführt werden können. #getPreparedStatement(): String Liefert das PreparedStatement für die rekursive SQLAnfrage in Form eines Strings. #setPreparedStatementArguments(pS: PreparedStatement): void Setzt die Argumente für das “rekursive” PreparedStatement. #produceResultEntry(oldEntry: Vector, rs: ResultSet): Vector Transformiert das interne Anfrage-Ergebnis in die anzuzeigende Form. 5.2.6 Die Klasse SqlTableView Diese Klasse stellt eine Sicht zur Verfügung, in der Ergebnisse einer SQL-Anfrage in Form einer Tabelle angezeigt werden. Weiterhin können Aktionen durch einen Doppelklick einer Tabellenzelle über die Methode cellDoubleClickedAt durchgeführt werden. Konstruktoren SqlTableView() Erzeugt eine neue Instanz dieser Klasse und registriert insbesondere einen MouseListener, der das Doppelklicken einer Tabellenzelle abfängt. Methoden +cellDoubleClickedAt(row: int, col: int): void Wird aufgerufen, wenn eine Tabellenzelle doppelt angeklickt wurde. 5.2.7 Die Klasse SqlTupleView Diese Klasse stellt eine Sicht zu Verfügung, in der das erste Ergebnistupel einer SQL-Anfrage in Form einer Tabelle angezeigt wird. Konstruktoren SqlTupleView() Erzeugt eine neue Instanz dieser Klasse und registriert insbesondere einen MouseListener, der das Doppelklicken einer Tabellenzelle abfängt. Methoden +cellDoubleClickedAt(row: int, col: int): void Wird aufgerufen, wenn eine Tabellenzelle doppelt angeklickt wurde. 42 5.3 5.3.1 KAPITEL 5. IMPLEMENTIERUNG Das Paket dbis.appl.oseto.common Die Klasse MyTableModel Stellt ein Tabellen-Modell zur Verfügung, in dem Zellinhalte nicht editierbar sind. Methoden +isCellEditable(): boolean Gibt stets false zurück. +removeAll(): void Löscht alle Zeilen in der Tabelle. 5.3.2 Die Klasse MySortedTableModel Stellt ein Tabellen-Modell zur Verfügung, in dem Zeilen nach einer bestimmten Spalte sortiert werden können. Attribute -index: int[] Repräsentiert die sortierte Permutation der TabellenZeilen. Konstruktoren MySortedTableModel() Erzeugt eine neue Instanz und initialisert den Permutations-Index. Methoden +getValueAt(row: int, col: int): Object Indirekter Zellen-Lesezugriff über den Permutations-Index. +setValueAt(value: Object, row: int, col: int): Object Indirekter Zellen-Schreibzugriff über den PermutationsIndex. -initIndex(): void Initialisiert den Permutations-Index (Identität). -compareCells(row1: int, row2:int, col: int): int Vergleicht zwei Zellen einer bestimmten Spalte. -swapRows(row1: int, row2:int): void Vertauscht zwei Zeilen (im Index). +sortByColumn(column: int): void Sortiert die Tabelle nach einer bestimmten Spalte. +tableChanged(e: TableModelEvent): void Veranlaßt die Initialisierung des Permutations-Indexes bei der Änderung eines Tabelleninhaltes. 5.3.3 Die Klasse SqlTableModel Stellt ein Tabellen-Modell zur Verfügung, in dem SQL-Anfragen ausgeführt werden können. Der Tabelleninhalt stellt das Anfragen-Ergebnis da. Weiterhin werden die SQL-Typen des Anfrage-Ergebnisses automatisch nach Java-Objekt-Typen konvertiert. Attribute -rsMetaData: ResultMetaData 5.3. DAS PAKET DBIS.APPL.OSETO.COMMON 43 -columnClasses: Class[] Array, in dem die Spalten-Typen des Anfrage-Ergebnisses abgespeichert werden. Methoden +getColumnClass(column: int): Class Gibt den Objekt-Typ einer bestimmten Spalte zurück. +query(query: String): void Führt die angegebene SQL-Anfrage aus und konvertiert die SQL-Typen nach Java-Typen. 5.3.4 Die Klasse SqlJTable Stellt eine erweiterte JTable-Komponente zur Verfügung, in der durch einen einfachen Aufruf das Ergebnis einer SQL-Anfrage in Form einer Tabelle dargestellt wird. Attribute -query: String -sqlTable: SqlTableModel Konstruktoren SqlJTable() Erzeugt eine neue Instanz. SqlJTable(query: String) Erzeugt eine neue Instanz dieser Klasse und führt die angegebene SQL-Anfrage aus. Methoden +query(query: String): void Führt die angegebene SQL-Anfrage aus. +refresh(): void Aktualisierung der zuletzt angegebenen SQL-Anfrage. +tableChanged(e: TableModelEvent): void Neusetzten der Spaltenbreiten nach jeder Tabellenänderung (evtl. Swing-Bug). +removeAll(): void Löscht alle Einträge in der Tabelle. 5.3.5 Die Klasse SqlTupleJTable SqlTupleJTable stellt das erste Tupel einer SQL-Anfrage in Form einer Tabelle da. Konstruktoren SqlTupleJTable() Erzeugt eine neue Instanz dieser Klasse. SqlTupleJTable(query: String) Erzeugt eine neue Instanz dieser Klasse und führt die angegebende SQL-Anfrage aus. Methoden +query(query: String): void Führt die angegebene SQL-Anfrage aus. +setColumnIdentifiers(columnNames: String[]): void Setzt die Tabellenüberschriften. 44 KAPITEL 5. IMPLEMENTIERUNG +refresh(): void Auffrischen der zuletzt angegebenen SQL-Anfrage. +removeAll(): void Löscht alle Einträge in der Tabelle. 5.3.6 Die Klasse ErrorWindow ErrorWindow stellt ein statisches Fehlermeldungs-Fenster zu Verfügung. Methoden +$show(errorMessage: String): void Zeigt ein Fehlermeldungs-Fenster mit der Meldung errorMessage und dem Titel Error“ an. ” +$show(errorMessage: String, title: String): void Zeigt ein Fehlermeldungs-Fenster mit der Meldung errorMessage und dem Titel title an. +$show(sqlEx, SQLException): void Zeigt eine SQLException in einem Fehlermeldungs-Fenster an. Im Debug-Modus (s. dbis.appl.oseto.Global) wird der StackTrace auf der Standard-Ausgabe ausgegeben. +$show(ex, Exception): void Zeigt eine Exception in einem Fehlermeldungs-Fenster an und gibt den StackTrace auf der Standard-Ausgabe aus. +$main(args[], String): void Zur Ausführung einer Instanz dieser Klasse zu Testzwecken. 5.3.7 Die Klasse InfoWindow InfoWindow stellt ein statisches Info-Fenster zu Verfügung. Methoden +$show(message: String) Zeigt ein Info-Fenster mit der Meldung message und dem Titel Info“ an. ” +$main(args[], String): void Zur Ausführung einer Instanz dieser Klasse zu Testzwecken. 5.3.8 Die Klasse DBHandler DBHandler übernimmt die Kommunikation mit einem Datenbankserver via JDBC und stellt elementare Datenbankmethoden zur Verfügung. Destrutoren -finalize() Stellt bei der Deinstanziierung sicher, daß eine eventuell noch vorhandene JDBC-Verbindung beendet wird. Methoden +isConnected(): boolean Gib zurück, ob momentan eine Verbindung zu einem JDBCServer besteht. +connect(username: String, password: String, url: String, driver: String): void Aufbau einer JDBC-Verbindung. +disconnect(): void Beenden einer JDBC-Verbindung. 5.3. DAS PAKET DBIS.APPL.OSETO.COMMON 45 +getProductName(): String Gibt den Datenbank-Produktnamen zurück. +createStatement(): Statement Erzeugt ein neues Datenbank-Statement und gibt dieses zurück. +getMetaData(): DatabseMetaData Gibt ein DatabaseMetaData-Objekt zurück. +query(query: String): ResultSet Führt eine SQL-Anfrage aus und liefert das Ergebnis in Form einer ResultSet zurück. +prepareStatement(query: String): PreparedStatement Erzeugt ein PreparedStatement. 5.3.9 Die Klasse ConnectionSettings Diese Klasse stellt einen Dialog zur Verfügung, in dem Einstellungen zur Datenbankverbindung festgelegt werden können. Es können auch mehrere Verbindungseinstellungen verwaltet werden. Konstruktoren ConnectionSettings() Erzeugt einen neuen Dialog. Methoden -resfresh(): void Aktualisiert die Inhalte der Komponenten des Dialogfensters. +setVisible(visible: boolean) Zeigt oder versteckt das Dialogfenster. +getUserName(): String Gibt den ausgewählten Nutzernamen zurück. +getPassword(): String Gibt das ausgewählte Paßwort zurück. +getUrl(): String Gibt den ausgewählten URL zurück. +getDriver(): String Gibt den ausgewählten JDBC-Treiber-Bezeichner zurück. +getProperties(): Hashtable Gibt die alle Einstellungsdaten als Hashtable zurück. +setProperties(allProperties: Hashtable): void Setzt die Einstellungsdaten durch die angegebene Hashtable. +$main(args: String[]): void Zur Ausführung eines Objekts dieser Klasse zu Testzwecken. 5.3.10 Die Klasse JBlinker JBlinker stellt eine kleine in verschiedenen Farben leuchtende Komponente zur Verfügung. Konstruktoren JBlinker() Erzeugt eine neue JBlinker-Instanz. Methoden 46 KAPITEL 5. IMPLEMENTIERUNG +setOn(b: boolean): void Setzt den Zustand des Blinkers. +toggle(): void Wechselt den Zustand des Blinkers (an → aus bzw. aus → an). +setRed(): void Setzt die Farbe, die beim angeschalteten Zustand angezeigt wird, auf Rot. +setGreen(): void Setzt die Farbe, die beim angeschalteten Zustand angezeigt wird, auf Grün. 5.4 Das Paket dbis.appl.oseto.oracle In diesem Paket sind die oracle-spezifischen Klassen implementiert. Da u.a. eine etwas größere Anzahl von Sicht-Klassen vorhanden sind, werden diese nicht in aller Ausführlichkeit beschrieben. Einen Überblick über den Zusammenhang der SichtKlassen gibt Abbildung 5.4, S. 47. 5.4.1 Die Klasse DBBrowser DBBrowser ist von der Klasse AbstractViewModel abgeleitet und stellt den Oracle-Datenbank-Browser zur Verfügung. Der Browser besteht aus einem JSplitPane, in dem auf der linken Seite der Selektions-Baum eingefügt wird. Auf der rechten Seite erscheint in Abhängigkeit von der Selektion eine entsprechende Sicht (AbstractModelView), welche ebenfalls an dieser Stelle instanziiert werden. Weiterhin ist das “zurückbrowsen” zu vorherigen Selektionen möglich. Hierzu werden die öffentlichen Methoden browseBack und browseForward zur Verfügung gestellt. Konstruktoren DBBrowser() Erzeugt eine Instanz dieser Klasse. Methoden +refresh(): void Aktualisiert den Selektionsbaum. -showPublic(value: Object): void Zeigt die “Public”-Sicht und trägt die Auswahl in der History ein. -showUser(value: Object): void Zeigt die Nutzer-Sicht mit dem entsprechenden Nutzer an und trägt die Auswahl in der History ein. -showSysPrivs(value: Object): void Zeigt die System-Privilegien-Sicht mit dem entsprechenden Privileg an und trägt die Auswahl in der History ein. -showRole(value: Object): void Zeigt die Rollen-Sicht mit der entsprechenden Rolle an und trägt die Auswahl in der History ein. -showObject(value: Object): void Zeigt die Objekt-Sicht mit dem entsprechenden Objekt an und trägt die Auswahl in der History ein. -showObjectSelector(value: Object): void Zeigt die Objekt-Selektor-Sicht mit der entsprechenden Objekt-Auswahl an und trägt die Auswahl in der History ein. 47 5.4. DAS PAKET DBIS.APPL.OSETO.ORACLE DBBrowser SysPrivsView TablespaceUserView ObjectView ProfileView ObjectInfoView RoleView TablespaceInfoView UserView ProfileInfoView ObjectPrivsView PublicView UserInfoView TablespaceView ObjectViewInfoView ObjectIndexInfoView ObjectTypeInfoView ObjectTriggerInfoView ObjectSourceView ObjectDependencyView ObjectTableInfoView ProfileUserView ObjectTableColumnSubPrivsView ObjectTableColumnSubConView ObjectTableColumnSubView ObjectTableColumnView RoleTreeView UserObjectView UserObjPrivsView UserSysPrivsView UserQuotaView UserProfileView UserDependencyView ObjectTableColumnSubComView Abbildung 5.2: Der Zusammenhang zwischen den Sicht-Klassen 48 KAPITEL 5. IMPLEMENTIERUNG -updateBrowseButtons(): void Aktualisiert die Browse-Buttons in Abhängigkeit von der aktuellen Position in der History. +browseForward(): void Zeigt die nächste Sicht in der History an. +browseBack(): void Zeigt die vorhergehende Sicht in der History an. +showHistoryAt(position: int): void Zeigt Sicht mit der entsprechenden Auswahl aus der History an. +show(item: DBBrowserItem): void Zeigt eine Sicht mit dem entsprechenden Parameter an. Die Auswahl wird der History hinzugefügt. +addToHistory(item: DBBrowserItem): void Fügt die angegebene Auswahl der History hinzu. 5.4.2 Die Klasse DBBrowserItem Instanzen dieser Klasse beinhalten die Information einer Selektion für den Datenbankbrowser. Jeder History-Eintrag des Browsers entspricht einer Instanz dieser Klasse. Hierzu werden der Typ der Selektion und ein Auswahlparameter abgespeichert. Weiterhin werden die möglichen Typen als statische Variablen (int) zur Verfügung gestellt. Attribute +$PUBLIC: int Entspricht Public. +$USER: int Entspricht einer Nutzer-Auswahl. +$ROLE: int Entspricht einer Rollen-Auswahl. +$OBJECT: int Entspricht einer Objekt-Auswahl. +$OBJECTSELECTOR: int Entspricht der Auswahl des Objekt-Selektors. +$SYSPRIV: int Entspricht einer System-Privilegien-Auswahl. +$DNINFO: int Entspricht der Datenbank-Info-Auswahl. +type: int Typ der Selektion. +value: int Auswahl-Parameter der Selektion. Konstruktoren DBBrowserItem(type: int, value: Object) Erzeugt eine Instanz dieser Klasse. 5.4.3 Die Klasse ObjectView Diese Klasse stellt die Haupt-Sicht für das Anzeigen von Informationen über ein Schema-Objekt zur Verfügung. Sie enthält Untersichten, um weitere Informationen über ein bestimmtes Schema-Objekt anzuzeigen. Die Menge der angezeigten Untersichten ändert sich dynamisch in Abhängigkeit vom Schema-Objekt-Typ. 5.4. DAS PAKET DBIS.APPL.OSETO.ORACLE 49 Konstruktoren ObjectView() Erzeugt eine neue Instanz dieser Klasse. Methoden +setValue(value: Object): void Setzt die Objekt-ID des Objektes, das angezeigt werden soll. Weiterhin werden eventuell entsprechende Untersichten entfernt bzw. hinzugefügt. Die entsprehende Methode der Eltern-Klasse wird aufgerufen, damit der Parameter auch an die Untersichten weitergegeben wird. 5.4.4 Die Klasse UserObjPrivsView Diese von AbstractViewModelThreaded abgeleitete Klasse stellt eine Sicht zur Verfügung, in der die einem Nutzer direkt und indirekt zugewiesenen Objekt-Privilegien angezeigt werden. (Hierbei sind eventuelle Spalten-Privilegien einer Relation mit eingeschlossen.) Konstruktoren UserObjPrivsView() Erzeugt eine neue Instanz dieser Klasse. Methoden +reload(): void Aktualisiert die angezeigten Objekt-Privilegien. An dieser Stelle werden nur die direkt zugewiesenen Privilegien angezeigt. +actionPerformed(): void Ruft die entsprechende Methode in der Eltern-Klasse auf und aktualisiert zusätzlich die Anzeige der bis jetzt berechneten Privilegien. +newTask Erzeugt einen neuen Berechnungsprozess (UserObjPrivsView.Task). 5.4.5 Die Klasse UserObjPrivsView.Task Prozess (von SwingWorker abgeleitet), der das Berechnen der indirekt (über Rollen) zugewiesenen Objekt-Privilegien übernimmt. Hierzu wird der zugewiesene Rollenbaum durch einen Breitensuche“-Algorithmus berechnet. Zu einem gefun” denen Knoten (Rolle) werden sofort die zugewiesenen Objektprivilegien angefragt und in der Ergebnistabelle mit dem entsprechenden Pfad abgespeichert. Benutzte vorbereitete Anfragen (prepared statement): • select OWNER, TABLE NAME, GRANTOR, PRIVILEGE, GRANTABLE from DBA TAB PRIVS where GRANTEE = ? • select GRANTED ROLE from DBA ROLE PRIVS where GRANTEE = ? (Die ? stellen hier Platzhalter da, die zur Laufzeit durch entsprechende Parameterwerte ersetzt werden.) Methoden +construct(): Object Methode, die die Berechnungen durchführt. +finished(): void Aktualisiert die Ansichtstabelle nach Beendigung des Berechnungsprozesses. 50 5.4.6 KAPITEL 5. IMPLEMENTIERUNG Weitere Sicht-Klassen Da alle Sicht-Klassen von derselben Elternklasse abgeleitet sind, verzichte ich im folgenden auf die Schnittstellen-Beschreibung. Ich gehe nur noch auf eventuelle Besonderheiten und auf die benutzten Oracle-Dictionary-Sichten ein. PublicView Diese Klasse stellt die Haupt-Sicht für das Anzeigen von Informationen über die öffentliche Gruppe PUBLIC zur Verfügung. Sie enthält Untersichten, um weitere Informationen über diese Gruppe anzuzeigen. RoleView Diese Klasse stellt die Haupt-Sicht für das Anzeigen von Informationen über eine Rolle zur Verfügung. Sie enthält Untersichten, um weitere Informationen über die Rolle anzuzeigen. UserView Diese Klasse stellt die Haupt-Sicht für das Anzeigen von Informationen über einen Nutzer zu Verfügung. Sie enthält Untersichten, um weitere Informationen über einen bestimmten Nutzer anzuzeigen. UserInfoView Diese Klasse stellt eine Sicht zur Verfügung, die Informationen zu einem Nutzer aus der Oracle-Data-Dictionary-Sicht DBA USERS bzw. USER USERS anzeigt. RoleTreeView Diese Klasse stellt eine Sicht zur Verfügung, die Informationen über zugewiesene Rollen aus der Oracle-Data-Dictionary-Sicht DBA ROLE PRIVS bzw. USER ROLE PRIVS anzeigt. Die zugewiesenen Rollen werden in Form eines Baumes dargestellt (JTree). UserObjectView Diese Klasse stellt eine Sicht zur Verfügung, die die Schemaobjekte eines Nutzers anzeigt. Diese Sicht greift auf die Oracle-Data-Dictionary-Sicht DBA OBJECTS bzw. USER OBJECTS zu. UserObjPrivsView Diese von AbstractViewModelThreaded abgeleitete Klasse stellt eine Sicht zur Verfügung, in der die einem Nutzer direkt oder indirekt zugewiesenen ObjektPrivilegien angezeigt werden. (Hierbei sind eventuelle Spalten-Privilegien einer Relation mit eingeschlossen.) Diese Sicht greift auf die folgenden Oracle-Data-Dictionary-Sichten zu: USER OBJECTS, DBA OBJECTS, USER COL PRIVS, DBA COL PRIVS, USER TAB PRIVS, DBA TAB PRIVS 5.4. DAS PAKET DBIS.APPL.OSETO.ORACLE 51 UserSysPrivsView Diese von AbstractViewModelThreaded abgeleitete Klasse stellt eine Sicht zur Verfügung, in der die einem Nutzer direkt oder indirekt zugewiesenen SystemPrivilegien angezeigt werden. Diese Sicht greift auf folgende Oracle-Data-Dictionary-Sichten zu: USER SYS PRIVS, DBA SYS PRIVS, USER ROLE PRIVS, DBA ROLE PRIVS UserQuotaView Diese Klasse stellt eine Sicht zur Verfügung, die die zugewiesenen Quotas eines Nutzers anzeigt. Diese Sicht greift auf die Oracle-Data-Dictionary-Sicht DBA TS QUOTAS bzw. USER TS QUOTAS zu. UserProfileView Diese Klasse stellt eine Sicht zur Verfügung, die die Resourcen des Profils eines Nutzers anzeigt. Diese Sicht greift auf die Oracle-Data-Dictionary-Sicht DBA PROFILES zu. UserDependencyView Diese Klasse stellt eine Sicht zur Verfügung, in der die direkten und indirekten Oracle-Dependencies der Objekte eines Nutzers angezeigt werden. Diese Sicht greift auf ALL OBJECTS, DBA OBJECTS, USER DEPENDENCIES und DBA DEPENDENCIES zu. SysPrivsView Diese Klasse stellt eine Sicht zur Verfügung, die die direkten oder indirekten Zuweisungen eines Systemprivilegs anzeigt. Diese Sicht greift auf die Oracle-Data-Dictionary-Sichten DBA SYS PRIVS bzw. USER SYS PRIVS zu. Als Parameter wird dieser Sicht die ID des Systemprivilegs übergeben (setValue). ProfileView Diese Klasse stellt die Haupt-Sicht für das Anzeigen von Informationen über Profile zur Verfügung. Sie enthält Untersichten, um weitere Informationen über diese Gruppe anzuzeigen. Als Parameter wird dieser Sicht der Name des Profils in Form einer Zeichenkette übergeben (setValue). ProfileInfoView Diese Klasse stellt eine Sicht zur Verfügung, die Informationen zu einem Profil aus der Oracle-Data-Dictionary-Sicht DBA PROFILES anzeigt. ProfileUserView Diese Klasse stellt eine Sicht zur Verfügung, die die Nutzer zu einem bestimmten Profil anzeigt. Diese Klasse greift auf Oracle-Data-Dictionary-Sicht DBA USERS zu. 52 KAPITEL 5. IMPLEMENTIERUNG TablespaceView Diese Klasse stellt die Haupt-Sicht für das Anzeigen von Informationen über Tablespaces zur Verfügung. Sie enthält Untersichten, um weitere Informationen über diese Gruppe anzuzeigen. Als Parameter wird dieser Sicht der Name des Tablespace in Form einer Zeichenkette übergeben (setValue). TablespaceInfoView Diese Klasse stellt eine Sicht zur Verfügung, die Informationen zu einem Tablespace aus der Oracle-Data-Dictionary-Sicht DBA TABLESPACES bzw. USER TABLESPACES anzeigt. TablespaceUserView Diese Klasse stellt eine Sicht zur Verfügung, die die Nutzer anzeigt, denen eine Quota auf einer bestimmten Tablespace zugewiesen ist (dieses schließt default und temporary tablespaces ein). ObjectView Diese Klasse stellt die Haupt-Sicht für das Anzeigen von Informationen über ein Schema-Objekt zur Verfügung. Sie enthält Untersichten, um weitere Informationen über ein bestimmtes Schema-Objekt anzuzeigen. Die Menge der angezeigten Untersichten ändert sich dynamisch in Abhängigkeit vom Schema-Objekt-Typ. ObjectView Diese Klasse greift auf Oracle-Data-Dictionary-Sichten DBA TS QUOTAS und DBA USERS zu. ObjectInfoView Diese Klasse stellt eine Sicht zur Verfügung, die Informationen zu einem SchemaObjekt aus der Oracle-Data-Dictionary-Sicht DBA OBJECTS anzeigt. ObjectPrivsView Diese Klasse stellt eine Sicht zur Verfügung, die die direkt oder indirekt vergebenen Privilegien anzeigt. Diese Sicht greift auf die Oracle-Data-Dictionary-Sichten DBA TAB PRIVS bzw. ALL TAB PRIVS zu. ObjectDependencyView Diese Klasse stellt eine Sicht zur Verfügung, in der die direkten und indirekten Oracle-Dependencies eines Objekts angezeigt werden. Diese Sicht greift auf ALL OBJECTS, DBA OBJECTS, ALL DEPENDENCIES und DBA DEPENDENCIES zu. ObjectSourceView Diese Klasse stellt eine Sicht zur Verfügung, die den Quelltext eines SchemaObjekts aus der Oracle-Data-Dictionary-Relation SOURCE$ anzeigt. 5.4. DAS PAKET DBIS.APPL.OSETO.ORACLE 53 ObjectTriggerInfoView Diese Klasse stellt eine Sicht zur Verfügung, die Informationen zu einem Trigger aus der Oracle-Data-Dictionary-Sicht DBA TRIGGERS anzeigt. ObjectTypeInfoView Diese Klasse stellt eine Sicht zur Verfügung, die Informationen zu einem Typ aus der Oracle-Data-Dictionary-Sicht DBA TYPES anzeigt. ObjectIndexInfoView Diese Klasse stellt eine Sicht zur Verfügung, die Informationen zu einer Sicht aus der Oracle-Data-Dictionary-Sicht DBA INDEXES anzeigt. ObjectViewInfoView Diese Klasse stellt eine Sicht zur Verfügung, die Informationen zu einer Sicht aus der Oracle-Data-Dictionary-Sicht DBA VIEWS anzeigt. ObjectTableInfoView Diese Klasse stellt eine Sicht zur Verfügung, die Informationen zu einer Tabelle aus der Oracle-Data-Dictionary-Sicht DBA TABLES anzeigt. ObjectTableColumnView Diese Klasse stellt eine Sicht zur Verfügung, die die Spalten einer Oracle-Relation in Form einer Tabelle darstellt (DBA TAB COLUMNS). Je Zeile werden Name und Typ der jeweiligen Spalte angezeigt. Zusätzlich enthält diese Sicht die Untersicht ObjectTableColumnSubView, die weitere Informationen zu der jeweils ausgewählten Spalte anzeigt. ObjectTableColumnSubView Diese von AbstractViewContainerModel abgeleitete Klasse stellt Informationen zu einer Tabellen-Spalte dar. Als Container enthält sie folgende Untersichten: ObjectTableColumnSubConView, ObjectTableColumnSubPrivsView, ObjectTableColumnSubComView. Als Parameter wird dieser Sicht die Objekt-ID der Tabelle und der Spaltenname (beide als Zeichenkette) in Form einer Hashtable übergeben, mit den Schlüsselwerten “tableOID” und “columnName” (setValue). ObjectTableColumnSubConView Diese Klasse stellt eine Sicht zur Verfügung, die die Constraints einer Tabellenspalte aus der Oracle-Data-Dictionary-Sicht DBA CONS COLUMN anzeigt. ObjectTableColumnSubPrivsView Diese Klasse stellt eine Sicht zur Verfügung, die die vergebenen Spaltenprivilegien einer Tabellenspalte aus der Oracle-Data-Dictionary-Sicht DBA COL PRIVS anzeigt. 54 KAPITEL 5. IMPLEMENTIERUNG ObjectTableColumnSubComView Diese Klasse stellt eine Sicht zur Verfügung, die die Kommentare einer Tabellenspalte aus der Oracle-Data-Dictionary-Sicht DBA COL COMMENTS anzeigt. Kapitel 6 Ausblick An dieser Stelle möchte ich selbst ein paar Verbesserungs- bzw. Erweiterungsvorschläge für meine Applikation machen. Mit dem entworfenen Sichtkonzept soll eine leicht erweiterbare und flexible Möglichkeit zur Verfügung gestellt werden. Die Abhängigkeiten und Verbindungen zwischen den Sichtmodulen sind bis jetzt aber noch fest im Quellcode verankert. Diese Abhängigkeiten und Verbindungen sollten zum Beispiel in externe Definitionsdateien ausgelagert werden. Mit den inzwischen ausgereiften Java-Implementierungen von XML-Parsern, bietet sich XML als standardisierte und allgemein akzeptierte Sprache gerade zu für diesen Zweck an. Gleiches gilt auch für die Abspeicherung der Konfigurationsdaten. Als sinnvolle Erweiterung sehe ich auch eine Logik, durch die selbst bestimmt werden kann, welche Privilegien der Benutzer der Applikation hat, und auf welche Daten er damit zugreifen kann. Bis jetzt gibt es nur die Möglichkeit, zwischen den beiden extremen Modi DBA-Modus - ja / nein - zu wählen, wobei beim nichtgewählten DBA-Modus nur Privilegien vorausgesetzt werden, die jeder Oracle-Nutzer hat. Weiterhin denke ich, daß man die Ermittlung von indirekten Rechtezuweisungen noch weiter automatisieren könnte. So gibt es z.B. die Möglichkeit, die Ergebnisse, die durch die Bestimmung der indirekten Privilegienvergabe und der indirekten Objektabhängigkeiten ermittelt wurden, zu kombinieren. So könnten zum Beispiel indirekte Zugriffspfade über ein Objekt automatisch berechnet werden, für welches ein Nutzer nur indirekte Privilegien durch eine Rolle besitzt. 55 56 KAPITEL 6. AUSBLICK Kapitel 7 Beispielschema Das SQL-Skript init.sql legt Nutzer, Rollen und Objekte an, um einen beispielhaften Einblick in das Oracle-Rechte-Konzept zu ermöglichen. Diese angelegten Nutzer, Rollen und Objekte können mit dem Skript deinit.sql wieder entfernt werden. Beide Skript müssen unter dem Nutzer SYS ausgeführt werden. init.sql rem Dieses Skript muss vom Benutzer sys ausgeführt werden rem Beispiel-Profil CREATE PROFILE oseto LIMIT PASSWORD_LIFE_TIME 100; COMMIT; rem Beispiel-Nutzer mit Betriebsystem-Authentifikation CREATE USER ops$oracle DEFAULT TABLESPACE tools TEMPORARY TABLESPACE temp IDENTIFIED EXTERNALLY; GRANT CONNECT TO ops$oracle; rem DBA für Beispiel-Schema CREATE USER osetodba DEFAULT TABLESPACE tools TEMPORARY TABLESPACE temp QUOTA UNLIMITED on tools IDENTIFIED BY osetodba; GRANT CREATE PROCEDURE, CREATE SEQUENCE, CREATE SYNONYM, CREATE PUBLIC SYNONYM, CREATE TABLE, CREATE TRIGGER, CREATE VIEW to osetodba; GRANT CONNECT to osetodba; 57 58 KAPITEL 7. BEISPIELSCHEMA GRANT CREATE TYPE to osetodba; rem Rolle für Lesezugriff auf rem bestimmte Daten im Beispielschema CREATE ROLE clerk; GRANT connect TO clerk; GRANT clerk TO osetodba WITH ADMIN OPTION; REVOKE clerk FROM sys; rem Rolle für Lese- und Schreibzugriff rem auf bestimmte Daten im Beispielschema CREATE ROLE rec_clerk; GRANT clerk TO rec_clerk; GRANT rec_clerk TO osetodba WITH ADMIN OPTION; REVOKE rec_clerk FROM sys; rem Managerrolle für das Beispielschema CREATE ROLE manager; GRANT rec_clerk TO manager; GRANT manager TO osetodba WITH ADMIN OPTION; REVOKE manager FROM sys; rem Nutzer für das Beispielschema CREATE USER witchen DEFAULT TABLESPACE tools TEMPORARY TABLESPACE temp IDENTIFIED BY witchen PROFILE oseto; GRANT clerk TO witchen; CREATE USER punzel DEFAULT TABLESPACE tools TEMPORARY TABLESPACE temp IDENTIFIED BY punzel PROFILE oseto; GRANT rec_clerk TO punzel; CREATE USER nase DEFAULT TABLESPACE tools TEMPORARY TABLESPACE temp QUOTA 100m ON tools IDENTIFIED BY nase PROFILE oseto; 59 GRANT manager TO nase; COMMIT; CONNECT osetodba/osetodba@text; rem Beispiel-Typ CREATE TYPE test_type AS OBJECT ( num INTEGER, MEMBER PROCEDURE double ); / CREATE TYPE BODY test_type AS MEMBER PROCEDURE double IS g INTEGER; BEGIN g := 2; num := num * g; END double; END; / COMMIT; CREATE TABLE test_type_table (num test_type); COMMIT; rem Relationen für das Beispielschema CREATE TABLE department ( dept_no number(3) CONSTRAINT pk_dept PRIMARY KEY, dept_name varchar2(30) NOT NULL); GRANT SELECT ON department TO clerk; GRANT INSERT ON department TO rec_clerk; GRANT DELETE, UPDATE ON department TO manager; INSERT INTO department VALUES (’1’, ’Verwaltung’); INSERT INTO department VALUES (’2’, ’Buchhaltung’); COMMIT; CREATE TABLE employee ( emp_no number(3) CONSTRAINT pk_emp PRIMARY KEY, emp_lname varchar2(30) NOT NULL, 60 KAPITEL 7. BEISPIELSCHEMA emp_fname varchar2(30) NOT NULL, emp_salary number(7), emp_dept_no number(3) NOT NULL, CONSTRAINT fk_emp_dept_no FOREIGN KEY (emp_dept_no) REFERENCES department ON DELETE CASCADE); GRANT SELECT, INSERT ON employee TO rec_clerk; GRANT UPDATE, DELETE ON employee TO manager; INSERT INTO employee VALUES (’1’, ’Witchen’, ’Klaus’, ’1000’, ’1’); INSERT INTO employee VALUES (’2’, ’Punzel’, ’Maria’, ’2000’, ’2’); INSERT INTO employee VALUES (’3’, ’Nase’, ’Robert’, ’3000’, ’2’); INSERT INTO employee VALUES (’4’, ’Roeschen’, ’Anne’, ’4000’, ’1’); COMMIT; rem Beispielsicht (bewirkt Abhängigkeiten (dependencies)) CREATE VIEW view_employee AS SELECT emp.emp_lname, emp.emp_fname, emp.emp_salary, emp.emp_no, dept.dept_name FROM osetodba.department dept, osetodba.employee emp WHERE emp.emp_dept_no = dept.dept_no; CREATE PUBLIC SYNONYM public_employee for osetodba.view_employee; GRANT SELECT on employee TO public; GRANT REFERENCES (emp_no) on osetodba.employee TO witchen; rem Beispiel Procedure rem (bewirkt Abhängigkeiten (dependencies)) CREATE PROCEDURE raise_salary (emp_number number, amount number) IS BEGIN UPDATE public_employee SET emp_salary = emp_salary + amount WHERE emp_no = emp_number; END raise_salary; / GRANT EXECUTE ON raise_salary TO witchen; COMMIT; deinit.sql rem Dieses Skript muss vom Benutzer sys ausgeführt werden 61 DROP USER ops$oracle CASCADE; DROP USER osetodba CASCADE; DROP ROLE clerk; DROP ROLE rec_clerk; DROP ROLE manager; DROP USER witchen CASCADE; DROP USER punzel CASCADE; DROP USER nase CASCADE; DROP PUBLIC SYNONYM public_employee; DROP PROFILE oseto; COMMIT; 62 KAPITEL 7. BEISPIELSCHEMA Literaturverzeichnis [1] Oracle8 Administrator’s Guide Release 8.0, Oracle Corporation, 1997. [2] Oracle8 Concepts Release 8.0, Oracle Corporation, 1997. [3] Oracle8 Concepts Release 8.1.5, Oracle Corporation, 1999. [4] Oracle8 SQL Reference Release 8.0, Oracle Corporation, 1997. [5] Marlene Theriault & William Heney: Oracle Security. O’Reilly, Sebastopol, 1998. [6] UML Notation Guide, version 1.1, Rational Software, Santa Clara, 1997. 63 64 LITERATURVERZEICHNIS Teil III Nachwort 65 67 In ein paar wenigen Worten möchte ich dem Leser oder der Leserin in paar Erfahrungen mitteilen, die in solcher Form nicht in die vorangegangenden Abschnitte gepaßt hätten. Zunächst ein paar Bemerkungen zum Oracle-Datenbank-System selbst. Wenn man ein wenig hinter die Kulissen geschaut hat, sieht man, daß Oracle schon eine längere Entwicklung hinter sich gebracht hat und einige Altlasten mit sich trägt. Da bemerkt man plötzlich, daß es im Grunde keine Objekt-, sondern nur TabellenPrivilegien gibt (2.2.3, S. 20). Ähnlich mit Altlasten behaftet sind auch viele der Data-Dictionary-Sichten. Neben Sichten, die gänzlich nur aus Abwärts-Kompatibilitätsgründen vorhanden sind, fällt insbesondere auf, daß die aktuellen Sichten nicht sehr einheitlich entworfen sind. Da kann es schon vorkommen, daß sich entsprechende Attribute in verschiedenen Sichten völlig unterschiedlich benannt sind. Einmal ist von user id“ an anderer ” Stelle von schema id“ die Rede, um nur ein Bespiel zu nennen. Dieser Umstand ” erschwert den Alltag desjenigen sehr, der viel mit Data-Dictionary-Sichten zu tun hat. Desweiteren hätte ich mir einige Zeilen Quellcode für die Applikation sparen können. Weiterhin mußte ich nach einiger Zeit einsehen, daß das zunächst konsequent anmutende Rechtekonzept Oracles doch von einigen Ausnahmeregelungen durchlöchert ist (siehe z.B. 2.1.1, S. 17). Wenn man sich dessen nicht bewußt ist, kann man schnell ins Grübeln kommen, wenn in bestimmten Situation Dinge nicht funktionieren, die doch offensichtlich funktionieren müssten. Hinzu kommt, daß gerade solch wichtige Informationen recht weit in der Dokumentation verstreut sind. Probleme bereitet hat u.a. auch der JDBC-Thin-Client, der mit der OracleVersion 8.0.5 ausgeliefert wurde. Nachdem ich Nächte damit verbracht hatte, Fehler in meinem eigenen Quellcode zu suchen, sind bestimmte Probleme mit der Installation einer neuen Version des JDBC-Treiber einfach verschwunden. Als ich einen Blick in das Instanz-Initialisierungs-Skript sql.bsq“ warf, habe ” ich mir die Frage gestellt, wie das überhaupt funktionieren soll. Kurios kam es mir zunächst schon vor, als ich sah, daß an einer Stelle eine Tabelle angelegt wird, in der alle Tabellen dieser Instanz eingetragen werden, d.h. diese Tabelle selbst auch. Auf der anderen Seite ist es aber auch sehr interessant zu sehen, wie ein Datenschema in einem kommerziellen und erfolgreichen Datenbanksystem realisiert ist. Weiterhin habe ich die Erfahrung gemacht, daß es relativ einfach ist mit Java und JDBC eine Datenbank-Applikation zu programmieren. Gerade wenn die Performance nicht oberste Priorität ist, kann dieses Gespann nur empfohlen werden. Da die Handhabung von Anfrageergebnissen über Java-Objekte stattfindet, muß man keine sonderlich große Schwierigkeiten überwinden, um mit verschiedenen Datentypen umzugehen. Diesen Vorteil bieten natürlich die meisten objekt-orientierten Sprachen - mit JDBC hat man aber eine transparente und recht verbreitete Spezifikation. Somit müßte man z.B. nicht besonders viel Zeit aufbringen, um die Applikation auch auf andere Datenbanksysteme zu erweitern. Abstriche muß ich aber noch bei den in meiner Applikation benutzten JFCs (java foundation classes) machen. Ich habe die Erfahrung gemacht, daß einige visuelle Komponenten nicht so reagieren, wie man es nach dem Lesen der Dokumentation erwarten sollte, und die somit nicht leicht zu handhaben sind.