Hallo,
ich bräuchte Unterstützung oder Ideen zur Lösung meines Problems:
Name des in der Webanwendung (verifiziert gegen ein ActiveDirectory) angemeldeten Nutzers soll in der Triggerfunktion verwendet werden, damit im Änderungsnachweis erkennbar ist, wer wann welche Einträge vorgenommen/geändert/gelöscht hat.
Dieser Nachweis ist für ausgewählte Tabellen zwingend notwendig, bei anderen wünschenswert - weil “Ich habe das nicht gemacht!” ist die häufigste Antwort bei der Frage “Wer hat den Wert dort eingetragen?”.
Eckdaten:
- Webanwendung
- PHP/HTML/CSS/JavaScript, wobei Datenbankzugriffe NUR über PHP programmiert wurden und werden
- Authentifizierung mittels ActiveDirektory
- Einträge in pg_hba.conf:
host DB all IP-BEREICH ldap ldapserver=IP-ADRESSE ldapprefix=“PREFIX” ldapsuffix=""
wobei für jede DB davor noch Einträge für administrative (anmeldungsbezogene) Anmeldungen mit Passwort vorhanden sind
- Trigger, um Änderungen in der DB anmeldungsbezogen zu dokumentieren - siehe oben!
Problem:
Für den Verbindungsaufbau zur Datenbank aus der Anwendung heraus wird Nutzername und PASSWORD benötigt. Das Password während der Ausführung (vom Zeitpunkt der Anmeldung mit Abgleich gegen das AD bis zur Abmeldung bzw. Verfall der Session) in einer PHP-Session-Variablen zu speichern finde ich suboptimal, weil der Zugriff darauf (mit etwas gutem Willen) möglich ist. Aktuell stelle ich über Prozeduren sicher, daß bei Codeänderungen ein sofortiger Stop der Ausführung erfolgt. Dies ist ein Minimalschutz, aber nicht das, was ich mir letztendlich vorstelle.
Vielleicht ist ja auch mein Ansatz nicht ideal oder einfach falsch, aber für die Dokumentation der Änderungen an ausgewählten Tabellen ist die Zuordnung des angemeldeten Nutzers (in PHP gegen das AD verifiziert) zwingend erforderlich.
Für die betreffenden Tabellen werden Triggerfunktionen erstellt:
CREATE OR REPLACE FUNCTION public.TABELLE_delete()
RETURNS trigger AS
$BODY$
BEGIN
INSERT INTO public.tupda(aenderung_nutzer,aenderung_datum,aenderung_zeit,aenderung_tabelle,aenderung_feld,aenderung_wert_alt,aenderung_wert_neu,primary_key_wert) VALUES(current_user,now(),now(),'TABELLE','gruppe|gruppe_beschreibung|gruppe_system|gilt_bis',OLD.gruppe || '|' || OLD.gruppe_beschreibung || '|' || OLD.gruppe_system || '|' || OLD.gilt_bis,'GELOESCHT',OLD.pk_vw01);
RETURN NEW;
END;
$BODY$
LANGUAGE plpgsql VOLATILE
COST 100;
CREATE OR REPLACE FUNCTION public.TABELLE_last_change()
RETURNS trigger AS
$BODY$
BEGIN
if (TG_OP = 'UPDATE') THEN
INSERT INTO public.tupda(aenderung_nutzer,aenderung_datum,aenderung_zeit,aenderung_tabelle,aenderung_feld,aenderung_wert_alt,aenderung_wert_neu,primary_key_wert) VALUES(current_user,now(),now(),'TABELLE','gruppe|gruppe_beschreibung|gruppe_system|gilt_bis',OLD.gruppe || '|' || OLD.gruppe_beschreibung || '|' || OLD.gruppe_system || '|' || OLD.gilt_bis,NEW.gruppe || '|' || NEW.gruppe_beschreibung || '|' || OLD.gruppe_system || '|' || NEW.gilt_bis,NEW.pk_vw01);
else
INSERT INTO public.tupda(aenderung_nutzer,aenderung_datum,aenderung_zeit,aenderung_tabelle,aenderung_feld,aenderung_wert_alt,aenderung_wert_neu,primary_key_wert) VALUES(current_user,now(),now(),TABELLE','gruppe|gruppe_beschreibung|gilt_bis','NEUANLAGE',NEW.gruppe || '|' || NEW.gruppe_beschreibung || '|' || NEW.gruppe_system || '|' || NEW.gilt_bis,NEW.pk_vw01);
END IF;
RETURN NEW;
END;
$BODY$
LANGUAGE plpgsql VOLATILE
COST 100;
current_user (in den Triggerfunktionen) ist ja der an der Datenbank (über den connect-String verbundene) angemeldete Nutzer - ich habe hierfür aber keinen anderen Ansatz gefunden. Die Angabe muß dem angemeldeten (Webanwendung) Nutzer entsprechen.
Danach werden die Trigger zum Aufruf der Funktion beim Eintreten der Ereignisse definiert:
-- Anlegen Trigger
CREATE TRIGGER "delete"
AFTER DELETE
ON public.TABELLE
FOR EACH ROW
EXECUTE PROCEDURE public.TABELLE_delete();
CREATE TRIGGER last_change
BEFORE INSERT OR UPDATE
ON public.TABELLE
FOR EACH ROW
EXECUTE PROCEDURE public.TABELLE_last_change();
Hat jemand eine Idee oder kann mir auch mitteilen “Das, was Du machen willst - geht so nicht!” - auch gerne dies, dann brauche ich keine Energie zu vergeuden. Aber irgendwie muß es doch machbar sein…
Einen Gedanken, den ich schon mal hatte, wäre ein Nutzer in der Datenbank, der sich durch einen Hashwert vom Namen des Nutzers eindeutig erzeugen läßt. Aber dies muß eben eindeutig sein und die Anforderungen an die Komponenten zur Bildung des Hash (Algorithmus, Länge des zu ‘hashenden’ Wertes, eventuell Domainangaben und Salt zum Nutzernamen ergänzen, …) sind mir nur oberflächlich bekannt. Mit gefährlichem Halbwissen zu agieren ist nicht mein Ding, daher müßte ich hier weitere Recherchen betreiben.
Ich bin Euch für JEDE Idee dankbar!
Gruß Rainer