#!/bin/sh


#
# Installe les triggers ncessaires pour que la modification d'un RR
# ou de ses caractristiques (rr_ip, etc.) provoque la modification
# du "generer" dans la table "zone", provoquant ainsi la gnration
# des zones DNS correspondant  l'objet modifi.
#
# Historique
#   2002/05/02 : pda/jean : cration
#   2002/05/03 : pda/jean : contournement du bug "PERFORM  plusieurs lignes"
#   2004/02/11 : pda      : adaptation nouveau format de base pour ipv6
#

BASE=dns

PGPASSWORD="mot-de-passe-de-dns"
export PGPASSWORD

# droplang plgsql
createlang plpgsql $BASE

psql $BASE <<'EOF'
--DROP TRIGGER tr_modifier_ip        ON rr_ip ;
--DROP TRIGGER tr_modifier_cname     ON rr_cname ;
--DROP TRIGGER tr_modifier_mx        ON rr_mx ;
--DROP TRIGGER tr_modifier_rr	     ON rr ;
--DROP TRIGGER tr_modifier_dhcprange ON dhcprange ;
--DROP TRIGGER tr_modifier_reseau    ON reseau ;


-- note sur les PERFORM sum (...)
-- PERFORM ignore le rsultat du SELECT, mais rle lorsque le
-- SELECT renvoie plusieurs lignes. On est donc obligs de recourrir
--  une magouille infecte : mettre un "sum(...)" pour ramener l'ensemble
-- des lignes  une seule (qui sera ignore).

------------------------------------------------------------------------------
-- Fonctions auxiliaires
--
-- But : modifier le bit "generer" dans la table "zone" correspondant
--    l'objet en cours de modification (nom ou adresse IP).
------------------------------------------------------------------------------

-- appel lors de la modification d'une adresse IPv4
CREATE OR REPLACE FUNCTION gen_rev4 (INET) RETURNS INTEGER AS '
    BEGIN
	UPDATE zone_reverse4 SET generer = 1 WHERE $1 <<= selection ;
	RETURN 1 ;
    END ;
    ' LANGUAGE 'plpgsql' ;

-- appel lors de la modification d'une adresse IPv6
CREATE OR REPLACE FUNCTION gen_rev6 (INET) RETURNS INTEGER AS '
    BEGIN
	UPDATE zone_reverse6 SET generer = 1 WHERE $1 <<= selection ;
	RETURN 1 ;
    END ;
    ' LANGUAGE 'plpgsql' ;

-- ID du RR
CREATE OR REPLACE FUNCTION gen_norm_idrr (INTEGER) RETURNS INTEGER AS '
    BEGIN
	UPDATE zone_normale SET generer = 1
		WHERE selection = (
			SELECT domaine.nom
				FROM domaine, rr
				WHERE rr.idrr = $1 AND rr.iddom = domaine.iddom
			) ;
	RETURN 1 ;
    END ;
    ' LANGUAGE 'plpgsql' ;

CREATE OR REPLACE FUNCTION gen_norm_iddom (INTEGER) RETURNS INTEGER AS '
    BEGIN
	UPDATE zone_normale SET generer = 1
		WHERE selection = (
			SELECT domaine.nom
				FROM domaine
				WHERE domaine.iddom = $1
			) ;
	RETURN 1 ;
    END ;
    ' LANGUAGE 'plpgsql' ;

------------------------------------------------------------------------------
-- Fonction associe au trigger de modification des RR d'adresses IP
--
-- But : fonction appele  chaque modification de la table rr_ip
------------------------------------------------------------------------------

CREATE OR REPLACE FUNCTION modifier_ip () RETURNS trigger AS '
    BEGIN
	IF TG_OP = ''INSERT''
	THEN
	    PERFORM sum (gen_rev4 (NEW.adr)) ;
	    PERFORM sum (gen_rev6 (NEW.adr)) ;
	    PERFORM sum (gen_norm_idrr (NEW.idrr)) ;

	    UPDATE dhcp SET generer = 1
		FROM rr WHERE rr.idrr = NEW.idrr AND rr.mac IS NOT NULL ;

	    UPDATE dhcp SET generer = 1
		FROM rr WHERE rr.idrr = NEW.idrr AND rr.mac IS NOT NULL ;
	END IF ;

	IF TG_OP = ''UPDATE''
	THEN
	    PERFORM sum (gen_rev4 (NEW.adr)) ;
	    PERFORM sum (gen_rev4 (OLD.adr)) ;
	    PERFORM sum (gen_rev6 (NEW.adr)) ;
	    PERFORM sum (gen_rev6 (OLD.adr)) ;
	    PERFORM sum (gen_norm_idrr (NEW.idrr)) ;
	    PERFORM sum (gen_norm_idrr (OLD.idrr)) ;

	    UPDATE dhcp SET generer = 1
		FROM rr WHERE rr.idrr = OLD.idrr AND rr.mac IS NOT NULL ;
	    UPDATE dhcp SET generer = 1
		FROM rr WHERE rr.idrr = NEW.idrr AND rr.mac IS NOT NULL ;
	END IF ;

	IF TG_OP = ''DELETE''
	THEN
	    PERFORM sum (gen_rev4 (OLD.adr)) ;
	    PERFORM sum (gen_rev6 (OLD.adr)) ;
	    PERFORM sum (gen_norm_idrr (OLD.idrr)) ;

	    UPDATE dhcp SET generer = 1
		FROM rr WHERE rr.idrr = OLD.idrr AND rr.mac IS NOT NULL ;
	END IF ;

	RETURN NEW ;
    END ;
    ' LANGUAGE 'plpgsql' ;

