Deprecated: Implicit conversion from float 1732182298.211983 to int loses precision in /hp/ao/ae/lz/www/detlefhahn/common/inc/startup_20150225.php on line 225

Deprecated: Implicit conversion from float 1732182298.212303 to int loses precision in /hp/ao/ae/lz/www/detlefhahn/common/inc/startup_20150225.php on line 798

Deprecated: Implicit conversion from float 1732182298.21234 to int loses precision in /hp/ao/ae/lz/www/detlefhahn/common/inc/startup_20150225.php on line 130

Deprecated: Implicit conversion from float 1732182298.212427 to int loses precision in /hp/ao/ae/lz/www/detlefhahn/common/inc/startup_20150225.php on line 225

Deprecated: Implicit conversion from float 1732182298.212594 to int loses precision in /hp/ao/ae/lz/www/detlefhahn/common/inc/startup_20150225.php on line 130

Deprecated: Implicit conversion from float 1732182298.212656 to int loses precision in /hp/ao/ae/lz/www/detlefhahn/common/inc/startup_20150225.php on line 130

Deprecated: Implicit conversion from float 1732182298.212887 to int loses precision in /hp/ao/ae/lz/www/detlefhahn/common/inc/startup_20150225.php on line 130

Deprecated: Implicit conversion from float 1732182298.212955 to int loses precision in /hp/ao/ae/lz/www/detlefhahn/common/inc/startup_20150225.php on line 130

Deprecated: Implicit conversion from float 1732182298.213045 to int loses precision in /hp/ao/ae/lz/www/detlefhahn/common/inc/startup_20150225.php on line 130

Deprecated: Implicit conversion from float 1732182298.213105 to int loses precision in /hp/ao/ae/lz/www/detlefhahn/common/inc/startup_20150225.php on line 130
Ethernet
CREATE DNS

DNS-Files erzeugen

Im Rahmen des inside-network Projektes der lug-gg habe ich 2006 dieses Utility geschrieben.
Voraussetzungen: Falls nicht:
        $ aptitude install bind9 dhcp3-server dialog  ncurses nslint
   
Ziel:
Alle Dateien, die für die einen DNS- / DHCP-Server erforderlich sind, werden erzeugt.
Da ein DNS kein X benötigt, werden nur Befehle der bash-Shell und Dialog eingesetzt.
Alles ist in einer Scriptdatei, damit ist keine Installation erforderlich.
Es wird ein Unterverzeichnis bind_new angelegt, in dem die Dateien erzeugt werden


Das Script wird noch erweitert um:

