#!/usr/bin/perl 
# $Id$
# This script (sophomorix-setup-pgldap) is maintained by Rüdiger Beck
# It is Free Software (License GPLv3)
# If you find errors, contact the author
# jeffbeck@web.de  or  jeffbeck@gmx.de



# This Script adds directories and files that are necessary for sophomorix-base 
# It should be run as postinst
use strict;
use DBI;
use Getopt::Long;
Getopt::Long::Configure ("bundling");

use Sophomorix::SophomorixConfig; 
use Sophomorix::SophomorixBase; 
use Net::LDAP;
use Sophomorix::SophomorixPgLdap qw(
                                    check_connections
                                    db_connect
                                    db_disconnect
                                    get_smb_sid
                                    create_class_db_entry
                                    fetch_ldap_pg_passwords
                                    dump_slapd_to_ldif
                                    add_slapd_from_ldif
                                    patch_ldif
                                   );

my @arguments = @ARGV;

my $replace="";

$Conf::log_level=1;

my $domainname="";
my $servername="";

# comment TLS entries in slapd.conf
my $tls_comment="# ";
if (-e $DevelConf::slapd_pem_file){
    # do not comment TLS entries in slapd.conf
    # use them with $DevelConf::slapd_pem_file 
    $tls_comment="";
}

my $smbworkgroup="";
my $internip="";
my $ipcopip="";
my $internmask="";
my $imaging="";
my $sid="";
my $smbserverstring="";
my $dbname="";
my $ldappw="";
my $dbpw="";

my $info=0;
my $help=0;
my $testports=0;
my $slapd_standalone=1;
my $slapd_integrated=0;

my $new_database=0;
my $keep_database=0;
my $config_file=0;

my $create_indices_only=0;
my $drop_indices_only=0;
my $update_indices=0;

my $old_version="";
my $new_version="";
my @upgrade_sql_id=();
my $upgrade_sql_id_number=0;
my %upgrade_sql_id_filename=();

my @upgrade_scripts_id=();
my $upgrade_scripts_id_number=0;
my %upgrade_scripts_id_filename=();

my $ldappassword = "";
my $dbpassword = "";
my $ldap_explanation="";
my $db_explanation="";

# 2 means: option not given
my $linuxmuster=2;
# configuring everything or not
my $full_config=0;


my $timestamp=&zeit_stempel();


# Parsen der Optionen
my $testopt=GetOptions(
           "verbose|v+" => \$Conf::log_level,
           "help|h" => \$help,
           "info|i" => \$info,
           "testports" => \$testports,
           "configfile" => \$config_file,
           "oldversion=s" => \$old_version,
           "newversion=s" => \$new_version,
           "ldappw|ldappassword=s" => \$ldappw,
           "dbpw|dbpassword=s" => \$dbpw,
           "new-database" => \$new_database,
           "linuxmuster!" => \$linuxmuster,
           "keep-database" => \$keep_database,
           "create-indices-only" => \$create_indices_only,
           "drop-indices-only" => \$drop_indices_only,
           "update-indices-only" => \$update_indices,
           "slapd-standalone" => \$slapd_standalone,
           "slapd-integrated" => \$slapd_integrated,
          );


# Prüfen, ob Optionen erkannt wurden
&check_options($testopt);


if ($testports==1){
    &get_pg_server_version("5432");
    &get_pg_server_version("5433");
    exit;
}

if (not -e "/usr/sbin/linuxmuster-setup"){
    $full_config=1;
}

if ($linuxmuster==1){
    $full_config=0;
} elsif ($linuxmuster==0){
    $full_config=1;
}