CREATE TRIGGER tr_modifier_ip
    AFTER INSERT OR UPDATE OR DELETE
    ON rr_ip
    FOR EACH ROW
    EXECUTE PROCEDURE modifier_ip ()
    ;

------------------------------------------------------------------------------
-- Fonctions associes aux triggers de modification des RR MX et CNAME
--
-- But : fonction appele  chaque modification de la table rr_mx ou rr_cname
------------------------------------------------------------------------------

CREATE OR REPLACE FUNCTION modifier_mxcname () RETURNS trigger AS '
    BEGIN
	IF TG_OP = ''INSERT''
	THEN
	    PERFORM sum (gen_norm_idrr (NEW.idrr)) ;
	END IF ;

	IF TG_OP = ''UPDATE''
	THEN
	    PERFORM sum (gen_norm_idrr (NEW.idrr)) ;
	    PERFORM sum (gen_norm_idrr (OLD.idrr)) ;
	END IF ;

	IF TG_OP = ''DELETE''
	THEN
	    PERFORM sum (gen_norm_idrr (OLD.idrr)) ;
	END IF ;

	RETURN NEW ;
    END ;
    ' LANGUAGE 'plpgsql' ;


CREATE TRIGGER tr_modifier_cname
    AFTER INSERT OR UPDATE OR DELETE
    ON rr_cname
    FOR EACH ROW
    EXECUTE PROCEDURE modifier_mxcname ()
    ;

CREATE TRIGGER tr_modifier_mx
    AFTER INSERT OR UPDATE OR DELETE
    ON rr_mx
    FOR EACH ROW
    EXECUTE PROCEDURE modifier_mxcname ()
    ;

------------------------------------------------------------------------------
-- Fonction associe au trigger de modification de RR
--
-- But : fonction appele  chaque modification de la table rr
------------------------------------------------------------------------------


-- modifier le RR et les zones reverses pour toutes les adresses IP
CREATE OR REPLACE FUNCTION modifier_rr () RETURNS trigger AS '
    BEGIN
	IF TG_OP = ''INSERT''
	THEN
	    PERFORM sum (gen_norm_iddom (NEW.iddom)) ;
	    PERFORM sum (gen_rev4 (adr)) FROM rr_ip WHERE idrr = NEW.idrr ;
	    PERFORM sum (gen_rev6 (adr)) FROM rr_ip WHERE idrr = NEW.idrr ;

	    IF NEW.mac IS NOT NULL
	    THEN
		UPDATE dhcp SET generer = 1 ;
	    END IF ;
	END IF ;

	IF TG_OP = ''UPDATE''
	THEN
	    PERFORM sum (gen_norm_iddom (NEW.iddom)) ;
	    PERFORM sum (gen_rev4 (adr)) FROM rr_ip WHERE idrr = NEW.idrr ;
	    PERFORM sum (gen_rev6 (adr)) FROM rr_ip WHERE idrr = NEW.idrr ;
	    PERFORM sum (gen_norm_iddom (OLD.iddom)) ;
	    PERFORM sum (gen_rev4 (adr)) FROM rr_ip WHERE idrr = OLD.idrr ;
	    PERFORM sum (gen_rev6 (adr)) FROM rr_ip WHERE idrr = OLD.idrr ;

	    IF OLD.mac IS DISTINCT FROM NEW.mac
		OR OLD.iddhcpprofil IS DISTINCT FROM NEW.iddhcpprofil
	    THEN
		UPDATE dhcp SET generer = 1 ;
	    END IF ;
	END IF ;

	IF TG_OP = ''DELETE''
	THEN
	    PERFORM sum (gen_norm_iddom (OLD.iddom)) ;
	    PERFORM sum (gen_rev4 (adr)) FROM rr_ip WHERE idrr = OLD.idrr ;
	    PERFORM sum (gen_rev6 (adr)) FROM rr_ip WHERE idrr = OLD.idrr ;

	    IF OLD.mac IS NOT NULL
	    THEN
		UPDATE dhcp SET generer = 1 ;
	    END IF ;
	END IF ;

	RETURN NEW ;
    END ;
    ' LANGUAGE 'plpgsql' ;

CREATE TRIGGER tr_modifier_rr
    AFTER INSERT OR UPDATE OR DELETE
    ON rr
    FOR EACH ROW
    EXECUTE PROCEDURE modifier_rr ()
    ;