Clientseitig

  • installieren Sie dhcp3
               $ aptitude install dhcp3-client
         

  • Fügen Sie in /etc/network/interfaces folgende Zeilen ein
  • 	   # The primary network interface
               auto eth0
               iface eth0 inet dhcp
    

  • editeren Sie /etc/dhcp3/dhclient.conf und fügen Sie folgende Zeilen ein:
    	    send host-name "lugdh-vm01";
                request subnet-mask, broadcast-address, time-offset, routers,
                        domain-name, domain-name-servers;
    	 
  • Beim Booten sollte eine Meldung wie diese erscheinen.

                







    Download script : create_dns.tar.gz

    # ---------------------------------------------------------------------
    # Das Script erzeugt alle Dateien für einen Nameserver
    # Autor : Detlef Hahn
    # Copyright (c) 2005/2006  Detlef Hahn
    # --------------------------------------------------------------------
    # Versionlog 
    # 0.1.4  03.03.2006 Detlef Hahn   Default für Mailer
    # 0.1.3  19.01.2006 Detlef Hahn   Verschönerung 
    # 0.1.3  15.01.2006 Detlef Hahn   einfaches DHCP
    # 0.1.2  05.01.2006 Detlef Hahn   Verarbeitung .ini  CNAME 
    # 0.1.2  11.12.2005 Detlef Hahn   Korrektur der Ergänzungen (doppelter
    #                                 Eintrag DNS und Mailer) 
    # 0.1.1  10.12.2005 Helmut Kohl   Korrekturen, Ergänzungen
    # 0.1    05.12.2005 Detlef Hahn   Originalversion  
    #
    # --------------------------------------------------------------------
    
    
    # ---------------------------------------------------------------------
    # Default Variablen fuer Erzeugung der Datenfiles
    # ---------------------------------------------------------------------
     typeset -x VERSION=0.1.4
     typeset -x ETH=eth0
     typeset -x TTL=604800
     typeset -x DNSNAME="dns-xx"
     typeset -x GATEWAYNAME="rtg"
     typeset -x MAILNAME="mail-server"
     typeset -x DOMAIN=whatever
     typeset -x SERIAL=`date +%Y%m%d`01
     typeset -x REFRESH=3600
     typeset -x RETRY=600
     typeset -x EXPIRE=2419200
     typeset -x CACHENEG=604800
     typeset -x NETZ=10.64.106
     typeset -x DNSIP=253
     typeset -x IP=${NETZ}.${DNSIP}
     typeset -x NETMASK=255.255.255.0
     typeset -x BROADCAST=${NETZ}.255
     typeset -x GATEWAYIP=254
     typeset -x MAILIP=254
     typeset -x REVNETZ=106.64.10
     typeset -x LOCALHOST=localhost
     typeset -x NAMED=named.conf
     typeset -x TMPDIR="${HOME}/bind_new"
     typeset -x TARGETDIR=/etc/bind
     typeset -x DHCP=dhcpd.conf
     typeset -x DHCPZONE=${DOMAIN}
     typeset -x RANGEVON=100
     typeset -x RANGEBIS=150
     typeset -x RESOLV=resolv.conf
     typeset -x msg
     typeset -x defmail
     typeset -x DEFMAILER
    
    # ---------------------------------------------------------------------
    # Variablen fuer Dialogsteuerung 
    # teilweise doppelt dmit ein Script besser verständlich 
    # ---------------------------------------------------------------------
    : ${DIALOG=dialog}
    : ${DIALOG_OK=0}                    # Yes oder Ok
    : ${DIALOG_NO=1}                    # No oder Cancel
    : ${DIALOG_CANCEL=1}                # No oder Cancel
    : ${DIALOG_HELP=2}                  # Help
    : ${DIALOG_EXTRA=3}                 # Extrabutton
    : ${DIALOG_EXIT=3}                  # Extrabutton
    : ${DIALOG_ESC=255}                 # ESC
    if [ ! -d ${TMPDIR} ] ; then 
              mkdir ${TMPDIR}
    fi
    cd 
    
    tempfile=`tempfile 2>/dev/null` || tempfile=${TMPDIR}/test$$
    
    trap "rm -f $tempfile" 0 1 2 5 15
    trap 'print $0 [$LINENO]' ERR
    # ---------------------------------------------------------------------
    # Variablen fuer Scriptsteuerung und optische Darstellung
    # ---------------------------------------------------------------------
    CUUP=`tput cuu1`
    CLR_EOS=`tput ed`
    blue=""
    grev=""                # gruen und rev
    grey=""                # schwarz auf grau 
    norm=""
    
    # ---------------------------------------------------------
    # Funktionen muessen vor der Verwendung deklariert werden
    # ---------------------------------------------------------
    kopf() {
    
    typeset -i p
    len=${#1}                      # Laenge Parameter 1
    rev=$(tput smso)               # terminal capabilities zuweisen
    norm=$(tput rmso)       
    clr_eol=$(tput el)             # clear to end of line
    ((p=(30-l)/2+17))
    clear
    echo  ""$clr_eol "" Datum : $(date '+%d.%m.%y')$(tput cup 0 $p) $1 $(tput cup 0 62) Uhrzeit : $(date '+%H:%M')""
    echo  ""$clr_eol "" `uname -a` ""
    echo
    }
    
    # ---------------------------------------------------------
    #  Gibt Parameter aus und wartet auf Benutzer CR
    #  q  beedentet das Script
    # ---------------------------------------------------------
    cont() {
         echo -n "$1 Fortsetzung durch  "
         read dummy
         if  [ "${dummy}" = "q"  -o "${dummy}" = "Q" ]
         then
            exit 1
         fi
         echo -n "${CUUP}${CLR_EOS}"
         
    } 
    
    
    # --------------------------------------------------------
    # liest einen Wert und schreibt ihn indirekt in die Variable 
    # --------------------------------------------------------
    function get_input() {
        eval VAL=\$$1                # tricky substitution
        $DIALOG --inputbox   $1 8 40  `echo  ${VAL}` 2>  $tempfile 
        ret=$?
        newval=$(< $tempfile)
        case $ret in
           $DIALOG_OK)               # zurückschreiben in Ausgangsvariable
             eval `echo $1=$newval`  # tricky substitution   
              ;;
           $DIALOG_CANCEL)
              ;;
           $DIALOG_ESC)
              exit 1                 # Abbruch
              ;;
           *)
              ;;
         esac 
    }
    
    # -----------------------------------------------------------------------
    # Holt sich die Kenndaten des aufrufenden Benutzers    
    # -----------------------------------------------------------------------
    function show_userdata() {
         ids=`id|sed -e 's/([^)]*)//g'`
         uid=`echo "$ids" | sed -e 's/^uid=//' -e 's/ .*//'`
         gid=`echo "$ids" | sed -e 's/^.* gid=//' -e 's/ .*//'`
    
         user="$USER"
         home="$HOME"
         tempdir="$TMPDIR"
         value="\nUsername:  $USER \nUID:       $uid  \nGID:       $gid \nHOME:      $home \nTempdir:   $TMPDIR" 
         show=`echo "$value" |sed -e 's/\n/\n       /'`
    
         $DIALOG  --title "Benutzerdaten " --keep-window --no-shadow --no-collapse --cr-wrap \
                    --ok-label "Weiter" \
                    --msgbox "Benutzerdaten: \n${show} " 12 40
     }
    
    # --------------------------------------------------------------------
    # tauscht IP für Reverse-Netz
    # --------------------------------------------------------------------
    function rev_netz(){
     REVNETZ=$(echo ${NETZ} | sed -e "s/\([0-9]*\).\([0-9]*\).\([0-9]*\)/\3.\2.\1/" )
    }
    # --------------------------------------------------------------------
    # Anzeigen der Grunddaten. Diese sollen in der nächsten Version aus 
    # einer .INI gelesen werden.
    # --------------------------------------------------------------------
    
    function show_config() {
    rev_netz
    echo "  DOMAIN      = ${DOMAIN}"
    echo "  DNSNAME     = ${DNSNAME}"
    echo "  GATEWAYNAME = ${GATEWAYNAME}"
    echo "  MAILNAME    = ${MAILNAME}"
    echo "  TTL         = ${TTL}"
    echo "  SERIAL      = ${SERIAL}"
    echo "  REFRESH     = ${REFRESH}"
    echo "  RETRY       = ${RETRY}"
    echo "  EXPIRE      = ${EXPIRE}"
    echo "  CACHENEG    = ${CACHENEG}" 
    echo "  NETZ        = ${NETZ}"
    echo "  DNSIP       = ${DNSIP}"
    echo "  GATEWAYIP   = ${GATEWAYIP}"
    echo "  MAILIP      = ${MAILIP}"
    }
    
    
    # --------------------------------------------------------------------
    # Ausgabe der Grunddaten
    # --------------------------------------------------------------------
    
    
    function save_config() {
      
      echo "#!/bin/bash" > ${TMPDIR}/.bind_config.ini
      show_config | sed -e 's/ //g' >> ${TMPDIR}/.bind_config.ini
      (( max = ${#iptab[*]}  ))
      i=0
      while [ $i -lt $max ] 
      do
          echo "iptab[$i]=${iptab[i]}"  >> ${TMPDIR}/.bind_config.ini
          (( i = i + 1 )) 
      done
      chmod 755 ${TMPDIR}/.bind_config.ini
    }
    
    # -----------------------------------------------------------------
    # Die Funktion gibt alle Daten aus. Der Anwender kann einen Eintrag 
    # zur Änderung auswählen. Der  geänderte Wert wird wieder angezeigt.
    # -----------------------------------------------------------------
    
    function change_values () {
     $DIALOG --title "Configdaten" \
            --backtitle "Detlef's DNS-Builder V ${VERSION}       (c) Basic-Software-Beratungs GmbH" \
            --ok-label "ändern" \
            --cancel-label "Exit Programm" \
            --extra-button --extra-label "Weiter" \
    	--title "Auswahl Änderung" \
            --radiolist "Benutzen Sie UP/Down zur Navigation \n\
    mit der Leertaste selektieren Sie den Wert \n\n\
    welchen Wert wollen Sie ändern?" 22 61 13 \
            DOMAIN      "${DOMAIN}" off \
            DNSNAME     "${DNSNAME}" off \
            GATEWAYNAME "${GATEWAYNAME}" off \
            MAILNAME     "${MAILNAME}" off \
            TTL         "${TTL}" off \
            SERIAL      "${SERIAL}" off \
            REFRESH     "${REFRESH}" off \
            RETRY       "${REFRESH}" off \
            EXPIRE      "${EXPIRE}" off \
            CACHENEG    "${CACHENEG}" off \
            NETZ        "${NETZ}" off \
            DNSIP       "${DNSIP}" off \
            GATEWAYIP   "${GATEWAYIP}" off \
            MAILIP      "${MAILIP}" off \
       2> ${tempfile}
        retval=$?
    #        NETMASK   "${NETMASK}" off
    #        BROADCAST "${BROADCAST}" off
    #        REVNETZ   "${REVNETZ}" off 
    
        choice=$( < ${tempfile} )        # schneller als cat file
        case $retval in
          $DIALOG_OK)
             if [ -z "$choice" ] ; then
                retval=$DIALOG_EXTRA
             else 
                get_input "$choice"
             fi
             ;;
          $DIALOG_EXTRA)                 # Exit gewählt, keine weiteren Änderungen
             ;;
          $DIALOG_CANCEL)                # Abbruch
              exit 1
              ;;
          $DIALOG_ESC)
              exit 1                     # Programm abbrechen
              ;;
          *)
            echo "Unexpected return code: $retval (ok would be $DIALOG_OK)";;
        esac
         BROADCAST=${NETZ}.255           # Wenn sich das Netz ändert muss
         IP=${NETZ}.${DNSIP}             # sich auch die IP ändern
         rev_netz
    
    # DNS, GATEWAY,MAIL  wenn diese  Werte geändert wurden, muss in itab[0-2] auch
    # geändert werden
    
         iptab[0]="${DNSNAME}:${DNSIP}:${MAILNAME}:"          # DNS selbst eintragen
         iptab[1]="${GATEWAYNAME}:${GATEWAYIP}:${MAILNAME}:"  # GATEWAY  (rtg) eintragen
         if [ ${GATEWAYIP} = ${MAILIP} ] ; then               # IP gleich dann CNAME fuer 
             iptab[2]="${MAILNAME}:::${GATEWAYNAME}"          # MAIL-Server  eintragen
         else
             iptab[2]="${MAILNAME}:${MAILIP}:${MAILNAME}:"    # MAIL-Server  eintragen
         fi
         if (defmail) ; then
            DEFMAIL=$MAILNAME
         fi 
       return $retval
    }
    
    # ---------------------------------------------------------------------------
    # Der Benutzer kann auswählen ob der Defaultmailer verwendet wird,  wenn
    # er keinen Mailer explizit angibt
    # ---------------------------------------------------------------------------
    function ask_defmailer() {
    $DIALOG --title "Defaultmailer" --yesno \
        "${MAILNAME} verwenden ?" 10 40 
        defmail=$?
        case $defmail in
          $DIALOG_OK)
             DEFMAILER=${MAILNAME}
             ;;
          $DIALOG_CANCEL)
             DEFMAILER=""  
             ;;
         esac
    }
    
    # ----------------------------------------------------------------------------
    # prüft ob ein Rechner mit seinen angegebenen Daten eingetragen werden darf
    # ----------------------------------------------------------------------------
    function check_new() {
       (( max = ${#iptab[*]}  ))
       val="${1}::::"
       rechner=$( echo ${val} | cut -f1  -d: ) 
       renr=$( echo ${val}    | cut -f2  -d: )
       mx1=$( echo ${val}     | cut -f3  -d: )
       cname=$( echo ${val}   | cut -f4 -d: )   # | sed -e 's/:/ /' )
       neu="${rechner}:${renr}:${mx1}:${cname}"
       ret=0 
       msg=""
       if [ -z "${rechner}"  ] ; then
          msg="Name darf nicht leer sein  \n"
          ret=1
       else
         echo "${rechner}" | egrep -q "^[a-zA-Z][a-zA-Z0-9]*"  
         if [ "$?" != "0" ] ; then
             msg="Name enthält unzulässige Zeicen"
             ret=1
         fi
       fi
       # IP nur prüfen wenn   cname   leer
       if [ -z "${cname}" ] ; then 
        echo "${renr}" | egrep -q  '^[0-9]*$'
        if [ "$?" != "0" ] ; then
          msg=${msg}"IP enthält unzulässige Zeichen\n"
          ret=1
        fi
       fi
       # Rangecheck
       if [ "$ret" -eq "0"   -a "${DHCP}" != "" ] ; then
          if [ "$renr" -ge "${RANGEVON}" -a "${renr}" -le "${RANGEBIS}" ] ; then
             msg=${msg}" Feste IP ${renr}  im DHCP-Bereich ${RANGEVON}  bis ${RANGEBIS} nicht zulässig"
             ret=1
          fi
       fi
        
       if  [ "${2}" = "2" ] ; then     # beide erforderlich
              if [ "${#renr}" -eq "0"   -a  "${#cname}" -eq "0" ] ; then
                 msg="${msg} Rechnername und Originalname müssen beide angegeben werden"
                  ret=1
              fi 
       fi 
       # cn=0
       #  rn=0
       p=0
       while [  $p -lt $max  -a "$ret" -eq "0" ] 
        do
          tabrechner="$( echo ${iptab[p]} | cut  -f1 -d:  )"
          tabrenr="$( echo ${iptab[p]} | cut  -f2 -d: )"
          tabcname="$( echo ${iptab[p]} | cut  -f4 -d: )"
    
          if [ "${rechner}" =  "${tabrechner}" ] ; then 
              msg="Den Rechner mit dem Namen ${rechner}  gibt es bereits"
              (( ret = ret + 1 )) 
          fi
          if [ $2 = "1" ] ; then
           if [ "${renr}" =  "${tabrenr}" ] ; then 
             msg="${msg} Den Rechner ${renr} mit der IP ${tabrenr} gibt es bereits an Position $p " 
             (( ret = ret + 2 )) 
           fi
           if [ "${renr}" -gt 254 -o "${renr}" -eq 0 ] ; then
               msg="${msg} Die Rechnernummer muss > 0 und kleiner als 255 sein" 
             (( ret = ret + 4 ))
           fi
          fi 
         (( p = p + 1 ))
       done
    
       case $ret in
       0)
         iptab[max]="${neu}"
         (( max = max + 1))
          ;;
       esac  
       return $ret
    }
    
    # ------------------------------------------------------------------------------
    # zeigt alle Rechner in der Zone an und erlaubt die Neueingabe von Rechnern
    # ------------------------------------------------------------------------------
    function show_systems() {
     typeset -i p=0  mode=1 m=${1}
    
    returncode=0
    while [ $returncode != 1 ] && [ $returncode != 250 ] || [ $mode -lt  3 ]
    do
        (( n = ${#iptab[*]}  ))
         zone=""
         rm $tempfile
         p=0
         touch $tempfile
         while (( p <  n ))
         do  
             zone="${zone}${p})   ${iptab[p]} \n" 
             echo "${p})   ${iptab[p]}"  >> $tempfile 
             (( p = p + 1 ))
         done
        rechner=""
        renr=""
        if [ ${defmail} == "0" ] ; then 
             mx1=${DEFMAILER}
        else  
             mx1=""
        fi
        mx1="${MAILER:-${DEFMAILER}}"
        cname=""
    
    #--form text height width formheight [ label y x item y x fieldlen inputlen ] ...
     case $mode in
      1) 
        exec 3>&1
        value=`$DIALOG --no-shadow --keep-window --begin 1 2 --cr-wrap \
                       --title "Rechner in der Zone" \
                       --exit-label "Weiter" \
               --textbox "${tempfile}" 20 50  \
               --and-widget  --no-shadow \
                        --title "Eingabe neuer Rechner" \
                        --begin 1  53 --ok-label "Enter" \
                        --extra-button --extra-label "Weiter" \
                        --cancel-label "Exit Prog."  \
              --form "UP/Down wechselt zwischen den Feldern \n  beendet die Eingabe" \
        12 45 0 \
                "Rechnername:" 1 1 "$rechner" 1 15 20 0 \
                "IP  nnn:"     2 1 "$renr  "  2 15  5 0 \
                "MX-Mailer:"   3 1 "$mx1"     3 15 20 0 \
        2>&1 1>&3`
        returncode=$?
        if [ $returncode == $DIALOG_CANCEL ] ; then 
            exit 1
        fi
        exec 3>&-
            # ersetze Trennzeichen new-line durch :
        val=$(echo ${value} | sed ':a; /$/N; s/\n/:\t/; ta' | sed -e 's/ /:/g')  
        ;;
     2)
        exec 3>&1
        value=`$DIALOG --no-shadow --keep-window --begin 1 2 --cr-wrap \
                       --title "Rechner in der Zone" \
                       --exit-label "Weiter" \
               --textbox "${tempfile}" 20 50  \
               --and-widget  --no-shadow \
                        --title "Eingabe Zweitname" \
                        --begin 1  53 --ok-label "Enter" \
                        --extra-button --extra-label "Weiter" \
                        --cancel-label "Exit Prog."  \
              --form "Beispiel:  mail-server   Orignalname rtg\n\
    mail-server ist ein weiterer name für den in der Zone existierenden Rechner rtg" \
        12 45 0 \
                "Rechnername:" 1 1 "$rechner" 1 15 20 0 \
                "Originalname:"       2 1 "$cname"   2 15 20 0 \
        2>&1 1>&3`
        returncode=$?
        exec 3>&-
            # ersetze Trennzeichen new-line durch :
        val=$(echo ${value} | sed ':a; /$/N; s/\n/:\t/; ta' | sed -e 's/ /:::/g')  
       ;; 
     esac
        show=`echo "$val" |sed -e 's/^/       /'`
    
            case $returncode in
            3)
                 if [ $mode -eq 1 ] ; then
                    (( mode++ ))
                 else  
                    "$DIALOG" \
                    --clear \
                    --title "Last Chance" \
                    --yesno "Eingabeloop verlassen?" 6 30
                    case $? in
                    0)
                            break            # Loop verlassen
                            ;;
                    1)
                            returncode=99
                            mode=1 
                            ;;
                    esac
                 fi
                    ;;
            0)
                    check_new "${val}"  "${mode}"
                    ret=$?
                    case $ret in
                    0)
                        ;;
                    *)    # Eintrag ungültig
                          $DIALOG  --msgbox \
                            "Angaben ungültig : \n${msg}\nEs erfolgt kein Eintrag\n${show}" 10 40
                         ;;
                    esac
                   ;;
            *)
                    echo "Return code was $returncode"
                    exit
                    ;;
            esac
    done
    }
    
    # --------------------------------------------------------------------
    # DHCP Range eingeben
    # --------------------------------------------------------------------
    function dhcp_range() {
        DHCPZONE=""
        exec 3>&1
        value=`$DIALOG  --no-shadow --title "DHCP-Range" \
                        --begin 11  20 --ok-label "Enter" \
                        --cancel-label "weiter" \
              --form "Soll für den Rechner DHCP aufgesetzt werden\n
    dann geben Sie bitte die Range ein\nBitte lassen Sie einen Bereich für feste IP-Nummern frei\nUP/Down wechselt zwischen den Feldern \n  beendet die Eingabe" \
        12 50 0 \
                "Range von:"       1 1 "$RANGEVON"   1 15 5 0 \
                "Range bis:"       2 1 "$RANGEBIS"   2 15 5 0 \
        2>&1 1>&3`
        returncode=$?
        exec 3>&-
            # ersetze Trennzeichen new-line durch :
    
        val=$(echo ${value} | sed ':a; /$/N; s/\n/:\t/; ta' | sed -e 's/ /:/g')  
        case $returncode in
          $DIALOG_OK)
            RANGEVON=""
            RANGEBIS=""
            DHCPZONE=""
            if [ ":${val}" != ":" ] ; then
                 RANGEVON="$(echo ${val} | cut  -f1 -d:   )" 
                 RANGEBIS="$(echo ${val} | cut  -f2 -d: )"   
                 DHCPZONE=${DOMAIN}
            fi
          ;;
        esac
       
        if [ ":${DHCPZONE}" != ":" ] ; then
           ALLOWUPDATE=" allow-update { any; }; "    
        else
           ALLOWUPDATE=""    
    
        fi
        return $returncode
    }
    
    
    # -------------------------------------------------------------------
    # Das Menu erlaubt das Anzeigen der erzeugten Dateien
    # -------------------------------------------------------------------
    
    function menu_show_files() {
    
     retval=$DIALOG_OK
     while [ "$retval" -eq "$DIALOG_OK" ]
     do 
       $DIALOG --clear --title "Configfiles anzeigen" \
                        --extra-button --extra-label "Weiter" \
                        --cancel-label "Exit Prog."  \
            --menu "Wählen Sie die Datei aus:" 20 79 9 \
            "${DOMAIN}"  "Zonenfile (Name  IP)  " \
            "${DOMAIN}.rev" "Reverse  (IP  Name)" \
            "${LOCALHOST}" "localhost" \
            "${LOCALHOST}.rev" "localhost.rev" \
            "${NAMED}" "named.conf" \
            "${DHCP}" "dhcpd.conf" \
            "${RESOLV}" "resolv.conf" \
            "${NSLINT}" "nslint.log" \
         2> ${tempfile}
    
      retval=$?
      choice=$( <  $tempfile )
    
      case $retval in
        $DIALOG_OK)
          dialog --title "${choice}" --textbox "$TMPDIR/${choice}" 24 75
            ;;
        $DIALOG_EXTRA)
           ;;
        $DIALOG_CANCEL)
           exit 1 
           ;;
      esac
     done
    
    }
    
    
    
    # --------------------------------------------------------------------
    
    function create_db_root() {
    
    cat > $TMPDIR/db.root << "EOF"
    ; <<>> DiG 9.2.3 <<>> ns . @a.root-servers.net.
    ;; global options:  printcmd
    ;; Got answer:
    ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 18944
    ;; flags: qr aa rd; QUERY: 1, ANSWER: 13, AUTHORITY: 0, ADDITIONAL: 13
    
    ;; QUESTION SECTION:
    ;.				IN	NS
    
    ;; ANSWER SECTION:
    .			3600000	IN	NS	A.ROOT-SERVERS.NET.
    .			3600000	IN	NS	B.ROOT-SERVERS.NET.
    .			3600000	IN	NS	C.ROOT-SERVERS.NET.
    .			3600000	IN	NS	D.ROOT-SERVERS.NET.
    .			3600000	IN	NS	E.ROOT-SERVERS.NET.
    .			3600000	IN	NS	F.ROOT-SERVERS.NET.
    .			3600000	IN	NS	G.ROOT-SERVERS.NET.
    .			3600000	IN	NS	H.ROOT-SERVERS.NET.
    .			3600000	IN	NS	I.ROOT-SERVERS.NET.
    .			3600000	IN	NS	J.ROOT-SERVERS.NET.
    .			3600000	IN	NS	K.ROOT-SERVERS.NET.
    .			3600000	IN	NS	L.ROOT-SERVERS.NET.
    .			3600000	IN	NS	M.ROOT-SERVERS.NET.
    
    ;; ADDITIONAL SECTION:
    A.ROOT-SERVERS.NET.	3600000		A	198.41.0.4
    B.ROOT-SERVERS.NET.	3600000		A	192.228.79.201
    C.ROOT-SERVERS.NET.	3600000		A	192.33.4.12
    D.ROOT-SERVERS.NET.	3600000		A	128.8.10.90
    E.ROOT-SERVERS.NET.	3600000		A	192.203.230.10
    F.ROOT-SERVERS.NET.	3600000		A	192.5.5.241
    G.ROOT-SERVERS.NET.	3600000		A	192.112.36.4
    H.ROOT-SERVERS.NET.	3600000		A	128.63.2.53
    I.ROOT-SERVERS.NET.	3600000		A	192.36.148.17
    J.ROOT-SERVERS.NET.	3600000		A	192.58.128.30
    K.ROOT-SERVERS.NET.	3600000		A	193.0.14.129
    L.ROOT-SERVERS.NET.     3600000         A       198.32.64.12
    M.ROOT-SERVERS.NET.     3600000         A       202.12.27.33
    
    ;; Query time: 81 msec
    ;; SERVER: 198.41.0.4#53(a.root-servers.net.)
    ;; WHEN: Sun Feb  1 11:27:14 2004
    ;; MSG SIZE  rcvd: 436
    
    EOF
    
    }
    
    # --------------------------------------------------------------------
    # Erzeugt eine Zonendatei   Name -> IP
    # --------------------------------------------------------------------
    function create_domain() {
    cat  > $tempfile  << "EOF"
    ; /etc/{DOMAIN}
    ; erstellt mit bsb_dns_config (c) Basic-Software-Beratungs GmbH
    ;
    ; BIND Zonefile fuer das Interface {ETH}
    ;
    $TTL	{TTL}
    {DOMAIN}.  IN	SOA  {DNSNAME}.{DOMAIN}.  root.{MAILNAME}.{DOMAIN}. (
    		     {SERIAL}		; Serial
    			   {REFRESH}		; Refresh 604800 = 1 Woche
    			    {RETRY}		; Retry  600 = 10 Minuten
    			{EXPIRE}		; Expire
    			 {CACHENEG} )	; Negative Cache TTL
    ;
    		NS	{DNSNAME}.{DOMAIN}.
    		MX  10  {MAILNAME}.{DOMAIN}.   	
    
    $ORIGIN {DOMAIN}.
    
    EOF
    
    cat $tempfile | sed -e "s/{ETH}/"${ETH}"/g" \
                     -e "s/{DNSNAME}/"${DNSNAME}"/g" \
                     -e "s/{GATEWAYNAME}/"${GATEWAYNAME}"/g" \
                     -e "s/{DOMAIN}/"${DOMAIN}"/g" \
                     -e "s/{MAILNAME}/"${MAILNAME}"/g" \
                     -e "s/{TTL}/"${TTL}"/g" \
                     -e "s/{SERIAL}/"${SERIAL}"/g" \
                     -e "s/{REFRESH}/"${REFRESH}"/g" \
                     -e "s/{RETRY}/"${RETRY}"/g" \
                     -e "s/{EXPIRE}/"${EXPIRE}"/g" \
                     -e "s/{CACHENEG}/"${CACHENEG}"/g" \
                     -e "s/{NETZ}/"${NETZ}"/g" \
                     -e "s/{DNSIP}/"${DNSIP}"/g" \
                     -e "s/{GATEWAYIP}/"${GATEWAYIP}"/g" \
                     -e "s/{MAILIP}/"${MAILIP}"/g" \
          > $TMPDIR/${DOMAIN}
    
        p=0                           # feste Stationen selbst nicht mehr eintragen
        net=${#NETZ}                  # Länge Netzanteil
        (( net = net + 1))            # + plus Punkt
        while (( p <  n ))
         do  
             #echo "-${iptab[p]}-"
             host=$(echo "${iptab[p]}" | cut -f1 -d: )
             ipnr="${NETZ}."$(echo "${iptab[p]}"| cut -f2 -d: )
             cname=$(echo "${iptab[p]}" | cut -f4 -d: )
             if [ ${#host} -gt 0 ] && [ ${#ipnr} -gt ${net} ] ; then
                tmp="${host}                                ";
                rec="${tmp:0:15}    A      $ipnr"
                echo "$rec" >> $TMPDIR/${DOMAIN}
             fi
             mail=$(echo "${iptab[p]}" | cut -f3 -d: )
             if [ ${#mail} -gt 1 ] ; then
                rec="                   MX  10 ${mail}.${DOMAIN}."
                echo "$rec" >> $TMPDIR/${DOMAIN}
             fi
    
    # Hier  die Abarbeitung der CNAME-Einträge für eine Station
             if [ ${#cname} -gt 0 ] ; then 
                tmp="${host}                        ";
                rec="${tmp:0:15}    CNAME  ${cname}.${DOMAIN}."
                echo "$rec" >> $TMPDIR/${DOMAIN}
             fi
    
             echo " " >> $TMPDIR/${DOMAIN}
             (( p = p + 1 ))
         done
    }
    
    # --------------------------------------------------------------------
    #  erzeugt Zone-reverse  IP -> Name
    # --------------------------------------------------------------------
    function create_domain_rev() {
    cat  > ${tempfile}  << "EOF"
    ; /etc/{DOMAIN}.rev
    ; erstellt mit bsb_dns_config (c) Basic-Software-Beratungs GmbH
    ;
    ; BIND  fuer reverse Namensaufloesung {ETH}
    $TTL	{TTL}       ; Zeit in Sekunden
    {REVNETZ}.in-addr.arpa. IN  SOA {DNSNAME}.{DOMAIN}. root.{MAILNAME}.{DOMAIN}. (
    		     {SERIAL}		; Serial
    			   {REFRESH}		; Refresh 604800 = 1 Woche
    			    {RETRY}		; Retry  600 = 10 Minuten
    			{EXPIRE}		; Expire
    			 {CACHENEG} )	; Negative Cache TTL
    ;
                 NS       {DNSNAME}.{DOMAIN}.  ; wer ist Nameserver
    
    $ORIGIN {REVNETZ}.in-addr.arpa.
    
    
    EOF
    
    cat $tempfile | sed -e "s/{ETH}/"${ETH}"/g" \
                     -e "s/{REVNETZ}/"${REVNETZ}"/g" \
                     -e "s/{DNSNAME}/"${DNSNAME}"/g" \
                     -e "s/{GATEWAYNAME}/"${GATEWAYNAME}"/g" \
                     -e "s/{DOMAIN}/"${DOMAIN}"/g" \
                     -e "s/{MAILNAME}/"${MAILNAME}"/g" \
                     -e "s/{TTL}/"${TTL}"/g" \
                     -e "s/{SERIAL}/"${SERIAL}"/g" \
                     -e "s/{REFRESH}/"${REFRESH}"/g" \
                     -e "s/{RETRY}/"${RETRY}"/g" \
                     -e "s/{EXPIRE}/"${EXPIRE}"/g" \
                     -e "s/{CACHENEG}/"${CACHENEG}"/g" \
                     -e "s/{DNSIP}/"${DNSIP}"/g" \
                     -e "s/{GATEWAYIP}/"${GATEWAYIP}"/g" \
                     -e "s/{MAILIP}/"${MAILIP}"/g" \
          > $TMPDIR/${DOMAIN}.rev
    
    
        (( n = ${#iptab[*]}  ))
       p=0                      # feste Stationen selbst nicht mehr eintragen
        while (( p <  n ))
         do  
             host=$(echo "${iptab[p]}" | cut -f1 -d: )
             ipnr=$(echo "${iptab[p]}"| cut -f2 -d: )
             if [ ${#ipnr} -gt 0 ] ; then 
                tmp="${ipnr}                        ";
                i=0
                ok=0
    #           Nur eintragen, wenn nicht bereits vorhanden           
                while (( i < ( p - 1 ) ))
                do
                   old=$(echo "${iptab[i]}"| cut -f2 -d: )
                   if [ "${ipnr}" = "${old}" ] ; then
                      ok=1; 
                      break
                   fi
                   ((  i = i + 1 ))
                done
                if  [ $ok = 0 ] ; then
                   tmp="${ipnr}                        ";
                   rec="${tmp:0:12}          PTR    ${host}.${DOMAIN}."
                   echo "$rec" >> $TMPDIR/${DOMAIN}.rev
                fi
             fi
             echo " " >> $TMPDIR/${DOMAIN}.rev
             (( p = p + 1 ))
         done
    } 
    
    # --------------------------------------------------------------------
    #  erzeugt Zone-localhost   Name  <- IP
    # --------------------------------------------------------------------
    
    function create_localhost() {
    cat  > $TMPDIR/${LOCALHOST}  << "EOF"
    
    ; erstellt mit bsb_dns_config (c) Basic-Software-Beratungs GmbH
    ;
    ;
    ; BIND data file for local loopback interface
    ;
    $TTL	604800
    @	IN	SOA	localhost. root.localhost. (
    			      1		; Serial
    			 604800		; Refresh
    			  86400		; Retry
    			2419200		; Expire
    			 604800 )	; Negative Cache TTL
    ;
    @	  	NS	localhost.
    @	  	A	127.0.0.1
    
    EOF
    
    }
    
    
    # --------------------------------------------------------------------
    #  erzeugt Zone-localhost.rev IP ->  Name 
    # --------------------------------------------------------------------
    
    function create_localhost_rev() {
    
    cat  > $TMPDIR/${LOCALHOST}.rev  << "EOF"
    
    ; erstellt mit bsb_dns_config (c) Basic-Software-Beratungs GmbH
    ;
    ; BIND reverse data file for local loopback interface
    ;
    $TTL	604800
    @	IN	SOA	localhost. root.localhost. (
    			      1		; Serial
    			 604800		; Refresh
    			  86400		; Retry
    			2419200		; Expire
    			 604800 )	; Negative Cache TTL
    ;
    @	  	NS	localhost.
    1.0.0	  	PTR	localhost.
    
    EOF
    
    }
    
    # --------------------------------------------------------------------
    #  erzeugt named.conf 
    #  Damit eine Prüfung mit nslint vorgenommen werden kann, werden
    #  die Daten zunächst in ein temporäres Verzeichnis geschrieben.
    #  Erst nach der Prüfung werden die endgültigen Pfade gesetzt
    # --------------------------------------------------------------------
    
    function create_named_conf() {
    #if [ "$#" -eq 1 ] ; then
    #    DIR="$1"
    #else
    #    DIR="$TARGETDIR"
    #fi
    
    cat  > ${tempfile}  << EOF
    
    // erstellt mit bsb_dns_config (c) Basic-Software-Beratungs GmbH
    
    // ----------------------------------------------------------
    // named.conf
    
    options {  
            directory "/var/cache/bind" ;  
            listen-on port  53 { {NETZ}.{DNSIP}; }  ;
            listen-on-v6 { none; };
            allow-query { {NETZ}.0/24; } ;
            auth-nxdomain  no;       # conform to RFC1035
          };
    
    
    // prime the server with knowledge of the root servers
    zone "." {
    	type hint;
    	file "{DIR}/db.root";
    };
    
    
    // be authoritative for the localhost forward and reverse zones, and for
    // broadcast zones as per RFC 1912
    
    zone "{DOMAIN}" {
    	type master;
    	file "{DIR}/{DOMAIN}";
    	${ALLOWUPDATE}
    };
    
    zone "{REVNETZ}.in-addr.arpa" {
    	type master;
    	file "{DIR}/{DOMAIN}.rev";
    	${ALLOWUPDATE}
    };
    
    // be authoritative for the localhost forward and reverse zones, and for
    // broadcast zones as per RFC 1912
    
    zone "localhost" {
    	type master;
    	file "{DIR}/{LOCALHOST}";
    };
    
    zone "127.in-addr.arpa" {
    	type master;
    	file "{DIR}/{LOCALHOST}.rev";
    };
    
    EOF
    
    cat ${tempfile} | sed -e "s+{DIR}+"${TARGETDIR}"+g" \
                        -e "s/{LOCALHOST}/"${LOCALHOST}"/g" \
                        -e "s/{DOMAIN}/"${DOMAIN}"/g" \
                        -e "s/{NETZ}/"${NETZ}"/g" \
                        -e "s/{REVNETZ}/"${REVNETZ}"/g" \
                        -e "s/{DNSIP}/"${DNSIP}"/g" \
              > $TMPDIR/${NAMED}
    }
    
    # --------------------------------------------------------------------
    # create_resolv_conf
    # --------------------------------------------------------------------
    create_resolv_conf() {
    
    cat  > ${tempfile}  << EOF
    search {DOMAIN}
    nameserver {NETZ}.{DNSIP}
    EOF
    
    cat ${tempfile} | sed -e "s/{DOMAIN}/"${DOMAIN}"/g" \
                        -e "s/{NETZ}/"${NETZ}"/g" \
                        -e "s/{DNSIP}/"${DNSIP}"/g" \
              > $TMPDIR/resolv.conf
    
    }
    
    # --------------------------------------------------------------------
    # dhcpd.conf erzeugen, muß nach /etc/dhcp3 kopiert werden
    # --------------------------------------------------------------------
    function create_dhcpd_conf(){
    
    cat  > ${tempfile}  << EOF
    
    # dhcp.conf
    # erstellt mit bsb_dns_config (c) Basic-Software-Beratungs GmbH
    
    # ----------------------------------------------------------
    
    # automatischer DNS abgleich
    ddns-update-style interim;
    
    
    default-lease-time 600;
    max-lease-time 7200;
    ignore-client-updates;
    
    # Dieser Server ist Chef der Zone , deshalb wird authoritative angegeben
    authoritative;
    zone {DOMAIN} {
         primary {NETZ}.{DNSIP};
    }
    
    zone {REVNETZ}.in-addr.arpa {
         primary {NETZ}.{DNSIP};
    }
    
    subnet {NETZ}.0 netmask {NETMASK} {
      server-identifier  {NETZ}.{DNSIP};
      option routers {NETZ}.{GATEWAYIP};
      option subnet-mask {NETMASK};
      option broadcast-address {BROADCAST};
      option domain-name "{DOMAIN}";
      option domain-name-servers {NETZ}.{DNSIP}; 
      option dhcp-server-identifier {NETZ}.{DNSIP};
      range {NETZ}.{RANGEVON} {NETZ}.{RANGEBIS};
    }
    
    EOF
    
    cat ${tempfile} | sed -e "s|{DIR}|"${TARGETDIR}"|g" \
                        -e "s|{LOCALHOST}|"${LOCALHOST}"|g" \
                        -e "s|{GATEWAYIP}|"${GATEWAYIP}"|g" \
                        -e "s|{NETZ}|"${NETZ}"|g" \
                        -e "s|{REVNETZ}|"${REVNETZ}"|g" \
                        -e "s|{NETMASK}|"${NETMASK}"|g" \
                        -e "s|{BROADCAST}|"${BROADCAST}"|g" \
                        -e "s|{DNSIP}|"${DNSIP}"|g" \
                        -e "s|{DOMAIN}|"${DOMAIN}"|g" \
                        -e "s|{RANGEVON}|"${RANGEVON}"|g" \
                        -e "s|{RANGEBIS}|"${RANGEBIS}"|g" \
              > ${TMPDIR}/${DHCP}
    
    }
    # ---------------------------------------------------------------------
    
    # --------------------------------------------------------------------
    # move_files
    # --------------------------------------------------------------------
    function move_files() {
         if [  $uid -ne 0  -o $user != "root" ] ; then 
         $DIALOG  --title "Benutzerhinweis " \
                    --ok-label "Weiter" \
                    --msgbox "Sie sind kein Superuser, deshalb können die \
    Dateien nicht automatisch in die Verzeichnisse \
    verschoben werden. " 12 40
                return ;
         fi   
         $DIALOG --yesno "Sie sind Superuser! Soll bind jetzt gestoppt werden und die Dateien in die Zielverzeichnisse übertragen werden?" 0 0 
         retval=$?
         case $retval in
          $DIALOG_OK)
     
             # Eigentuemer setzen, wenn root
             if [  $uid -eq 0 ] && [ $user = "root" ] ; then
                grep  "^bind" /etc/passwd > /dev/null
                r=$?
                if [ $r -eq 0 ] ; then
                      chown bind:bind ${TMPDIR}/${DOMAIN}
                      chown bind:bind ${TMPDIR}/${DOMAIN}.rev
                      chown bind:bind ${TMPDIR}/${LOCALHOST}
                      chown bind:bind ${TMPDIR}/${LOCALHOST}.rev
                      chown root:bind ${TMPDIR}/${NAMED}
                      chown root:root ${TMPDIR}/resolv.conf
                else
                      echo "User bind existiert nicht! Bitte anlegen und chown durchführen "
                fi
                clear
                /etc/init.d/dhcp3-server stop 
                /etc/init.d/bind9 stop 
             #  Files ins Zielverzeichnis kopieren, Owner, mode  beibehalten
                cp -p ${TMPDIR}/db.root /etc/bind
                cp -p ${TMPDIR}/${DOMAIN} /etc/bind
                cp -p ${TMPDIR}/${DOMAIN}.rev /etc/bind
                cp -p ${TMPDIR}/${LOCALHOST} /etc/bind
                cp -p ${TMPDIR}/${LOCALHOST}.rev /etc/bind
                cp -p ${TMPDIR}/${NAMED} /etc/bind
                cp -p ${TMPDIR}/${DHCP} /etc/dhcp3
                cp -p ${TMPDIR}/${RESOLV} /etc/resolv.conf
                /etc/init.d/bind9 start
                /etc/init.d/dhcp3-server start
                ps ax | grep named | grep -v grep
                ps ax | grep dhcp  | grep -v grep
                cont
                echo "   <<< ***  /var/log/syslog  *** >>> "
                echo    
                tail -20 /var/log/syslog 
                cont
             fi
    
    # -----------------------------------------------------------
    
    
    
             ;;
          $DIALOG_CANCEL)                         # Abbruch
              ;;
          *)                                      # Weiter
             ;;
         esac
    }
    
    # --------------------------------------------------------------------
    #   Beginn  Hauptsteuerung
    # --------------------------------------------------------------------
    
    kopf "Detlef's DNS-Builder V ${VERSION}"
    cat << EOF
         Das Script erzeugt die Dateien die für den Betrieb einen DNS 
         erforderlich sind.
         Die Dateien werden in dem Verzeichnis ${TMPDIR} abgelegt.
         Läuft das Script mit Superuser-Privilegien, so werden auch
         die Rechte an den Dateien richtig gesetzt. 
         Das Script kann in den Menues vorzeitig abgebrochen werden.
         Die Dateien werden dann nicht geschrieben.
    
         Have fun
    
         Detlef Hahn
    
    
    EOF
    cont 
    # -------------------------------------------------------------------
    # Namen und Rechnernummer fuer alle Maschinen anfragen
    # -------------------------------------------------------------------
    declare -a iptab nametab
    typeset -x -i i=3 n=3
    iptab[0]="${DNSNAME}:${DNSIP}:${MAILNAME}:"          # DNS selbst eintragen
    iptab[1]="${GATEWAYNAME}:${GATEWAYIP}:${MAILNAME}:"  # GATEWAY  (rtg) eintragen
    if [ ${GATEWAYIP} = ${MAILIP} ] ; then               # IP gleich dann CNAME fuer 
        iptab[2]="${MAILNAME}:::${GATEWAYNAME}"          # MAIL-Server  eintragen
    else
        iptab[2]="${MAILNAME}:${MAILIP}:${MAILNAME}:"    # MAIL-Server  eintragen
    fi
    # -------------------------------------------------------------------
    show_userdata                                        # funktion aufrufen
    
    if  [ -f ${TMPDIR}/.bind_config.ini ] ; then
        . ${TMPDIR}/.bind_config.ini
        tmpdate=`date +%Y%m%d`                           # Tagesdatum erzeugen
        tmpserial=${SERIAL:0:8}                          # yyyymmdd  extrahieren
        if [ "${tmpdate}" != "${tmpserial}" ] ; then     # Tageswechsel?
            SERIAL=`date +%Y%m%d`01                      # ja, neu hochzaehlen
        else
           (( SERIAL = SERIAL + 1 ))                     # weiterzaehlen
        fi
    fi
    
    dhcp_range                         # Muss vor Eingabe der Rechnernummern erfolgen
                                       # damit Range beräcksichtigt werden kann
    # -------------------------------------------------------------------
    # Grunddaten eingeben bzw ändern 
    # -------------------------------------------------------------------
    retval="$DIALOG_OK"
    while [ "$retval" = "$DIALOG_OK" ]
    do 
         change_values                 # änderungen der Configdaten
         retval=$?
    done
     
    ask_defmailer
    show_systems "${i}"                 # Anzeigen der ersten 3 Einträge    
    
    # -------------------------------------------------------------------
    # Jetzt sollten alle Daten vorhanden sein
    # Die Ausgabedateien werden erzeugt
    # -------------------------------------------------------------------
    
    rm  ${TMPDIR}/${DOMAIN} ${TMPDIR}/${DOMAIN}.rev ${TMPDIR}/${LOCALHOST} \
        ${TMPDIR}/${LOCALHOST}.rev ${TMPDIR}/${NAMED} ${TMPDIR}/${DHCP}
    
    create_db_root
    create_domain
    create_domain_rev
      
    create_localhost
    create_localhost_rev
    create_named_conf
    create_resolv_conf
    if [ "${DHCPZONE}"  != "" ] ; then
         create_dhcpd_conf               # nur wenn DHCP gefordert
    fi
    save_config                         # .ini wegschreiben   
    
    
    # ------------------------------------------------------------
    # -----------------------------------------------------------
    # Prüfen 
    # -----------------------------------------------------------
    NSLINT=".nslint.log"
    nslint -c $TMPDIR/named.conf   2>  ${TMPDIR}/${NSLINT}
    
    menu_show_files                     # erzeugte Dateien anzeigen 
    
    move_files                          # Dateien ins Zielverzeichnis verschieben
    
    
    # aufräumen
    # -----------------------------------------------------------
    rm ${TMPDIR}/file*
    ls -la ${TMPDIR}
    
    

       Copyright © 2003 - 2024 by Detlef Hahn  http://www.detlefhahn.de       Stand  21.07.15 11:41