Das ClassiX®-System bietet ein sehr differenziertes System der Überwachung
und Einschränkung von Zugriffsrechten an. Dieses Security-System von ClassiX®
ist optional, es kann, aber es muss nicht benutzt werden.
Allerdings kann ein Anwender seine Datenbank so modifizieren, dass ein Zugriff
ohne Überwachung der Zugriffsrechte nicht mehr möglich ist.
Die Zugriffsrechte werden durch Security-Objekte beschrieben.
Security-Objekte können folgendes verhindern oder erlauben:
¹) Dies bezieht sich nur auf persistente Objekte aus der Datenbank. Für transiente Objekte gibt es keine Kontrolle der Zugriffsrechte!
Die Security-Objekte, die das Zugriffsprofil eines bestimmten Benutzers beschreiben, sind mit dem CX_USER-Objekt für diesen Anwender verbunden und
werden beim Login aktiviert (beim ClassiX®-System angemeldet).
Angemeldete Security-Objekte bleiben aktiv bis zum nächsten Start des ClassiX®-Systems,
man kann sie nicht wieder deaktivieren.
Nun bleibt immer noch die Möglichkeit, dass sich Unbefugte mit selbst
geschriebenem InstantView®-Code Zugang zu sensiblen Daten
verschaffen.
Auch davor kann man sich schützen. Wenn eine Datenbank ein Master-Security-Objekt
enthält, ist jeder unautorisierte Zugriff mit InstantView®-Anweisungen
unmöglich.
Wer jetzt immer noch bestimmte Daten sehen will, muss eigene Programme mit
C++ entwickeln. Wenn jemand die dafür nötigen Mittel besitzt und Energie
aufbringt, kann er/sie nicht nur auf die Daten-Objekte sondern auch auf
Informationen über die gespeicherten Klassen zugreifen. Das heißt, dies ist
eine ernst zu nehmende Möglichkeit, geschützte Daten unbefugt zu lesen oder
auch zu modifizieren!
Im letzten Abschnitt dieser Übersicht zeigen wir, wie auch
dieses Einfallstor geschlossen werden kann!
Wie oben gesagt, kann der lesende und schreibende Zugriff auf bestimmte Daten
verhindert werden.
Der Gültigkeitsbereich solcher Einschränkungen kann sich beziehen auf
Die Angaben auf dieser Ebene betreffen zunächst alle Datenfelder eines Objekts, natürlich auch dynamische Datenfelder.
Für bestimmte Zugriffsausdrücke können abweichende Zugriffsrechte vergeben
werden (CX_ATTRIBUTE_SECURITY).
Objekte der Klasse CX_ATTRIBUTE_SECURITY sind immer entweder einem
CX_CLASS_SECURITY oder einem CX_OBJECT_SECURITY-Objekt untergeordnet.
Der allgemeinste Fall einer Beschreibung von Lese/Schreibrechten gilt für alle Zugriffsausdrücke für alle Objekte einer bestimmten Klasse bzw. davon abgeleiteter Klassen, der speziellste Fall betrifft dann einen ganz bestimmten Zugriffsausdruck, wenn dieser auf ein ganz bestimmtes individuelles Objekt angewendet wird.
Verschiedene Security-Objekte der Klassen CX_CLASS_SECURITY und CX_OBJECT_SECURITY² können mit einem Objekt der Klasse CX_SECURITY_SET zusammengefasst werden. Durch die Kombination von allgemeinen und spezielleren Aussagen lassen sich die Zugriffsrechte oft mit nur wenigen Objekten beschreiben.
²) das gilt auch für CX_MESSAGE_SECURITY und CX_SECURITY_OPTIONS, siehe unten. CX_ATTRIBUTE_SECURITY-Objekte kommen nie direkt im Security-Set vor.
Wenn das ClassiX®-System die Berechtigung eines Zugriffs via Zugriffsausdruck auf ein bestimmtes Objekt überprüft und ein Security-Set aktiv ist, entscheidet das erste Element des Sets, das eine für den Fall zutreffende Festlegung trifft. Liefert keines der Security-Objekte im Security-Set eine Aussage, so ist der Zugriff verboten.
Wenn ein Security-Objekt im ClassiX®-System aktiv ist, gilt: Alles was nicht ausdrücklich erlaubt ist, ist verboten!
Das ist aber kein Problem: Ein CX_CLASS_SECURITY-Objekt für die Klasse CX_CLASS (und abgeleitete), das alles erlaubt, bildet einen Hintergrund für spezielle abweichende Festlegungen.
Dabei spielt die Reihenfolge im Security-Set eine Rolle: allgemeine Aussagen
dürfen erst nach den speziellen kommen.
Security-Sets dürfen weitere Security-Sets als Element enthalten.
Alle Beschreibung von Zugriffsrechten
lassen sich durch Security-Objekte in richtiger Anordnung in einem
Security-Set abbilden.
Als Set kann man Untergruppen bestimmter Rechte zusammenstellen, und einem
User dann eine Kombination solcher Untergruppen in einem die Teilgruppen
zusammenfassenden Security-Set zuordnen.
Es besteht noch eine weiter Möglichkeit: Spezialisierende Security-Objekte in die Collection spezializations eines Security-Objekts mit allgemeiner Aussage zu stellen.
Es macht keinen inhaltlichen Unterschied, ob das die Sonderfälle
beschreibende Security-Objekt S1 in einem Set vor dem Objekt mit der
allgemeinen Festlegung S0 steht, oder ob im Set nur S0 zu
finden ist, und S0 auf S1 über specializations
verweist.
Allerdings ist die letztere Methode schneller. Es müssen weniger Objekte
getestet werden, in S1 wird nur dann nachgesehen, wenn das übergeordnete
Objekt schon eine Aussage treffen konnte (siehe Hinweise
zu Performance).
| InstantView®-Statement | was passiert |
|---|---|
| Copy | Ergebnis ACCESS_DENIED |
| Get | Ergebnis ACCESS_DENIED |
| FillWindow | Windowobjekt wird ausgeblendet |
| InstantView®-Statement | was passiert |
|---|---|
| Put | Fehlermeldung 638 |
| DrainWindow | |
| Link, Unlink (bzw. SetReference, ClearReference, Insert, Remove) | |
| DeleteSlot, AssignSlot | |
| AdjustView | Windowobjekt wird in den NON_SELECTABLE-Modus versetzt |
Der Befehl AdjustView setzt den NON_SELECTABLE-Zustand wieder zurück, wenn
Schreibrechte bestehen.
Indem man ein Eingabefenster mit AdjustView vor der Eingabe des Anwenders
anpasst, vermeidet man, dass das abschließenden DrainWindow mit Fehler 638
scheitern kann.
Erlaubnis oder Verbot dafür kann nur pro Klasse vergeben werden - mit CX_CLASS_SECURITY-Objekten.
Alles was beim Thema Zugriff auf Datenfelder über die Möglichkeiten der Kombination gesagt wurde, gilt auch hier.
Folgende InstantView®-Befehle sind betroffen:
| InstantView®-Statement | was passiert |
|---|---|
| CreatePersObject | Fehlermeldung 635 |
| CopyPersObject | |
| DeleteObject | Fehlermeldung 636 |
Wenn ein Security-Objekt der Klasse CX_MESSAGE_SECURITY beim ClassiX®-System angemeldet wird (gewöhnlich als Element des angemeldeten CX_SECURITY_SET-Objekts), sperrt es die Message.
Folgende InstantView®-Befehle sind betroffen:
| InstantView®-Statement | was passiert |
|---|---|
| SendMsg(msg) | Fehlermeldung 640 |
| SendMsg(msg, DIRECT) | |
| PostMsg(msg) | |
| TestMsg(msg) | liefer ACCESS_DENIED, wenn die Message msg gesperrt ist, andernfalls TRUE |
Es ist sinnvoll, mit der Anweisung TestMsg die Menüs bzw. Buttons einer Anwendung so anzupassen, dass die betroffenen Teilanwendungen erst gar nicht ausgewählt werden können.
Mit dem Monitor-Window steht der InstantView®-Interpreter zur interaktiven Ausführung von Befehlen bereit, auch mit Zugriff auf die Objekte der Datenbank. Diese Möglichkeit soll nicht jedem Anwender zur Verfügung stehen.
Ein Objekt der Klasse CX_SECURITY_OPTIONS stellt 96 Bits bereit, mit dem besondere Systemfunktionen explizit erlaubt werden können - sobald ein solches Objekt aktiv ist.
Zur Zeit ist nur Bit 0 belegt und dem Start des Monitor-Fensters zugeordnet.
Enthält die Datenbank ein Master-Security-Objekt ( Klasse CX_MASTER_SECURITY), so wird dieses schon beim Systemstart aktiviert und verbietet (fast) alle Zugriffe. Erst ein erfolgreiches Login beseitigt diese Sperre. "Fast" alle Zugriffe heißt: einige wenige Funktionen der Klassen CX_CYBER_ENTERPRISE und CX_USER können aufgerufen werden, damit das Login mit InstantView®-Code realisiert werden kann.
Ein aktives Master-Security-Objekt verweigert alle Schreibrechte und für alle Zugriffspfade das Lese-Recht, mit einer Ausnahme: Der Pfad besteht nur aus einem Term (kein Weiter-Navigieren möglich !) und dies ist der Aufruf einer Funktion, die durch einen entsprechenden Eintrag im MDI vom Security-Check befreit ist.
Die Klassen CX_CYBER_ENTERPRISE und CX_USER besitzen solche Funktionen³:
| Klasse | Funktion | äquivalenter Zugriffsausdruck |
|---|---|---|
| CX_CYBER_ENTERPRISE | UniqueID() | uniqueID |
| NameOfPartner() | partner.name | |
| VatIDOfPartner() | partner.vatID | |
| DataBaseLayer() | dataBaseLayer | |
| CX_USER | ClearingObjectOfPartner(a, b) | partner.ClearingObject(a,b) |
| HasPassword() | Copy(password.password) if ... | |
| This() | this |
³) Zugriffsausdrücke mit den hier genannte Funktionen werden nur vom CX_MASTER_SECURITY-Objekt immer akzeptiert. Für CX_ATTRIBUTE_SECURITY sind sie normaler Bestandteil eines Zugriffsausdrucks, wie jeder anderer Funktionsaufruf auch.
Mit Hilfe dieser Funktionen können mit InstantView® geschriebene
Login-Module auch bei aktivem Master-Securtiy-Objekt arbeiten.
Die Funktion Login() der Klasse CX_USER deaktiviert das
Master-Security-Objekt und aktiviert Security-Objekte entsprechend des
Nutzer-Profils.
Darüber hinaus kann man vom Master-Security-Objekt uneingeschränkte
Zugriffsrechte bekommen, wenn man das Passwort dieses Objektes kennt.
Damit kann ein ausgewählter Personenkreis administrative Aufgaben lösen, auch
wenn der-/diejenige nicht als User in der Datenbank gespeichert ist (und das wäre
die Voraussetzung für ein Login).
Bei der ersten Anfrage nach Zugriffsrechten sendet das Master-Security-Objekt die system-interne Message MASTER_PASSWORD, mit einem Objekt der Klasse CX_STRING auf dem Stack.
Wird auf diese Message reagiert und in den String das richtige Passwort
geschrieben, so erlaubt das Master-Security-Objekt diese und alle folgenden
Anfragen.
Ein Master-Security-Objekt kann ein einziges Mal mit dem Utility cxgosr.exe in
einer Datenbank angelegt werden, und auch nur auf diese Weise (CreatePersObject(CX_MASTER_SECURITY)
geht natürlich nicht!)
Fremde Programme sind alle nicht zum ClassiX®-System
gehörenden Programme.
Allen Fremd-Programmen kann der Zugriff zur Datenbank vollständig verwehrt
werden.
Nun ist es auch nicht mehr möglich, mit C++ eigene Programme zu entwickeln, um
in der Datenbank eines Kunden zu lesen oder zu schreiben.
Diese Restriktion kann, wenn ein Kunde das wünscht, noch verschärft werden:
Nur das beim Kunden installierte (und bei ihm entsprechend angepasste) ClassiX®-System
kann auf die Datenbank zugreifen; jede andere ClassiX®-Installation
wird auch zum Fremdprogramm.
Variante 1 - Datenbank sperren - Zugang nur mit Standard-ClassiX®-System
Schema-Keys sind zwei Integer-Zahlen. Die DLL enthält diese Zahlen, aber in
modifizierter Form, so dass man sie dort nicht
finden kann.
Variante 2 - Datenbank sperren - Anwender erzeugt eigene DLL mit Key-Werten, die
nur ihm bekannt sind
Der Anwender sieht nur dieses und das Header-File cxProtect.hpp. Alles
andere befindet sich in
einer statischen Library - dieser C++-Code ist nur ClassiX® bekannt. Es
entsteht eine DLL, die sich von der oben genannten nur durch die anderen
Schlüsselwerte unterscheidet.
Der Zugang zu den Daten eines Unternehmens in der Datenbank des ClassiX®-Systems kann auf verschiedenen Ebenen kontrolliert werden:
Gesamte Datenbank gesperrt außer für das spezielle ClassiX®-System eines Anwenders. Die Schlüssel vergibt (und kennt nur) der Anwender selbst. |
Eigene Protection DLL erzeugen. .ini-File DLLs(..., myProtectionDLL) |
Gesamte Datenbank gesperrt außer für Standard- ClassiX®-System(e). Schlüssel vergibt und kennt ClassiX®. |
.ini-File DLLs(..., cxProtectDB) |
Daten für InstantView®
nur nach erfolgreichem Login sichtbar. Zugriff auf die Datenbank aber mit C++-Code möglich. |
CX_MASTER_SECURITY |
Datenzugriff nach Login entsprechend dem Zugangsprofil des Anwenders. |
CX_CLASS_SECURITY CX_OBJECT_SECURITY CX_ATTRIBUTE_SECURITY |
Unbeschränkter Zugang zu allen Daten. |
keine Protection DLL, keine aktiven Security-Objekte |
Zugang zu Teilanwendungen regeln Objekte der Klasse CX_MESSAGE-SECURITY.
Die Klasse CX_SECURITY_OPTIONS erlaubt oder sperrt bestimme System-Funktionen /
System-Optionen -
zur Zeit nur den Aufruf des Monitor-Windows.
Der Aufbau der Zugriffsrechte sollte aus drei Teilen bestehen.
| Hierbei sollte der erste Teil aus einer
Standardsperre bestehen, die jedem Benutzer oder einer Gruppe von
Benutzern zugewiesen werden muss. So sollte der normale Benutzer keinen
Zugriff auf administrative Bereiche haben. Allerdings muss jeder Benutzer über einen Zugriff auf sein Passwort haben, um es selber neu zu setzen. |
![]() |
| Im zweiten Teil werden dann die spezifischen
Einstellungen der Benutzer oder Benutzergruppen vorgenommen. Hier sollten alle Modulbereiche, auf die der Benutzer keinen Zugriff haben darf durch die Klassenzugriffsobjekte gesperrt werden. Zudem sollten aber alle Klassentypen, die der Benutzer editieren darf, hier freigeschaltet werden, da im nächsten Bereich eine standardmäßige Zugriffsbeschränkung fast aller Klassen folgt. (Treten widersprüchliche Zugriffsbeschränkungen auf, so gilt immer die erste. somit lässt sich ein Standardanmeldeschluss definieren, der durch diesen Teil doch spezifiziert werden kann.) |
![]() |
| Im letzten Teil sollte eine Standardfreigabe
aller Klassen erfolgen. Insbesondere der Klassen, die überall im System
verwendet werden, aber kein Geschäftsobjekt beschreiben. Hierzu zählen
zum Beispiel Datumsobjekte, Zähler, Monitore und weitere.
Außerdem sollte ein Lesezugriff auf alle Klassen gewährt werden. Ausnahmen kann man ja in einem der vorherigen Teile definieren. |
![]() |