---------------------------------------------------------------------------
-- Fonction associe au trigger de modification de relais de messagerie
---------------------------------------------------------------------------

-- DROP TRIGGER tr_modifier_relais ON relais_dom ;

CREATE OR REPLACE FUNCTION gen_relais (INTEGER) RETURNS INTEGER AS '
    BEGIN
	UPDATE zone_normale SET generer = 1
	    WHERE selection = (SELECT nom FROM domaine WHERE iddom = $1) ;
	RETURN 1 ;
    END ;
    ' LANGUAGE 'plpgsql' ;

CREATE OR REPLACE FUNCTION modifier_relais () RETURNS trigger AS '
    BEGIN
	IF TG_OP = ''INSERT''
	THEN
	    PERFORM sum (gen_relais (NEW.iddom)) ;
	END IF ;

	IF TG_OP = ''UPDATE''
	THEN
	    PERFORM sum (gen_relais (NEW.iddom)) ;
	    PERFORM sum (gen_relais (OLD.iddom)) ;
	END IF ;

	IF TG_OP = ''DELETE''
	THEN
	    PERFORM sum (gen_relais (OLD.iddom)) ;
	END IF ;

	RETURN NEW ;
    END ;
    ' LANGUAGE 'plpgsql' ;

CREATE TRIGGER tr_modifier_relais
    AFTER INSERT OR UPDATE OR DELETE
    ON relais_dom
    FOR EACH ROW
    EXECUTE PROCEDURE modifier_relais ()
    ;


------------------------------------------------------------------------------
-- Fonction associe au trigger de modification des zones
--
-- But : fonction appele  chaque modification d'une zone
------------------------------------------------------------------------------

CREATE OR REPLACE FUNCTION modifier_zone () RETURNS TRIGGER AS '
    BEGIN
	IF NEW.prologue <> OLD.prologue
		OR NEW.rrsup <> OLD.rrsup
		OR NEW.selection <> OLD.selection
	THEN
	    NEW.generer := 1 ;
	END IF ;
	RETURN NEW ;
    END ;
    ' LANGUAGE 'plpgsql' ;

CREATE TRIGGER tr_modifier_zone
    BEFORE UPDATE
    ON zone_normale
    FOR EACH ROW
    EXECUTE PROCEDURE modifier_zone ()
    ;

CREATE TRIGGER tr_modifier_zone
    BEFORE UPDATE
    ON zone_reverse4
    FOR EACH ROW
    EXECUTE PROCEDURE modifier_zone ()
    ;

CREATE TRIGGER tr_modifier_zone
    BEFORE UPDATE
    ON zone_reverse6
    FOR EACH ROW
    EXECUTE PROCEDURE modifier_zone ()
    ;

------------------------------------------------------------------------------
-- Fonction associe au trigger de gnration DHCP
--
-- But : fonction appele  chaque modification d'un rseau, d'un
-- intervalle DHCP, ou d'un profil DHCP
------------------------------------------------------------------------------

CREATE OR REPLACE FUNCTION generer_dhcp () RETURNS TRIGGER AS '
    BEGIN
	UPDATE dhcp SET generer = 1 ;
	RETURN NEW ;
    END ;
    ' LANGUAGE 'plpgsql' ;

CREATE TRIGGER tr_modifier_dhcprange
    BEFORE UPDATE
    ON dhcprange
    FOR EACH ROW
    EXECUTE PROCEDURE generer_dhcp ()
    ;

CREATE TRIGGER tr_modifier_reseau
    BEFORE UPDATE
    ON reseau
    FOR EACH ROW
    EXECUTE PROCEDURE generer_dhcp ()
    ;

CREATE TRIGGER tr_modifier_dhcpprofil
    BEFORE UPDATE
    ON dhcpprofil
    FOR EACH ROW
    EXECUTE PROCEDURE generer_dhcp ()
    ;

------------------------------------------------------------------------------
-- Fonction de vrification des droits sur une adresse IP par un correspondant
--
-- But : teste la validit des droits pour le correspondant ou le groupe
------------------------------------------------------------------------------

-- DROP FUNCTION valide_ip () ;

-- premier argument : adresse  tester
-- deuxime argument : id du correspondant

CREATE OR REPLACE FUNCTION valide_ip_cor (INET, INTEGER) RETURNS BOOLEAN AS '
    BEGIN
	RETURN valide_ip_grp ($1, idgrp) FROM corresp WHERE idcor = $2 ;
    END ;
' LANGUAGE 'plpgsql' ;

-- premier argument : adresse  tester
-- deuxime argument : id du groupe
CREATE OR REPLACE FUNCTION valide_ip_grp (INET, INTEGER) RETURNS BOOLEAN AS '
    BEGIN
	RETURN ($1 <<= ANY (SELECT adr FROM dr_ip
				WHERE allow_deny = 1 AND idgrp = $2)
	    AND NOT $1 <<= ANY (SELECT adr FROM dr_ip
				WHERE allow_deny = 0 AND idgrp = $2)
	    ) ;
    END ;
' LANGUAGE 'plpgsql' ;

EOF