############################################################
# --help
############################################################
if ($help==1) {
   # Scriptname ermitteln
   my @list = split(/\//,$0);
   my $scriptname = pop @list;
   # Befehlbeschreibung
   print "\n$scriptname configures sophomorix, postgresql, slapd and samba \n";
   print('
Options
  -h  / --help
  -i  / --info      show values used for configuration, do nothing

Configure the whole system or assume an linuxmuster.net system is decided 
automatically by the existence of /usr/sbin/linuxmuster-setup. 
To manually override this behaviour use:
   --linuxmuster
   --nolinuxmuster
   
Check which version of postgres is running on ports 5432 and 5433
   --testports

What settings to use:
  --configfile      use values from /etc/sophomorix/pgldap/pgldap.conf

Use a standalone ldap (this is the default)
  --slapd-standalone

Use a integrated ldap (this must be specified)
  --slapd-integrated

How to handle the database
  Version numbers are correctly set when using the debian package system
  --oldversion debian-version-number 
  --newversion debian-version-number

  These Options are for debugging (or when you are crazy!)
  --new-database    deletes the database and creates a new one (Dangerous!!)
  --keep-database   do not drop the database, keep it unmodified

What passwords to use:
  --ldappw string   use string as ldap rootdn password 
      Standard password is:
         - if given in /etc/ldap/slapd.conf :reuse old password
         - else: generate a random 10 digit number as password
  --dbpw string   use string as ldap database password 
      Standard password is:
         - if given in /etc/ldap/slapd.conf :reuse old password
         - else: generate a random 10 digit number as password

Update indices only:
indices are update automatically if you do not specify one of the following options

  --create-indices-only 
      This is for testing only

  --drop-indices-only 
      This is for testing only

  --update-indices-only 
      Drop indices listed in drop-index.sql and create indices in 
      create-index.sql.
      Use this, when you edit the above files  files and you want to check 
      performance gain (or loss).
      This is for testing only
');
   print "\n";
   exit;
}



&log_script_start(@arguments);


############################################################
# manage indices
############################################################


# --update-indices
if ($update_indices==1) {
    $create_indices_only=1;
    $drop_indices_only=1;
}

# --drop-indices
if ($drop_indices_only==1) {
    &drop_indices();
    # exit, 
    if ($create_indices_only==0){
        &log_script_exit("",1,1,0,@arguments);
    }
}

# --create-indices
if ($create_indices_only==1) {
    &create_indices();
    &log_script_exit("",1,1,0,@arguments);
}



############################################################
# manage passwords
############################################################

# fetch old passwords
my ($old_ldappw,$old_rootdn,$old_dbpw,$old_mail_dom)=&fetch_ldap_pg_passwords();

# ldap password
if ($ldappw ne ""){
    # use password given as option
    $ldappassword = $ldappw;
    $ldap_explanation="Password from Option";
} elsif ($old_ldappw ne "") {
    # reuse old password 
    $ldappassword = $old_ldappw;
    $ldap_explanation="reuse old password";
} else {
    # generate random password
    $ldappassword = int( rand(99999999999999999999)) + 99999999999999999999;
    $ldap_explanation="new random password";
}

# db password
if ($dbpw ne ""){
    # use password given as option
    $dbpassword = $dbpw;
    $db_explanation="Password from Option";
} elsif ($old_dbpw ne "") {
    # reuse old password 
    $dbpassword = $old_dbpw;
    $db_explanation="reuse old password";
} else {
    # generate random password
    $dbpassword = int( rand(99999999999999999999)) + 99999999999999999999;
    $db_explanation="new random password";
}




############################################################
# standalone ldap or integrated
############################################################

# standard is standalone
if ($slapd_integrated==1){
    $slapd_standalone=0;
    print "Configuring integrated ldap\n";
} else {
    print "Configuring standalone ldap\n";
}

print "Using the following values to configure the system\n";
print "   Full configuration                   : $full_config\n";

############################################################
# Debian Version
############################################################
my $deb_version = &get_debian_version();
my $lsb_release_codename = &get_lsb_release_codename();
print "   Debian Version                       : $deb_version\n";
print "   Codename                             : $lsb_release_codename\n";

############################################################
# read the values from the config file
############################################################
my $config_file="/etc/sophomorix/pgldap/pgldap.conf";
if (-e $config_file) { 
   { package PgLdapConf ; do "$config_file"}
   $domainname=$PgLdapConf::domainname;
   $servername=$PgLdapConf::servername;
   $smbworkgroup=$PgLdapConf::smbworkgroup;
   $smbserverstring=$PgLdapConf::smbserverstring;
   $internip=$PgLdapConf::internip;
   $ipcopip=$PgLdapConf::ipcopip;
   $internmask=$PgLdapConf::internmask;
   $imaging=$PgLdapConf::imaging;
   $dbname=$PgLdapConf::dbname;
}

############################################################
# get debconf data, one by one
############################################################

if ($config_file==0){

# domainname
#------------------------------------------------------------
my $domainname_debconf=
    &get_debconf_value("linuxmuster-base", "domainname",0);


# exit if debconf database is locked
# i.e. when dpkg-reconfigure sophomorix-pgldap is called
if (not defined $domainname_debconf){
    print STDERR "\nPackage sophomorix-pgldap cannot be configured\n";
    print STDERR "because the debconf database was locked\n\n";
    print STDERR "Try the command sophomorix-setup-pgldap.\n\n";
    &log_script_exit("Debconf locked",1,1,0,@arguments);
}


# process debconf data
if ($domainname_debconf ne 0){
    # from debconf
    $domainname=$domainname_debconf;    
    print "   Domainname from debconf              : $domainname \n";
} else {
    # from config file
    print "   Domainname from pgldap.conf          : $domainname \n";
}

# servername
#------------------------------------------------------------
my $servername_debconf=
    &get_debconf_value("linuxmuster-base", "servername",0);
# process debconf data
if ($servername_debconf ne 0){
    # from debconf
    $servername=$servername_debconf;    
    print "   Servername from debconf              : $servername \n";
} else {
    # from config file
    print "   Servername from pgldap.conf          : $servername \n";
}


# workgroup from samba
#------------------------------------------------------------
my $smbworkgroup_debconf=
    &get_debconf_value("linuxmuster-base", "workgroup",0);
# process debconf data
if ($smbworkgroup_debconf ne 0){
    # from debconf
    $smbworkgroup=$smbworkgroup_debconf;    
    print "   Workgroup from debconf               : $smbworkgroup \n";
} else {
    # from config file
    print "   Workgroup from pgldap.conf           : $smbworkgroup \n";
}

# internal ip
#------------------------------------------------------------
my $internsubrange_debconf=
    &get_debconf_value("linuxmuster-base", "internsubrange",0);
# process debconf data
if ($internsubrange_debconf ne 0){
    # from debconf
    my ($min,$max)=split(/-/,$internsubrange_debconf);    
    $internip="10.".$min.".1.1";    
    $ipcopip="10.".$min.".1.254";
    print "   Internal IP from debconf             : $internip \n";
    print "   Ipcop IP from Internal IP            : $ipcopip \n";
} else {
    # from config file
    print "   Internal IP from pgldap.conf         : $internip \n";
    print "   Ipcop IP from pgldap.conf            : $ipcopip \n";
}


# internal netmask
#------------------------------------------------------------
my $internmask_debconf=
    &get_debconf_value("linuxmuster-base", "internmask",0);
# process debconf data
if ($internmask_debconf ne 0){
    # from debconf
    $internmask=$internmask_debconf;    
    print "   Internal netmask from debconf        : $internmask \n";
} else {
    # from config file
    print "   Internal netmask from pgldap.conf    : $internmask \n";
}


# imaging system (rembo|linbo|tivoli)
#------------------------------------------------------------
my $imaging_debconf=
    &get_debconf_value("linuxmuster-base", "imaging",0);
# process debconf data
if ($imaging_debconf ne 0){
    # from debconf
    $imaging=$imaging_debconf;    
    print "   Imaging System from debconf          : $imaging \n";
} else {
    # from config file
    print "   Imaging System from pgldap.conf      : $imaging \n";
}


} # end $config_file==0


printf "   ldappassword %23s : ********** \n","($ldap_explanation)";
printf "   dbpassword   %23s : ********** \n","($db_explanation)";


# sid 
# use debconf (if existing), else net getlocalsid
$sid=&get_smb_sid();


# institutes
#------------------------------------------------------------
my (@institutes)= split(/\./,$domainname);
# take away the last
pop @institutes;

my $institutes = join "." , @institutes;
print "   String for institutes(ldap) :   $institutes \n";


if ($old_version eq "" or not defined $old_version ){
    # ask dpkg for old Version
    my $line=`dpkg -l sophomorix-pgldap | grep 'sophomorix-pg'`;
    chomp($line);
    my ($status,$name,$version,$desc)=split(/\s+/,$line);
    $old_version=$version;
#    # make sure to run all upgrads
#    $old_version="0.0.0-0";
}

if ($new_version eq "" or not defined $new_version ){
    # ask dpkg for new Version
    my $line=`dpkg -l sophomorix-pgldap | grep 'sophomorix-pg'`;
    chomp($line);
    my ($status,$name,$version,$desc)=split(/\s+/,$line);
    $new_version=$version;
}

print "Package Versions:\n";
print "   Old Debian Package Version  :   $old_version \n";
print "   New Debian Package Version  :   $new_version \n";


# reading list of db upgrade *.sql files
my @all_db_upgrades=();
opendir(UPGRADE, ${DevelConf::sql_upgrade_path}) or 
     die "can't opendir ${DevelConf::sql_upgrade_path}: $!";
while (defined(my $filename = readdir(UPGRADE))) {
    # do something with "$dirname/$file"
    if ($filename=~m/.sql$/){
       #print "$filename \n";
       push @all_db_upgrades, $filename;

    }
}
closedir(UPGRADE);


@all_db_upgrades = sort @all_db_upgrades;

print "\nChecking upgrade SQL-files (not ordered):\n";
foreach my $file (@all_db_upgrades){
    my $version="";
    # extract Version from filename
    if ($file=~m/sophomorix_(.*).sql/){
        $version=$1;
    }
    my @old = split(/[\.-]/,$old_version);
    my @new = split(/[\.-]/,$new_version);
    my @file = split(/[\.-]/,$version);

    # calculating number
    my $file_number=$file[3]
                   +$file[2]*1000
                   +$file[1]*1000*1000
                   +$file[0]*1000*1000*1000;
    my $old_number=$old[3]
                  +$old[2]*1000
                  +$old[1]*1000*1000
                  +$old[0]*1000*1000*1000;
    my $new_number=$new[3]
                  +$new[2]*1000
                  +$new[1]*1000*1000
                  +$new[0]*1000*1000*1000;

    #           - To old
    #  old ...  - To old
    #           + Run
    #           + Run 
    #  new ...  + Run
    #           - To new
    #           - To new

    if ($file_number > $old_number and $file_number <= $new_number){
        print "      ***Run $file as upgrade\n";
        push @upgrade_sql_id, $file_number;
        $upgrade_sql_id_filename{$file_number}=$file;        
    } elsif ($file_number <= $old_number){
        print "      File $file is to old\n";
    } elsif ($file_number > $new_number){
        print "      File $file is to new\n";
    }
}


# sorting the id numbers
@upgrade_sql_id= sort {$a <=> $b} @upgrade_sql_id;
$upgrade_sql_id_number=$#upgrade_sql_id+1;
print "SQL-files to load into database in correct order: \n";
foreach my $file_id (@upgrade_sql_id){
    printf "   %14s   %-40s \n",$file_id, $upgrade_sql_id_filename{$file_id};
}
print "  --> $upgrade_sql_id_number SQL-files will be loaded into database\n\n";


# reading list of scripts upgrade files
my @all_script_upgrades=();
opendir(SUPGRADE, ${DevelConf::upgrade_path_script}) or 
    die "can't opendir ${DevelConf::upgrade_path_script}: $!";
while (defined(my $filename = readdir(SUPGRADE))) {
    # do something with "$dirname/$file"
    if ($filename=~m/.upgrade$/){
       #print "$filename \n";
       push @all_script_upgrades, $filename;

    }
}
closedir(SUPGRADE);


@all_script_upgrades = sort @all_script_upgrades;

print "Checking upgrade script files (not ordered):\n";
foreach my $file (@all_script_upgrades){
    my $version="";
    # extract Version from filename
    if ($file=~m/sophomorix_(.*).upgrade/){
        $version=$1;
    }
    my @old = split(/[\.-]/,$old_version);
    my @new = split(/[\.-]/,$new_version);
    my @file = split(/[\.-]/,$version);

    # calculating number
    my $file_number=$file[3]
                   +$file[2]*1000
                   +$file[1]*1000*1000
                   +$file[0]*1000*1000*1000;
    my $old_number=$old[3]
                  +$old[2]*1000
                  +$old[1]*1000*1000
                  +$old[0]*1000*1000*1000;
    my $new_number=$new[3]
                  +$new[2]*1000
                  +$new[1]*1000*1000
                  +$new[0]*1000*1000*1000;

    #           - To old
    #  old ...  - To old
    #           + Run
    #           + Run 
    #  new ...  + Run
    #           - To new
    #           - To new

    if ($file_number > $old_number and $file_number <= $new_number){
        print "      ***Run $file as upgrade\n";
        push @upgrade_scripts_id, $file_number;
        $upgrade_scripts_id_filename{$file_number}=$file;        
    } elsif ($file_number <= $old_number){
        print "      File $file is to old\n";
    } elsif ($file_number > $new_number){
        print "      File $file is to new\n";
    }
}


# sorting the id numbers
@upgrade_scripts_id= sort {$a <=> $b} @upgrade_scripts_id;
$upgrade_scripts_id_number=$#upgrade_scripts_id+1;
print "Scripts to run for upgrade in correct order: \n";
foreach my $file_id (@upgrade_scripts_id){
    printf "   %14s   %-40s \n",$file_id, $upgrade_scripts_id_filename{$file_id};
}
print "  --> $upgrade_scripts_id_number scripts will be run\n\n";


if ($info==1){
    # show values only
    &log_script_exit("",1,1,0,@arguments);
}



############################################################
# upgrade the postgres database on dist upgrade
############################################################

# which postgres is running
&get_pg_server_version("5432");
# &get_pg_server_version("5433");

# repair.directories einlesen
my %permissions=&get_alle_verzeichnis_rechte();


############################################################
# Replace the following config-files
############################################################
# path to the template-files
my $template=${DevelConf::config_template_pfad};

# ldap
my $ldap_args_dir="/var/run/slapd";
my $ldap_conf="/etc/ldap/ldap.conf";
my $slapd_conf=$DevelConf::slapd_conf;
my $slapd_conf_custom="/etc/ldap/slapd.conf.custom";
my $slapd_d="/etc/ldap/slapd.d";
my $slapd_d_bak="/etc/ldap/slapd.d_backup";
my $default_slapd="/etc/default/slapd";
my $smbldap_conf="/etc/smbldap-tools/smbldap.conf";
my $ldap_secret="/etc/ldap.secret";
my $nsswitch_conf="/etc/nsswitch.conf";
my $libnssldap_conf="/etc/libnss-ldap.conf";
my $smb_ldap_conf="/etc/smbldap-tools/smbldap.conf";
my $smb_ldap_bind_conf="/etc/smbldap-tools/smbldap_bind.conf";
my $ldif_local="/usr/share/sophomorix/config-templates/ldap/local-gen.ldif";

# pg
my $odbc_ini="/etc/odbc.ini";
my $odbcinst_ini="/etc/odbcinst.ini";
my $sophomorix_db=${DevelConf::sql_create_path}."sophomorix.sql";

# pam
my $common_account="/etc/pam.d/common-account";
my $common_auth="/etc/pam.d/common-auth";
my $common_password="/etc/pam.d/common-password";
my $common_session="/etc/pam.d/common-session";
my $pam_ldap_conf="/etc/pam_ldap.conf";

# samba
# use linuxmuster-base if existing
my $smb_conf_template=${template}."/samba/smb.conf.template.".$imaging;

# path to imaging dependant smb.conf template
my $linuxmuster_base_smb_conf_imaging=
     $DevelConf::linuxmuster_base_smb_conf.".".$imaging;
if (-e $linuxmuster_base_smb_conf_imaging){
     $smb_conf_template=$linuxmuster_base_smb_conf_imaging;
}

my $smb_netlogon_bat=${DevelConf::devel_netlogon_path}."/logon.bat";
if (-e "$DevelConf::linuxmuster_base_logon_bat"){
    $smb_netlogon_bat=${DevelConf::linuxmuster_base_logon_bat};
}

my $smb_netlogin_bat=${DevelConf::devel_netlogon_path}."/login.bat";
if (-e "$DevelConf::linuxmuster_base_login_bat"){
    $smb_netlogin_bat=${DevelConf::linuxmuster_base_login_bat};
}

# bdb
my $db_config="/var/lib/ldap/DB_CONFIG";


############################################################
# message
############################################################
my $message1="Do not change this file! It will be overwritten!";
my $message2="This configuration file was automatically".
             " created by sophomorix-setup-pgldap";
my $message3="Last Modification: $timestamp";


############################################################
# basedn, dc
############################################################
my ($basedn,$dc)=&basedn_from_domainname($domainname);

############################################################
# SMB server string
############################################################
print "   Samba Server String         :   $smbserverstring \n";

############################################################
# Database
############################################################
print "   Database name               :   $dbname \n";

    # the great replacement string
    $replace= " -e 's/\@\@basedn\@\@/${basedn}/g'". 
              " -e 's/\@\@dc\@\@/${dc}/g'".
              " -e 's/\@\@servername\@\@/${servername}/g'". 
              " -e 's/\@\@internip\@\@/${internip}/g'". 
              " -e 's/\@\@ipcopip\@\@/${ipcopip}/g'". 
              " -e 's/\@\@serverip\@\@/${internip}/g'". 
              " -e 's/\@\@internmask\@\@/${internmask}/g'". 
              " -e 's/\@\@sid\@\@/${sid}/g'". 
              " -e 's/\@\@workgroup\@\@/${smbworkgroup}/g'". 
              " -e 's/\@\@smbserverstring\@\@/${smbserverstring}/g'". 
              " -e 's/\@\@ldappassword\@\@/${ldappassword}/g'". 
              " -e 's/\@\@dbpassword\@\@/${dbpassword}/g'". 
              " -e 's/\@\@dbname\@\@/${dbname}/g'". 
              " -e 's/\@\@teachersgroup\@\@/${DevelConf::teacher}/g'". 
              " -e 's/\@\@administrator\@\@/${DevelConf::smb_administrator}/g'". 
              " -e 's/\@\@domadmin\@\@/${DevelConf::smb_domadmin}/g'". 
              " -e 's/\@\@domadmins\@\@/${DevelConf::smb_domadmin_group}/g'". 
              " -e 's/\@\@tls_comment\@\@/${tls_comment}/g'". 
              " -e 's/\@\@message1\@\@/${message1}/g'". 
              " -e 's/\@\@message2\@\@/${message2}/g'".
              " -e 's/\@\@message3\@\@/${message3}/g'"; 


# Always create the local ldif file
print "Creating $ldif_local\n";
system("sed $replace ${template}/ldap/standalone.ldif.template > $ldif_local"); 

if ($full_config==1){
    if ($lsb_release_codename eq "oneiric"){
        &install_conf("/usr/share/sophomorix/config-templates/ldap",
                      "oneiric",
                      "15_ldap");     
    } else {
        # do it, ldap.conf
        print "Creating $ldap_conf\n";
        system("sed $replace ${template}/ldap/ldap.conf.template > $ldap_conf");
        # do it, slapd.conf
        print "Creating $slapd_conf\n";
        if ($slapd_standalone==1){
           system("sed $replace ${template}/ldap/slapd-standalone.conf.template > $slapd_conf");
        } else { 
           system("sed $replace ${template}/ldap/slapd.conf.template > $slapd_conf");
        } 

        # do it, slapd
        print "Creating $default_slapd\n";
        system("sed $replace ${template}/ldap/slapd.template > $default_slapd");
        print "Creating $smbldap_conf\n";
        system("sed $replace ${template}/ldap/smbldap.conf.template > $smbldap_conf"); 
        print "Creating $ldap_secret\n";
        system("sed $replace ${template}/ldap/ldap.secret.template > $ldap_secret"); 
        print "Creating $nsswitch_conf\n";
        system("sed $replace ${template}/ldap/nsswitch.conf.template > $nsswitch_conf");
        print "Creating $libnssldap_conf\n";
        system("sed $replace ${template}/ldap/libnss-ldap.conf.template > $libnssldap_conf");
    }

    # make sure a dummy custom template is there, so that 
    # slapd starts
    if (not -e $DevelConf::slapd_custom_file){
        print "Creating $DevelConf::slapd_custom_file\n";
        system("cp $DevelConf::slapd_custom_template $DevelConf::slapd_custom_file");
    }

    # activate slapd.conf in ubuntu 8.10 or later see wiki.ubuntuusers.de/OpenLDAP
    if ($lsb_release_codename eq "lenny"){
        # debian lenny
        system("rm -rf $slapd_d_bak");
        system("mv $slapd_d $slapd_d_bak");
        system("mkdir $slapd_d ");
        system("slaptest -f $slapd_conf -F $slapd_d ");
        system("chown -R openldap:openldap $slapd_d ");
        system("chmod 0640 /etc/ldap/slapd.conf");
        system("chown .openldap /etc/ldap/slapd.conf");
        system("chmod 0640 /etc/ldap/slapd.conf.custom");
        system("chown .openldap /etc/ldap/slapd.conf.custom");
    } elsif ($lsb_release_codename eq "squeeze"){
        # debian squeeze
        system("rm -rf $slapd_d_bak");
        system("mv $slapd_d $slapd_d_bak");
        system("mkdir $slapd_d ");
        system("slaptest -f $slapd_conf -F $slapd_d ");
        system("chown -R openldap:openldap $slapd_d ");
        system("chmod 0640 /etc/ldap/slapd.conf");
        system("chown .openldap /etc/ldap/slapd.conf");
        system("chmod 0640 /etc/ldap/slapd.conf.custom");
        system("chown .openldap /etc/ldap/slapd.conf.custom");
    } elsif ($lsb_release_codename eq "oneiric"){
        # ubuntu oneiric
        system("rm -rf $slapd_d_bak");
        system("mv $slapd_d $slapd_d_bak");
        system("mkdir $slapd_d ");
        system("slaptest -f $slapd_conf -F $slapd_d ");
        system("chown -R openldap:openldap $slapd_d ");
        system("chmod 0640 /etc/ldap/slapd.conf");
        system("chown .openldap /etc/ldap/slapd.conf");
        system("chmod 0640 /etc/ldap/slapd.conf.custom");
        system("chown .openldap /etc/ldap/slapd.conf.custom");
    } elsif ($lsb_release_codename eq "precise"){
        # ubuntu precise
        system("rm -rf $slapd_d_bak");
        system("mv $slapd_d $slapd_d_bak");
        system("mkdir $slapd_d ");
        system("slaptest -f $slapd_conf -F $slapd_d ");
        system("chown -R openldap:openldap $slapd_d ");
        system("chmod 0640 /etc/ldap/slapd.conf");
        system("chown .openldap /etc/ldap/slapd.conf");
        system("chmod 0640 /etc/ldap/slapd.conf.custom");
        system("chown .openldap /etc/ldap/slapd.conf.custom");
    }



    # do it, pg
    print "Creating $odbc_ini\n";
    system("sed $replace ${template}/pg/odbc.ini.template > $odbc_ini"); 
    print "Creating $odbcinst_ini\n";
    system("sed $replace ${template}/pg/odbcinst.ini.template > $odbcinst_ini");
} # end full_config


    # pg_hba.conf
    my $seen_postgres=0;
    my $seen_local_ldap=0;
    my $seen_host_ldap=0;
    my @line=();

    my $postgres_conf_dir="";
    my $psql="";

if ($lsb_release_codename eq "lenny"){
    # debian lenny
    $postgres_conf_dir="/etc/postgresql/8.3/main";
    $psql="/usr/lib/postgresql/8.3/bin/psql";
} elsif ($lsb_release_codename eq "squeeze"){
    # debian squeeze ?????????????????????
    $postgres_conf_dir="/etc/postgresql/8.3/main";
    $psql="/usr/lib/postgresql/8.3/bin/psql";
} elsif ($lsb_release_codename eq "oneiric"){
    # ubuntu oneiric
    $postgres_conf_dir="/etc/postgresql/9.1/main";
    $psql="sudo -u postgres /usr/lib/postgresql/9.1/bin/psql";
} elsif ($lsb_release_codename eq "precise"){
    # ubuntu precise
    $postgres_conf_dir="/etc/postgresql/9.1/main";
    $psql="sudo -u postgres /usr/lib/postgresql/9.1/bin/psql";
} else {
    &log_script_exit("Debian Version $deb_version ($lsb_release_codename) ",
                     "is not supported",
                     1,1,0,@arguments);
}


if ($full_config==1){
    # Debian Version dependant
    my $pg_hba_conf = $postgres_conf_dir."/pg_hba.conf";
    my $file_ident = $postgres_conf_dir."/pg_ident.conf";
    my $file_ident_tmp = $postgres_conf_dir."/pg_ident.conf.tmp";
    print "Working on pg_hba.conf\n";

    if ($lsb_release_codename eq "lenny"){
        &insert_line_before("local;all;postgres;ident;postgres",
                            "local;all;postgres;ident;sameuser",
                            "$pg_hba_conf");
        &insert_line_before("local;all;ldap;ident;ldap",
                            "local;all;postgres;ident;sameuser",
                            "$pg_hba_conf");
        &insert_line_before("local;template1;ldap;password;",
                            "local;all;all;ident;sameuser",
                            "$pg_hba_conf");
        &insert_line_before("local;ldap;ldap;password;",
                            "local;all;all;ident;sameuser",
                            "$pg_hba_conf");
        &insert_line_before("host;template1;ldap;127.0.0.1;255.255.255.255;password",
                            "host;all;all;127.0.0.1;255.255.255.255;ident;sameuser",
                            "$pg_hba_conf");
        &insert_line_before("host;ldap;ldap;127.0.0.1;255.255.255.255;password",
                            "host;all;all;127.0.0.1;255.255.255.255;ident;sameuser",
                           "$pg_hba_conf");
    } elsif ($lsb_release_codename eq "squeeze"){
        &insert_line_before("local;all;postgres;ident;postgres",
                            "local;all;postgres;ident;sameuser",
                            "$pg_hba_conf");
        &insert_line_before("local;all;ldap;ident;ldap",
                            "local;all;postgres;ident;sameuser",
                            "$pg_hba_conf");
        &insert_line_before("local;template1;ldap;password;",
                            "local;all;all;ident;sameuser",
                            "$pg_hba_conf");
        &insert_line_before("local;ldap;ldap;password;",
                            "local;all;all;ident;sameuser",
                            "$pg_hba_conf");
        &insert_line_before("host;template1;ldap;127.0.0.1;255.255.255.255;password",
                            "host;all;all;127.0.0.1;255.255.255.255;ident;sameuser",
                            "$pg_hba_conf");
        &insert_line_before("host;ldap;ldap;127.0.0.1;255.255.255.255;password",
                            "host;all;all;127.0.0.1;255.255.255.255;ident;sameuser",
                           "$pg_hba_conf");
    } elsif ($lsb_release_codename eq "oneiric"){
        &insert_line_before("local;ldap;ldap;ident;map=ldap",
                            "local;all;all;peer;",
                            "$pg_hba_conf");
        &insert_line_before("local;ldap;postgres;ident;map=postgres",
                            "local;all;postgres;peer;",
                            "$pg_hba_conf");
        &insert_line_before("local;template1;postgres;ident;map=postgres",
                            "local;all;postgres;peer;",
                            "$pg_hba_conf");
    } elsif ($lsb_release_codename eq "precise"){
        &insert_line_before("local;all;all;peer;",
                            "local;ldap;ldap;ident;map=ldap",
                            "$pg_hba_conf");
        &insert_line_before("local;ldap;postgres;ident;map=postgres",
                            "local;all;postgres;peer;",
                            "$pg_hba_conf");
        &insert_line_before("local;template1;ldap;ident;map=ldap",
                            "local;all;postgres;peer;",
                            "$pg_hba_conf");
    }

    # pg_ident.conf
    my $seen_ident_postgres=0;
    my $seen_ident_postgres_pg=0;
    my $seen_ident_ldap=0;
    open(IDENT, "<$file_ident") || die "Fehler: $!";
    open(IDENTMP, ">$file_ident_tmp") || die "Fehler: $!";
    while (<IDENT>) {
        chomp(); # Returnzeichen abschneiden
        if ($_ eq ""){next;} # Wenn Zeile Leer, dann aussteigen
        #if(/^\#/){next;} # Bei Kommentarzeichen aussteigen
        my (@line) = split(/\s+/);
        if ($line[0] eq "postgres" and
           $line[1] eq "root" and
           $line[2] eq "postgres") {
           $seen_ident_postgres=1;
           print "   Line is in $file_ident already ...  doing nothing.\n";
        }
        if ($line[0] eq "postgres" and
           $line[1] eq "postgres" and
           $line[2] eq "postgres") {
           $seen_ident_postgres_pg=1;
           print "   Line is in $file_ident already ...  doing nothing.\n";
        }
        if ($line[0] eq "ldap" and
           $line[1] eq "root" and
           $line[2] eq "ldap") {
           $seen_ident_ldap=1;
           print "   Line is in $file_ident already ...  doing nothing.\n";
        }
        print IDENTMP $_,"\n";
    }

    if ($seen_ident_postgres==0){
        print IDENTMP "postgres       root       postgres\n";
    }

    if ($seen_ident_postgres_pg==0){
        print IDENTMP "postgres       postgres   postgres\n";
    }

    if ($seen_ident_ldap==0){
        print IDENTMP "ldap           root       ldap\n";
    }


    close(IDENT);
    close(IDENTMP);
    # updating pg_ident_conf
    system("mv $file_ident_tmp $file_ident");

    # what to do:
    # 3x basedn
    # 1x sid
    # ... 

    # do it, pam
    system("sed $replace ${template}/pam/common-account.template > $common_account"); 
    system("sed $replace ${template}/pam/common-auth.template > $common_auth"); 
    system("sed $replace ${template}/pam/common-password.template > $common_password"); 
    system("sed $replace ${template}/pam/common-session.template > $common_session"); 
    system("sed $replace ${template}/pam/pam_ldap.conf.template > $pam_ldap_conf"); 

    # do it, samba
    # samba part 1
    &setup_verzeichnis("\$homedir_samba","$DevelConf::homedir_samba");
    system("sed $replace ${smb_conf_template} > ${DevelConf::smb_conf}"); 

    if (not -e "$DevelConf::smb_conf_global_sys"){
        system("cp $DevelConf::smb_conf_global $DevelConf::smb_conf_global_sys");
        system("chmod 644 $DevelConf::smb_conf_global_sys");
    }

    # do it, bdb
    if ($slapd_standalone==1){
        system("sed $replace ${template}/bdb/slapd-standalone.DB_CONFIG > $db_config");
        system("chown openldap.openldap $db_config"); 
    } else { 
        system("sed $replace ${template}/bdb/DB_CONFIG > $db_config"); 
        system("chown openldap.openldap $db_config"); 
    } 


    # Set password in /var/lib/samba/secrets.tdb
    system("smbpasswd -w $ldappassword");


    ############################################################
    # restarting services 
    ############################################################

    # stop samba
    if ($lsb_release_codename eq "lenny"){
        system("/etc/init.d/samba stop");
    } elsif ($lsb_release_codename eq "squeeze"){
        system("/etc/init.d/samba stop");
    } elsif ($lsb_release_codename eq "oneiric"){
        system("/usr/sbin/service smbd stop");
    } elsif ($lsb_release_codename eq "precise"){
        system("/usr/sbin/service smbd stop");
    }
    sleep 2;
    system("killall smbd");
    system("killall nmbd");


    # stop ldap
    if ($lsb_release_codename eq "lenny"){
        system("/etc/init.d/slapd stop");
    } elsif ($lsb_release_codename eq "squeeze"){
        system("/etc/init.d/slapd stop");
    } elsif ($lsb_release_codename eq "oneiric"){
        system("/usr/sbin/service slapd stop");
    } elsif ($lsb_release_codename eq "precise"){
        system("/usr/sbin/service slapd stop");
    }
    sleep 2;
    system("killall slapd");


    # stop postgres
    if ($lsb_release_codename eq "lenny"){
        system("/etc/init.d/postgresql-8.3 stop");
    } elsif ($lsb_release_codename eq "squeeze"){
        system("/etc/init.d/postgresql-8.4 stop");
    } elsif ($lsb_release_codename eq "oneiric"){
        system("/usr/sbin/service postgresql stop");
    } elsif ($lsb_release_codename eq "precise"){
        system("/usr/sbin/service postgresql stop");
    }
    sleep 5;
    system("killall postmaster");


    # starting postgres
    if ($lsb_release_codename eq "lenny"){
        system("/etc/init.d/postgresql-8.3 start");
    } elsif ($lsb_release_codename eq "squeeze"){
        system("/etc/init.d/postgresql-8.4 start");
    } elsif ($lsb_release_codename eq "oneiric"){
        system("/usr/sbin/service postgresql start");
    } elsif ($lsb_release_codename eq "precise"){
        system("/usr/sbin/service postgresql start");
    }
    sleep 5;


    # check if the following throws no error when already running
    # check on sarge without dist-upgrade
    # remove that ?????
    if (-e "/etc/init.d/postgresql-8.3"){
        system("/etc/init.d/postgresql-8.3 start");
    }

    # Drop old database, when --new-database
    if ($new_database==1 and $linuxmuster==0){
        print "\nWARNING: I will drop your database ldap in 5 seconds!\n";
        print "\n Hit Control-C to abort, ...!\n\n";
        sleep 5;

        if ($lsb_release_codename eq "lenny"){
            system("droplang -p ${DevelConf::sql_port} -U postgres plpgsql ldap");
            system("dropdb -p ${DevelConf::sql_port} -U postgres ldap");
            system("dropuser -p ${DevelConf::sql_port} -U postgres ldap");
        } elsif ($lsb_release_codename eq "squeeze"){
            system("droplang -p ${DevelConf::sql_port} -U postgres plpgsql ldap");
            system("dropdb -p ${DevelConf::sql_port} -U postgres ldap");
            system("dropuser -p ${DevelConf::sql_port} -U postgres ldap");
        } elsif ($lsb_release_codename eq "oneiric"){
            system("sudo -u postgres droplang -p ${DevelConf::sql_port} -U postgres plpgsql ldap");
            system("sudo -u postgres dropdb -p ${DevelConf::sql_port} -U postgres ldap");
            system("sudo -u postgres dropuser -p ${DevelConf::sql_port} -U postgres ldap");
        } elsif ($lsb_release_codename eq "precise"){
            system("sudo -u postgres droplang -p ${DevelConf::sql_port} -U postgres plpgsql ldap");
            system("sudo -u postgres dropdb -p ${DevelConf::sql_port} -U postgres ldap");
            system("sudo -u postgres dropuser -p ${DevelConf::sql_port} -U postgres ldap");
        }
        sleep 2;
    } else {
        print "\nNOT dropping the database\n";
        print "To drop the database use option --nolinuxmuster\n\n";
        sleep 5;
    }
} # end full_config


##################################################
# create new database if necessary
##################################################
# trying to connect (check if database ldap exists on 5432)
my $dbh = DBI->connect("dbi:Pg:dbname=ldap;port=${DevelConf::sql_port}", 
                       "ldap","pass",
          { RaiseError => 0, PrintError => 0});

if ( ($old_version eq "0.0.0-0" and not defined $dbh) or 
     ($new_database==1 and $linuxmuster==0) ){
    # first installation
    print "\ncreating the postgresql database ldap \n\n";
    &create_database();
} else {
    print "\nNOT creating empty postgresql database ",
          "ldap from scratch (update)\n\n";
}


# ???????????? muss drin sein, postgres muss dazu laufen
##################################################
# upgrade database structure if necessary
##################################################
if ($keep_database==1){
    print "\nNOT running upgrades on postgresql database ldap (option given)\n\n";
} else {
    &upgrade_database();
}



if ($full_config==1){
    # create new indices
    if ($lsb_release_codename eq "lenny"){
        &drop_indices();
    } elsif ($lsb_release_codename eq "squeeze"){
        &drop_indices();
    } elsif ($lsb_release_codename eq "oneiric"){
        # do nothing
    } elsif ($lsb_release_codename eq "precise"){
        # do nothing
    }

    # disabled from 2.2.15 on
    # &create_indices();
    # setting the password in pg
    if ( ($old_version eq "0.0.0-0" and not defined $dbh) or 
          ($new_database==1 and $linuxmuster==0) ){
        # first installation
        &set_db_passwd($dbpassword);
    } else {
        &titel("NOT updating password  for user ldap in Postgresql (update)");
    }

    # setting the ldap suffix dn=x in pg
    &set_ldap_suffix_pg($basedn);

    # setting institutes
    #&set_ldap_institutes($institutes);

    # setting the SID for existing users/groups
    # ???????
    #&set_samba_sid();

    # changes for the new version of slapd 2.3.27/etch that runs as openldap
    system("chmod 0644 $ldap_conf");
    if ($lsb_release_codename eq "lenny"){
        # debian lenny
        system("chmod 0640 $slapd_conf");
        system("chmod 0640 $slapd_conf_custom");
    } elsif ($lsb_release_codename eq "squeeze"){
        # debian squeeze ?????
        #system("chmod 0640 $slapd_conf");
        #system("chmod 0640 $slapd_conf_custom");
    } elsif ($lsb_release_codename eq "oneiric"){
        # ubuntu oneiric
        #system("chmod 0640 $slapd_conf");
        #system("chmod 0640 $slapd_conf_custom");
    } elsif ($lsb_release_codename eq "precise"){
        # ubuntu precise
        #system("chmod 0640 $slapd_conf");
        #system("chmod 0640 $slapd_conf_custom");
    }

    #system("chown openldap:openldap $ldap_conf");
    system("chown root:root $ldap_conf");
    # the args dir/file
    if (not -e "$ldap_args_dir"){
        system("mkdir $ldap_args_dir");
    }
    system("chmod 0755 $ldap_args_dir");
    system("chown openldap:openldap $ldap_args_dir");


    if ($slapd_standalone==1){
        # dump the current ldap
        &dump_slapd_to_ldif();

        # remove bdb files from slapd
        system("rm -rf /var/lib/ldap/*");

        # start and stop slapd to recreate files in /var/lib/ldap
        if ($lsb_release_codename eq "lenny"){
            system("/etc/init.d/slapd start");
            system("/etc/init.d/slapd stop");
        } elsif ($lsb_release_codename eq "squeeze"){
            system("/etc/init.d/slapd start");
            system("/etc/init.d/slapd stop");
        } elsif ($lsb_release_codename eq "oneiric"){
            system("/usr/sbin/service slapd start");
            system("/usr/sbin/service slapd stop");
        } elsif ($lsb_release_codename eq "precise"){
            system("/usr/sbin/service slapd start");
            system("/usr/sbin/service slapd stop");
        }

        # slapd must be stopped again
        # populate ldap (no users)
        print "Populating ldap with $ldif_local\n";
        print "This can take a while ...\n";
        if (not -e ${DevelConf::log_pfad_package_update}){
            system("mkdir -p ${DevelConf::log_pfad_pack_up}");
        }
        system("slapadd -c -l $ldif_local > ${DevelConf::log_pfad_pack_up}/slapadd-previous.log 2>&1");

        if ($new_database==1 and $linuxmuster==0){
            # new database doesnt need to be filled
        } else {
            # use the old database
            # modify the basedn and other stuff in the latest dump
            &patch_ldif($basedn,$smbworkgroup);
            # add the latest dump, if existing
            &add_slapd_from_ldif();
        }
    }

    sleep 5;

    ## make sure owner is correct, so that slapd can start
    system("chown -R openldap.openldap /var/lib/ldap/");
    if ($lsb_release_codename eq "lenny"){
        # debian lenny
        system("chmod 700 /var/lib/ldap");
        system("chmod 600 /var/lib/ldap/*");
    } elsif ($lsb_release_codename eq "squeeze"){
        # debian squeeze
        system("chmod 700 /var/lib/ldap");
        system("chmod 600 /var/lib/ldap/*");
    } elsif ($lsb_release_codename eq "oneiric"){
        # ubuntu oneiric
        system("chmod 700 /var/lib/ldap");
        system("chmod 600 /var/lib/ldap/*");
    } elsif ($lsb_release_codename eq "precise"){
        # ubuntu pecise
        system("chmod 700 /var/lib/ldap");
        system("chmod 600 /var/lib/ldap/*");
    }

    # starting ldap
    if ($lsb_release_codename eq "lenny"){
        system("/etc/init.d/slapd start");
    } elsif ($lsb_release_codename eq "squeeze"){
        system("/etc/init.d/slapd start");
    } elsif ($lsb_release_codename eq "oneiric"){
        system("/usr/sbin/service slapd start");
    } elsif ($lsb_release_codename eq "precise"){
        system("/usr/sbin/service slapd start");
    }

    sleep 2;

    # patch smbtools
    system("sed $replace ${template}/ldap/smbldap.conf.template > $smb_ldap_conf"); 
    system("sed $replace ${template}/ldap/smbldap_bind.conf.template > $smb_ldap_bind_conf"); 


    # starting samba
    if ($lsb_release_codename eq "lenny"){
        system("/etc/init.d/samba start");
    } elsif ($lsb_release_codename eq "squeeze"){
        system("/etc/init.d/samba start");
    } elsif ($lsb_release_codename eq "oneiric"){
        system("/usr/sbin/service smbd start");
    } elsif ($lsb_release_codename eq "precise"){
        system("/usr/sbin/service smbd start");
    }

    # ssh restart
    if ($lsb_release_codename eq "lenny"){
        system("/etc/init.d/ssh restart");
    } elsif ($lsb_release_codename eq "squeeze"){
        system("/etc/init.d/ssh restart");
    } elsif ($lsb_release_codename eq "oneiric"){
        system("/usr/sbin/service ssh restart");
    } elsif ($lsb_release_codename eq "precise"){
        system("/usr/sbin/service ssh restart");
    }

    # nscd restart
    if ($lsb_release_codename eq "lenny"){
       system("/etc/init.d/nscd stop");
       sleep 2;
       system("killall nscd");
       sleep 2;
       system("killall -9 nscd");
       system("/etc/init.d/nscd start");
    } elsif ($lsb_release_codename eq "squeeze"){
       system("/etc/init.d/nscd stop");
       sleep 2;
       system("killall nscd");
       sleep 2;
       system("killall -9 nscd");
       system("/etc/init.d/nscd start");
    } elsif ($lsb_release_codename eq "oneiric"){
       system("/usr/sbin/service nscd stop");
       sleep 2;
       system("killall nscd");
       sleep 2;
       system("killall -9 nscd");
       system("/usr/sbin/service nscd start");
    } elsif ($lsb_release_codename eq "precise"){
       system("/usr/sbin/service nscd stop");
       sleep 2;
       system("killall nscd");
       sleep 2;
       system("killall -9 nscd");
       system("/usr/sbin/service nscd start");
    }


    if ($slapd_standalone==1){
        # domain groups
        system("sophomorix-groupadd --skiplock --unix-group domadmins --nt-group 'Domain Admins' --domain --gidnumber 512");
        system("sophomorix-groupadd --skiplock --unix-group domusers --nt-group 'Domain Users' --domain --gidnumber 513");
        system("sophomorix-groupadd --skiplock --unix-group domguests --nt-group 'Domain Guests' --domain --gidnumber 514");
        system("sophomorix-groupadd --skiplock --unix-group domcomputers --nt-group 'Domain Computers' --domain --gidnumber 515");
        system("sophomorix-groupadd --skiplock --unix-group wwwadmin --nt-group 'Web Administrators' --domain --gidnumber 997");

        # local groups 
        system("sophomorix-groupadd --skiplock --unix-group printoperators --nt-group 'Print Operators' --local --gidnumber 550");
        #    system("sophomorix-groupadd --skiplock --unix-group wwwadmin --nt-group 'Web Administrators' --local --gidnumber 997");
        system("sophomorix-groupadd --skiplock --unix-group replicators --nt-group 'Replicators' --local --gidnumber 552");
        system("sophomorix-groupadd --skiplock --unix-group administrators --nt-group 'Administrators' --local --gidnumber 544");
        system("sophomorix-groupadd --skiplock --unix-group accountoperators --nt-group 'Account Operators' --local --gidnumber 548");
        system("sophomorix-groupadd --skiplock --unix-group backupoperators --nt-group 'Backup Operators' --local --gidnumber 551");

        # correct the groups-sids
        &update_groupsid("domadmins","512",$sid);
        &update_groupsid("domusers","513",$sid);
        &update_groupsid("domguests","514",$sid);
        &update_groupsid("domcomputers","515",$sid);

        &update_groupsid("administrators","544");
        &update_groupsid("accountoperators","548");
        &update_groupsid("printoperators","550");
        &update_groupsid("backupoperators","551");
        &update_groupsid("replicators","552");

        # delete groupmapping
        &delete_groupmap("Web Administrators");
    } else { 
        # adding groups with smbldap-tools
        &add_ldap_group("domadmins","Domain Admins",512);
        &add_ldap_group("domusers","Domain Users",513);
        &add_ldap_group("domguests","Domain Guests",514);
        &add_ldap_group("domcomputers","Domain Computers",515);
        # local groups
        &add_local_ldap_group("printoperators","Print Operators",550);
        #&add_local_ldap_group("pgmadmins","Program Administrators",999);
        &add_local_ldap_group("wwwadmin","Web Administrators",997);
        &add_local_ldap_group("replicators","Replicators",552);
        &add_local_ldap_group("administrators","Administrators",544);
        &add_local_ldap_group("accountoperators","Account Operators",548);
        &add_local_ldap_group("backupoperators","Backup Operators",551);
    }


    # group teachers part 1
    my $dbh_create_class_db_entry = 
             DBI->connect("dbi:Pg:dbname=ldap;port=${DevelConf::sql_port}", 
                          "ldap","",
               { RaiseError => 0, PrintError => 0});
    if (not defined $dbh_create_class_db_entry){
        print "   WARNING: Could not create class ${DevelConf::teacher}.\n";
        print "   Database ldap not running on port ${DevelConf::sql_port}\n";
    } else {
        &create_class_db_entry(${DevelConf::teacher},4);
    }
} # end full_setup

# adding users

# checking for admins 0: exists/ 1 nonexisting
my $admins_nonexisting=system("id administrator > /dev/null 2>&1");
if ($admins_nonexisting!=0){
    print "WARNING: Skipping chown commands because of nonexisting administrator\n";
}
if ($admins_nonexisting==0){
    &setup_verzeichnis("\$homedir_all_admins","$DevelConf::homedir_all_admins");
} 

if ($full_config==1){
    # grouplist for administrator
    my $grouplist="administrators,printoperators,${DevelConf::teacher}";

    if ($slapd_standalone==1){
        # administrator is equal to admin in ml 2.x
        system("sophomorix-useradd --skiplock --administrator administrator --uidnumber 998 --gecos administrator --unix-group 'domadmins' --secondary-groups '$grouplist' --shell /bin/bash");

        # pgmadmin is to install programs on the win clients
        system("sophomorix-useradd --skiplock --administrator pgmadmin --uidnumber 999 --gecos 'Programm Administrator' --unix-group 'domadmins' --shell /bin/false");

#    # wwwadmin for web services (moodle, opengroupware, imp ...) NOT a windows user
#    system("sophomorix-useradd --skiplock --unixadmin wwwadmin --uidnumber 997 --gecos 'Web Administrator' --unix-group 'administrators' --shell /bin/false");

    # wwwadmin for web services (moodle, opengroupware, imp ...) NOT a windows user
        system("sophomorix-useradd --skiplock --administrator wwwadmin --uidnumber 997 --gecos 'Web Administrator' --unix-group 'administrators' --shell /bin/false");



        # domadmin (for joining the domain)
        system("sophomorix-useradd --skiplock --administrator domadmin --uidnumber 996 --gecos 'Domain Admin' --unix-group 'domadmins' --shell /bin/false --home /dev/null");

        # correct the sids
        &update_sid("administrator","998","512",$sid);
        &update_sid("domadmin","996","512",$sid);
        &update_sid("pgmadmin","999","512",$sid);
        &update_sid("wwwadmin","997","544",$sid);
    } else { 
        # administrator is equal to admin in ml 2.x
        system("smbldap-useradd -u 998 -a -c administrator -m -d /home/administrators/administrator -g 'domadmins' -G '$grouplist' -s /bin/bash administrator");

        # pgmadmin is to install programs on the win clients
        system("smbldap-useradd -u 999 -a  -c 'Programm Administrator' -m -d /home/administrators/pgmadmin -g 'domadmins' -s /bin/false pgmadmin");

        # wwwadmin for web services (moodle, opengroupware, imp ...) NOT a windows user
        system("smbldap-useradd -u 997 -c 'Web Administrator' -m -d /home/administrators/wwwadmin -g 'wwwadmin' -s /bin/false wwwadmin");

        # domadmin (for joining the domain)
        system("smbldap-useradd -a -u 996 -c 'Domain Admin' -m -d /dev/null -g 'domadmins' -s /bin/false domadmin");
    }


    # updating ldap
    if ($new_database==1 and $linuxmuster==0){
        system("sophomorix-dump-pg2ldap --skiplock");
        # make sure slapd is running for the following chown commands
        sleep 5;
    }           
} # end full_setup

if ($admins_nonexisting==0){
    &setup_verzeichnis("\$share_share","$DevelConf::share_share");
}
# todo /etc/rc2.d samba auf 21 erhöhen

# Adding directories
# First Parameter: search for "$homedir_teacher" in repair.directories an do NOT
#    expand to the variable $homedir_teacher (i.e. dont forget the leading \)
# Second Parameter: Expand to the contents of $homedir_teacher wich is defined in
#    sophomorix-devel.conf 
if ($admins_nonexisting==0){
   &setup_verzeichnis("\$homedir_teacher","$DevelConf::homedir_teacher");
   &setup_verzeichnis("\$homedir_pupil","$DevelConf::homedir_pupil");
   &setup_verzeichnis("\$homedir_ws","$DevelConf::homedir_ws");
}

# share

if ($admins_nonexisting==0){
    &setup_verzeichnis("\$share_exams","$DevelConf::share_exams");
    &setup_verzeichnis("\$share_classes","$DevelConf::share_classes");
    &setup_verzeichnis("\$share_subclasses","$DevelConf::share_subclasses");
    &setup_verzeichnis("\$share_projects","$DevelConf::share_projects");
    &setup_verzeichnis("\$share_school","$DevelConf::share_school");
}
# tasks

if ($admins_nonexisting==0){
    &setup_verzeichnis("\$tasks_tasks","$DevelConf::tasks_tasks");
    &setup_verzeichnis("\$tasks_classes","$DevelConf::tasks_classes");
    &setup_verzeichnis("\$tasks_rooms","$DevelConf::tasks_rooms");
    &setup_verzeichnis("\$tasks_subclasses","$DevelConf::tasks_subclasses");
    &setup_verzeichnis("\$tasks_projects","$DevelConf::tasks_projects");
    &setup_verzeichnis("\$tasks_teachers","$DevelConf::tasks_teachers");
}
# samba part 2
if ($admins_nonexisting==0){
    &setup_verzeichnis("\$homedir_samba_netlogon",
                       "$DevelConf::homedir_samba_netlogon");
    &setup_verzeichnis("\$homedir_samba_progs",
                       "$DevelConf::homedir_samba_progs");
    &setup_verzeichnis("\$homedir_samba_cds",
                       "$DevelConf::homedir_samba_cds");
}

if ($full_config==1){
    #print "${template}/samba/netlogon/logon.bat.template > $smb_netlogon_bat \n";
    #print "${template}/samba/netlogon/login.bat.template > $smb_netlogin_bat \n";
    system("sed $replace ${template}/samba/netlogon/logon.bat.template > $smb_netlogon_bat"); 
    system("sed $replace ${template}/samba/netlogon/login.bat.template > $smb_netlogin_bat"); 
} # end full_config

# www stuff
if ($DevelConf::create_www==1){
   &setup_verzeichnis("/var/www","/var/www");
   &setup_verzeichnis("\$www_people","$DevelConf::www_people");
   &setup_verzeichnis("\$www_students","$DevelConf::www_students");
   &setup_verzeichnis("\$www_classes","$DevelConf::www_classes");
   &setup_verzeichnis("\$www_projects","$DevelConf::www_projects");
}

# make important data readable by root only
&setup_verzeichnis("\$var_lib_pfad","$DevelConf::var_lib_pfad");
&setup_verzeichnis("\$log_files","$DevelConf::var_lib_pfad");

# group teachers part 2
if ($admins_nonexisting==0){
    &provide_class_files(${DevelConf::teacher});
}
    
if ($full_config==1){
    # make some files owned by root.root and 0600
    &make_some_files_root_only();
    # undo some of the above changes 
    if ($lsb_release_codename eq "lenny"){
        system("chmod 0640 /etc/ldap/slapd.conf");
        system("chown .openldap /etc/ldap/slapd.conf");
        system("chmod 0640 /etc/ldap/slapd.conf.custom");
        system("chown .openldap /etc/ldap/slapd.conf.custom");
    } elsif ($lsb_release_codename eq "squeeze"){
        system("chmod 0640 /etc/ldap/slapd.conf");
        system("chown .openldap /etc/ldap/slapd.conf");
        system("chmod 0640 /etc/ldap/slapd.conf.custom");
        system("chown .openldap /etc/ldap/slapd.conf.custom");
    } elsif ($lsb_release_codename eq "oneiric"){
        system("chmod 0640 /etc/ldap/slapd.conf");
        system("chown .openldap /etc/ldap/slapd.conf");
        system("chmod 0640 /etc/ldap/slapd.conf.custom");
        system("chown .openldap /etc/ldap/slapd.conf.custom");
    } elsif ($lsb_release_codename eq "precise"){
        system("chmod 0640 /etc/ldap/slapd.conf");
        system("chown .openldap /etc/ldap/slapd.conf");
        system("chmod 0640 /etc/ldap/slapd.conf.custom");
        system("chown .openldap /etc/ldap/slapd.conf.custom");
    }
}

# run upgrade scripts
&run_upgrade_scripts();

&log_script_end(@arguments);




############################################################
# sub
############################################################

sub install_conf {
    # use conf templates from linuxmuster-base
    # pre: path to codename
    # codename: codename
    # path to insttation files in codename
    my ($pre,$codename,$post) = @_;
    my $dir=$pre."/".$codename."/".$post;
    my @files=();
    print "installing from $dir\n";

    opendir DIR, $dir or die "Cannot open $dir: $!";
    foreach my $file (readdir DIR) {
        if ($file eq "." or $file eq ".."){
	    next;
        }
        if ($file=~/target$/){
	    next;
        }
        push @files, $file;
    }
    @files = sort @files;
    foreach my $file (@files){
        my $abs_file=$dir."/".$file;
        print "Working on $abs_file:\n";
        my $abs_target = $abs_file.".target";
	if (-e $abs_target){
            my $target = `cat $abs_target`;
            chomp($target);
            print "   * Patching $abs_file\n       to \n     $target\n";
            my $sed_command = "sed $replace $abs_file > $target";
            print "$sed_command\n";
            system($sed_command);
        } else {
            print "   * No file $abs_target\n       for \n     $abs_file\n";
        }
    }
    closedir DIR;
}



sub update_sid {
    # update the sambasid and sambagroupsid of a user (pg and ldap)
    my ($user,$smb_sid,$smb_groupsid,$sid) = @_;
    if (not defined $sid){
        return;
    }
    $smb_sid=$sid."-".$smb_sid;
    $smb_groupsid=$sid."-".$smb_groupsid;
    print "Updating samba account $user:\n";
    print "   * sid:     $smb_sid\n";
    print "   * grp-sid: $smb_groupsid\n";

    my $dbh = DBI->connect("dbi:Pg:dbname=ldap;port=${DevelConf::sql_port}", 
                           "ldap","",
               { RaiseError => 0, PrintError => 0});
    if (not defined $dbh){
        print "   WARNING: Could not update samba account $user.\n";
        print "   Database ldap not running on port ${DevelConf::sql_port}\n";
	return 0;
    }

    my $dbh=&db_connect();
    my $sql="UPDATE samba_sam_account
             SET sambasid='$smb_sid',
                 sambaprimarygroupsid='$smb_groupsid'
             WHERE id=(SELECT id from userdata where uid='$user')";
    #print "\nSQL: $sql\n";
    $dbh->do($sql);
    &db_disconnect($dbh);
    # update ldap
    system("/usr/bin/pdbedit -r -U $smb_sid -G $smb_groupsid $user > /dev/null");
}



sub update_groupsid {
    my ($group,$smb_groupsid,$sid) = @_;
    if (not defined $sid){
        $sid="S-1-5-32";
    }
    $smb_groupsid=$sid."-".$smb_groupsid;
    print "Updating samba group $group:\n";
    print "   * grp-sid: $smb_groupsid\n";

    my $dbh = DBI->connect("dbi:Pg:dbname=ldap;port=${DevelConf::sql_port}", 
                           "ldap","",
               { RaiseError => 0, PrintError => 0});
    if (not defined $dbh){
        print "   WARNING: Could not update samba group $group.\n";
        print "   Database ldap not running on port ${DevelConf::sql_port}\n";
	return 0;
    }

    my $dbh=&db_connect();
    my $sql="UPDATE samba_group_mapping
             SET sambasid='$smb_groupsid'
             WHERE id=(SELECT id from classdata where gid='$group')";
    #print "\nSQL: $sql\n";
    $dbh->do($sql);
    &db_disconnect($dbh);
    # update ldap
    system("/usr/sbin/smbldap-groupmod -s $smb_groupsid $group > /dev/null");
}



sub delete_groupmap {
    my ($group) = @_;
    if (not defined $group){
        return;
    }
    print "Deleting groupmap for ntgroup $group\n";

    my $dbh = DBI->connect("dbi:Pg:dbname=ldap;port=${DevelConf::sql_port}", 
                           "ldap","",
               { RaiseError => 0, PrintError => 0});
    if (not defined $dbh){
        print "   WARNING: Could not delete groupmap for $group.\n";
        print "   Database ldap not running on port ${DevelConf::sql_port}\n";
	return 0;
    }

    my $dbh=&db_connect();
    my $sql="DELETE FROM  samba_group_mapping
             WHERE displayname='$group'";
    #print "\nSQL: $sql\n";
    $dbh->do($sql);
    &db_disconnect($dbh);
    # update ldap
    system("net groupmap delete ntgroup='$group' > /dev/null");
}




sub create_indices {
    &titel("Creating indices for Postgresql");
    my $dbh = DBI->connect("dbi:Pg:dbname=ldap;port=${DevelConf::sql_port}", 
                           "ldap","",
               { RaiseError => 0, PrintError => 0});
    if (not defined $dbh){
        print "   WARNING: Could not create indices.\n";
        print "   Database ldap not running on port ${DevelConf::sql_port}\n";
	return 0;
    }

    # read indices from file
    &titel("Creating indices in $DevelConf::sql_create_index");
    system("$psql -p ${DevelConf::sql_port} -U ldap ldap < $DevelConf::sql_create_index");
}


sub drop_indices {
    &titel("Dropping indices in $DevelConf::sql_drop_index");
    my $dbh = DBI->connect("dbi:Pg:dbname=ldap;port=${DevelConf::sql_port}", 
                           "ldap","",
               { RaiseError => 0, PrintError => 0});
    if (not defined $dbh){
        print "   WARNING: Could not drop indices.\n";
        print "   Database ldap not running on port ${DevelConf::sql_port}\n";
	return 0;
    }

    open(DROP, "<$DevelConf::sql_drop_index") || die "Fehler: $!";
    while (<DROP>) {
        chomp(); # Returnzeichen abschneiden
        s/\s//g;
        if (/^\#/ or $_ eq "") {
            next;
        }
        my $index = $_;
        if($Conf::log_level>=3){
            print "   Trying to drop $index ...\n";
        }
        # connect, but dont raise errors
        my $dbh=&db_connect(0);

        my $sql="DROP INDEX $index;";	
        if($Conf::log_level>=3){
           print "\nSQL: $sql\n";
        }
        if ($dbh->do($sql)){
            print "      DROPPED index $index\n";
        } else {
            my $err_str=$dbh->errstr;
            if ($err_str=~/existiert nicht/){
                # german errors
                if($Conf::log_level>=3){
		   print "      WARNING: index $index is nonexisting\n";
                }
            } else {
                # other languages
                if($Conf::log_level>=3){
		    print "      $err_str";
                }
            }
        }
        &db_disconnect($dbh);
    }
    close(DROP);
}


sub add_ldap_group {
    my ($unix_group,$nt_group,$gid) = @_;
    if (defined getgrnam($unix_group)) {
        print "Group $unix_group (NT: $nt_group) exists already.\n";
    } else {
        system("smbldap-groupadd -g $gid '$unix_group'");
        system("net groupmap add rid=$gid unixgroup='$unix_group' ntgroup='$nt_group'");
    }
}

sub add_local_ldap_group {
    my ($unix_group,$nt_group,$gid) = @_;
    if (defined getgrnam($unix_group)) {
        print "Group $unix_group (NT: $nt_group) exists already.\n";
    } else {
        system("smbldap-groupadd -g $gid '$unix_group'");
        system("net groupmap add sid='S-1-5-32-$gid' unixgroup='$unix_group' ntgroup='$nt_group' type=local");
    }
}

sub set_samba_sid {
    my $sid=&get_smb_sid();
    my $dbh=&db_connect();
    my $sql="";
    print "\nSetting SID in the database to $sid \n";

    my $sth= $dbh->prepare( "SELECT sambasid,sambaprimarygroupsid,id 
                             FROM samba_sam_account" );
       $sth->execute();

    my $array_ref = $sth->fetchall_arrayref();

    my $i=0;
    foreach ( @{ $array_ref } ) {
       my $user_sid=${$array_ref}[$i][0];
       my $group_sid=${$array_ref}[$i][1];
       my $id=${$array_ref}[$i][2];

       print " OLD user-sid :  $user_sid  \n";
       print " OLD group-sid:  $group_sid \n";

       my $new_user_sid=&new_sid($sid,$user_sid);
       my $new_group_sid=&new_sid($sid,$group_sid);

       print " NEW user-sid :  $new_user_sid  \n";
       print " NEW group-sid:  $new_group_sid \n";

       $sql="UPDATE samba_sam_account 
             SET 
             sambasid='$new_user_sid', sambaprimarygroupsid='$new_group_sid'
             WHERE id=$id";
       print $sql,"\n";
       #$dbh->do($sql);
       $i++;
    }   
    &db_disconnect($dbh);
}



sub new_sid {
    my ($sid,$old) = @_;
    my (@list) = split(/-/,$old);
    my $last = pop @list;
    my $new = $sid."-".$last

}




sub set_ldap_institutes {
    # what about bsz.local.domain.de or so???????
    my $dbh=&db_connect();
    my $sql="";
    print "\nUpdating institutes to $institutes \n";
    $sql="UPDATE institutes SET name='$institutes' WHERE id=1";
    print $sql,"\n";
    $dbh->do($sql);

    &db_disconnect($dbh);
}


sub set_db_passwd {
    my ($pass) = @_;
    &titel("Updating password  for user ldap in Postgresql");
    my $dbh = DBI->connect("dbi:Pg:dbname=ldap;port=${DevelConf::sql_port}", 
                           "ldap","",
               { RaiseError => 0, PrintError => 0});
    if (not defined $dbh){
        print "   WARNING: Could not update password of user ldap in postgres.\n";
        print "   Database ldap not running on port ${DevelConf::sql_port}\n";
	return 0;
    }

    my $dbh=&db_connect();
    my $sql="";
    print "\nUpdating password of user ldap \n";
    $sql="ALTER USER ldap WITH ENCRYPTED password '$pass'";
    # WARNING: The following line prints the password
    #print $sql,"\n";
    $dbh->do($sql);
    &db_disconnect($dbh);
}

sub set_ldap_suffix_pg {
    &titel("Setting ldap suffix  for Postgresql");
    my ($suffix) = @_;
    my $dbh = DBI->connect("dbi:Pg:dbname=ldap;port=${DevelConf::sql_port}", 
                           "ldap","",
               { RaiseError => 0, PrintError => 0});
    if (not defined $dbh){
        print "   WARNING: Could not update ldap suffix.\n";
        print "   Database ldap not running on port ${DevelConf::sql_port}\n";
	return 0;
    }
    if (not defined $suffix or $suffix eq ""){
        print "I won't set a empty ldap suffix!\n "
    } else {
       my $dbh=&db_connect();
       my $sql="";
       print "\nUpdating sldap suffix in the postgres database to $suffix \n";

       # updating ldap_entries
       my $sth= $dbh->prepare( "SELECT dn,id FROM ldap_entries" );
          $sth->execute();

       my $array_ref = $sth->fetchall_arrayref();

       my $i=0;
       foreach ( @{ $array_ref } ) {
          my $old_dn=${$array_ref}[$i][0];
          my $id=${$array_ref}[$i][1];
          # split at first 'dn'
          my ($old_cn)=split(/dc=/,$old_dn);
          my $new_dn=$old_cn.$suffix;
          if ($i<5){
              print " OLD dn:  $old_dn \n";
              print "  NEW dn: $new_dn \n";
          } elsif ($i==5){
              if($Conf::log_level>=3){
                  print " OLD dn:  $old_dn \n";
                  print "  NEW dn: $new_dn \n";
              } else {
                  print "  ... omitting some entries\n";
              }
          } elsif ($i>5 and $Conf::log_level>=3){
              print " OLD dn:  $old_dn \n";
              print "  NEW dn: $new_dn \n";
          }
          $sql="UPDATE ldap_entries SET dn='$new_dn' WHERE id=$id";
          #print $sql,"\n";
          $dbh->do($sql);
          $i++;
       }
       print "... $i entries updated\n";
       &db_disconnect($dbh);
    }
}


sub create_database {
    print "Creating database ldap \n";
    my $file_admin = ${DevelConf::sql_create_path}."sophomorix-admin.sql";
    my $file_lang = ${DevelConf::sql_create_path}."sophomorix-lang.sql";
    my $file_db = ${DevelConf::sql_create_path}."sophomorix.sql";

    if ($lsb_release_codename eq "lenny"){
       print "Loading $file_admin\n";
       system("$psql -p ${DevelConf::sql_port} -U postgres template1 < $file_admin");
       print "Loading $file_lang\n";
       system("$psql -p ${DevelConf::sql_port} -U postgres ldap < $file_lang");
       print "Loading $file_db\n";
       system("$psql -p ${DevelConf::sql_port} -U ldap ldap < $file_db");
    } elsif ($lsb_release_codename eq "squeeze"){
       print "Loading $file_admin\n";
       system("$psql -p ${DevelConf::sql_port} -U postgres template1 < $file_admin");
       print "Loading $file_lang\n";
       system("$psql -p ${DevelConf::sql_port} -U postgres ldap < $file_lang");
       print "Loading $file_db\n";
       system("psql -p ${DevelConf::sql_port} -U ldap ldap < $file_db");
    } elsif ($lsb_release_codename eq "oneiric"){
       print "Loading $file_admin\n";
       system("psql -p ${DevelConf::sql_port} -U postgres template1 < $file_admin");
       print "Loading $file_lang\n";
       system("psql -p ${DevelConf::sql_port} -U postgres ldap < $file_lang");
       print "Loading $file_db\n";
       system("psql -p ${DevelConf::sql_port} -U ldap ldap < $file_db");
    } elsif ($lsb_release_codename eq "precise"){
       print "Loading $file_admin\n";
       system("psql -p ${DevelConf::sql_port} -U postgres template1 < $file_admin");
       print "Loading $file_lang\n";
       system("psql -p ${DevelConf::sql_port} -U postgres ldap < $file_lang");
       print "Loading $file_db\n";
       system("psql -p ${DevelConf::sql_port} -U ldap ldap < $file_db");
    }
}



sub upgrade_database {
#    if ($old_version eq "0.0.0-0"){
#        print "NOT upgrading database ldap (Old package is $old_version) \n";
#    } else {
        print "Modifying postgres database ldap with the following SQL-files: \n";
        foreach my $file_id (@upgrade_sql_id){
            my $file = ${DevelConf::sql_upgrade_path}.
                       $upgrade_sql_id_filename{$file_id};
            print "  $file \n";
            system("$psql -p ${DevelConf::sql_port} -U ldap ldap < $file");
        }
        my $number=$#upgrade_sql_id+1;
        print "  --> $number SQL-files were loaded\n\n";
#    }
}

sub run_upgrade_scripts {
#    if ($old_version eq "0.0.0-0"){
#        print "NOT running upgrade scripts (Old package is $old_version) \n";
#    } else {
        print "\nRunning the following upgrade scripts: \n";
        foreach my $file_id (@upgrade_scripts_id){
            my $file = ${DevelConf::upgrade_path_script}.
               $upgrade_scripts_id_filename{$file_id};
            print "  $file \n";
            chmod 0755, $file;
            system("$file");
        }
        my $number=$#upgrade_scripts_id+1;
        print "  --> $number scripts were run\n\n";
#    }
}


sub insert_line_before {
    my ($insert_line,$before,$file) = @_;
    my $file_tmp=$file.".tmp";
    my $seen_line=0;
    my @insert_line = split(/;/,$insert_line);
    my @before = split(/;/,$before);
    print "Checking if line is to be inserted into $file:\n";
    print "   Insert_Line: $insert_line[0]  ","$insert_line[1]  ",
                          "$insert_line[2]  ","$insert_line[3]  ",
                          "$insert_line[4]  ","$insert_line[5]  ",
                          "$insert_line[6]  \n";

    print "   Before:      $before[0]  " ,"$before[1]  ",
                          "$before[2]  ","$before[3]  ",
                          "$before[4]  ","$before[5]  ",
                          "$before[6]  \n";

    open(HBA, "<$file") || die "Fehler: $!";
    open(HBATMP, ">$file_tmp") || die "Fehler: $!";
    while (<HBA>) {
      chomp(); # Returnzeichen abschneiden
#      if ($_ eq ""){next;} # Wenn Zeile Leer, dann aussteigen
#      if(/^\#/){next;} # Bei Kommentarzeichen aussteigen
      my (@line) = split(/\s+/);
      if ($line[0] eq $insert_line[0] and
          $line[1] eq $insert_line[1] and
          $line[2] eq $insert_line[2] and
          $line[3] eq $insert_line[3] and
          $line[4] eq $insert_line[4] and
          $line[5] eq $insert_line[5] and
          $line[6] eq $insert_line[6]
         ){
          $seen_line=1;
          # doing nothing
          print "   Line is in $file already ...  doing nothing.\n";
          #print HBATMP $_,"\n",
          #next;
      }
      if ($before[0] eq $line[0] and
          $before[1] eq $line[1] and
          $before[2] eq $line[2] and
          $before[3] eq $line[3] and
          $before[4] eq $line[4] and
          $before[5] eq $line[5] and
          $before[6] eq $line[6] and
          $seen_line==0
         ){
          print "   Inserting new line, ...\n";
          print HBATMP "$insert_line[0]   ",
                       "$insert_line[1]        ",
                       "$insert_line[2]         ",
                       "$insert_line[3]      ",
                       "$insert_line[4]      ",
                       "$insert_line[5]      ",
	               "$insert_line[6]\n";
    }
        print HBATMP "$_","\n",
  }
  close(HBA);
  close(HBATMP);
  system("mv $file_tmp $file");
}




sub save_password {
    my ($password,$file)=@_;
    open (FILE, ">$file");
    print FILE $password;
    close (FILE);

}




sub get_pg_server_version {
    my ($port) = @_;
    if (not defined $port){
	$port="5432";
    }
    my $pg_version="";
    print "Checking for Postgres version on port ${port}:";
    my $dbh = DBI->connect("dbi:Pg:dbname=template1;port=$port",
                           "postgres","",
               { RaiseError => 0, PrintError => 0, AutoCommit => 1 } );
    if (defined $dbh){
        $pg_version=$dbh->{'pg_server_version'};
        print " $pg_version \n";
        &db_disconnect($dbh);
    } else {
        $pg_version=0;
        print " not running ($pg_version)\n";
    }
    return $pg_version;
}


