Alexey Chetroi wrote:
On Mon, Jan 20, 2003 at 12:45:20PM +0100, Michael Bell wrote:

Exporting the Mails ...

Error 700
General Error. Database failed with errorcode 2162021. OpenCA::DB->getNextItem: Cannot open database (2141013) OpenCA::DB->dbOpen: No status specified..
I think the problem is that you are using DBM-files and I'm testing with SQL-databases. I attached a modified version of export-import.lib again. I changed only one line - 1982: CERTIFICATE --> VALID_CERTIFICATE.

Michael
--
-------------------------------------------------------------------
Michael Bell Email (private): [EMAIL PROTECTED]
Rechenzentrum - Datacenter Email: [EMAIL PROTECTED]
Humboldt-University of Berlin Tel.: +49 (0)30-2093 2482
Unter den Linden 6 Fax: +49 (0)30-2093 2959
10099 Berlin
Germany http://www.openca.org
## export/import library of OpenCA Group
##
## (c) 1998-2001 by OpenCA Group
## the license is the general project license
## (see http://openca.sourceforge.net)

## only for testing the library
#use strict;
#my $db;
#my $cryptoShell;
#my $tools;
#my $query;

##
## Usage:
##
## Export
## ------
## $tmp = createStructure ();
## exportXYZ ($tmp);
## exportABC ($tmp);
## eximIOExport ( DIR => $tmp, LEVEL => "(UP|DOWN|LOCAL)" );
## removeDirectory ( $tmp );
##
## Import
## ------
## $tmp = createStructure ();
## eximIOImport ( DIR => $tmp, LEVEL => "(UP|DOWN|LOCAL)" );
## importXYZ ($tmp);
## importABC ($tmp);
## removeDirectory ( $tmp );
##
## export/import functions:
##   * CSRs
##   * Certs
##   * CRRs
##   * CRLs
##   * CAs
##   * Configuration 
##      * directory (RBAC, OpenSSL, extfiles)
##      * file (openssl.cnf)
##   * Mails
##   * BP
##   * ImportFromCA/ExportToCA
##   * ImportFromRAServer/ExportToRAServer
##   * DB
##   * replayLog (for SQL-DBs only today)
##   * uploadCommit
##   * enrollCommit
##   * receiveCommit
##   * downloadCommit
##  
## other functions:
##   * createDirectory
##   * createStructure
##   * removeDirectory
##   * eximIOStart
##   * eximIOStop
##   * eximIOImport
##   * eximIOExport
##   * eximIOTest
##
## directories for the different objects:
##   * CA_CERTIFICATE
##   * REQUEST
##   * CERTIFICATE
##   * CRR
##   * CRL
##   * Configuration
##      * RBAC
##      * OpenSSL
##      * extfiles
##      * others (for the rest)
##   * Mail

## the variables which start with $exim_ are reserved for this library

####################################
## general function for archiving ##
####################################

## 
## createDirectory
##
## this function prepare a temporary directory for the files
## which should be exported
##
sub createDirectory {

  my $exim_tmp_dir;
  if ( not $_[0] ) {
    $exim_tmp_dir = getRequired ('TempDir')."/tmp_".$$;
  } else {
    $exim_tmp_dir = $_[0];
  }

  if (not mkdir ( $exim_tmp_dir, 0700 )) {
    ## output is only necessary if something going wrong
    print addLogSection (i18nGettext ("Creating Temporary Directory __DIR__ ...", 
"__DIR__", $exim_tmp_dir));
    print addErrorLog (i18nGettext ("Cannot create temporary directory __DIR__!", 
"__DIR__", $exim_tmp_dir));
    print closeLogSection();
    return "";
  }

  return $exim_tmp_dir;
}

##
## createStructure
##
## this function prepare a temporary directory for the files
## which should be exported
##
sub createStructure {

  ## get the base directory
  my $dir;
  if ( not $_[0]) {
    $dir = createDirectory ();
  } else {
    $dir = $_[0];
  }
  if (not defined $dir or not $dir) {
    return undef;
  }

  ## create the subdirectories

  ## create structure
  my $list      = {
    CERTIFICATE    => [ "VALID", "EXPIRED", "REVOKED", "SUSPENDED" ],
    REQUEST        => [ "PENDING", "APPROVED", "ARCHIVED", "DELETED", "RENEW" ],
    CA_CERTIFICATE => [ "VALID", "EXPIRED" ],
    CRL            => [ "VALID" ],
    CRR            => [ "PENDING", "APPROVED", "ARCHIVED", "DELETED" ],
    LOG            => [ "ALL", "DOWNLOAD", "ENROLL", "RECEIVE", "UPLOAD" ],
    MAIL           => [ "CRINS", "DEFAULT" ],
                   };

  my $object;
  foreach $object (keys %{$list}) {
    return undef if (not createDirectory ( $dir."/".$object ));
    my $status;
    foreach $status (@{$list->{$object}}) {
      return undef if (not createDirectory ( $dir."/".$object."/".$status ));
    }
  }
    
  return $dir;

}

## 
## removeArchive
##
## this function remove a temporary directory
##
sub removeDirectory {

  my $exim_tmp_dir = $_[0];
  my $ret;

  print addLogSection (gettext ("Clean up ..."));

  if ( length ( $exim_tmp_dir ) < 10 ) {
    print addErrorLog (i18nGettext ("Stop removing temporary directory __DIR__ because 
the length of it is smaller than 10!",
                                    "__DIR__", $exim_tmp_dir));
    print closeLogSection();
    return 0;
  }

  $ret = `cd $exim_tmp_dir/..; rm -rf $exim_tmp_dir`;
  if( $? != 0 ) {
    print addErrorLog(i18nGettext("Cannot remove temporary directory __DIR__", 
"__DIR__", $exim_tmp_dir));
    print addLogLine( "rm -rf $exim_tmp_dir" );
    print closeLogSection();
    return 0;
  }
  print addLogLine( gettext ("Ok.") );
  print closeLogSection();

  return 1;
}

###############################
## functions for IO-handling ##
###############################

## all functions use the device and needs the direction
##   * eximIOStart
##   * eximIOStop
##   * eximIOImport
##   * eximIOExport
##   * eximIOTest

## idea by Bahaaldin Al-amood <[EMAIL PROTECTED]>

## interface

sub eximIOEnroll {
    return eximIOExport (DIR => $_[0], LEVEL => "DOWN");
}

sub eximIODownload {
    return eximIOImport (DIR => $_[0], LEVEL => "UP");
}

sub eximIOReceive {
    return eximIOImport (DIR => $_[0], LEVEL => "DOWN");
}

sub eximIOUpload {
    return eximIOExport (DIR => $_[0], LEVEL => "UP");
}

## implementation

sub eximIOStart
{
    my $keys   = { @_ };
    my @starts = getRequiredList ('EXPORT_IMPORT_'.$keys->{LEVEL}.'_START');
    return 1 if (not @starts or not $starts[0]);

    ## preparing IO-operation
    print addPreLogLine (gettext ("Preparing the IO-operations ...."));

    my $device = getRequired ('EXPORT_IMPORT_'.$keys->{LEVEL}.'_DEVICE');

    foreach my $start (@starts)
    {
        $start = $query->subVar($start, '@__DEVICE__@', $device);

        print addPreLogLine ($start);
        $ret=`$start 2>&1`;
        if( $? != 0 ) {
            print addPreLogSection ("<FONT COLOR=#FF0000>".
                                    i18nGettext ("The operation failed with errorcode 
__ERRNO__.",
                                                 "__ERRNO__", $?).
                                    "</FONT>");
            print closeLogSection ();
            return undef;
        }
    }
    print closeLogSection ();
    return 1;
}

sub eximIOStop
{
    my $keys  = { @_ };
    my @stops = getRequiredList ('EXPORT_IMPORT_'.$keys->{LEVEL}.'_STOP');
    return 1 if (not @stops or not $stops[0]);

    ## preparing IO-operation
    print addPreLogLine (gettext ("Cleanup the IO-operations ...."));

    my $device = getRequired ('EXPORT_IMPORT_'.$keys->{LEVEL}.'_DEVICE');

    foreach my $stop (@stops)
    {
        $stop      = $query->subVar($stop, '@__DEVICE__@', $device);

        print addPreLogLine ($stop);
        $ret=`$stop 2>&1`;
        if( $? != 0 ) {
            print addPreLogSection ("<FONT COLOR=#FF0000>".
                                    i18nGettext ("The operation failed with errorcode 
__ERRNO__.",
                                                 "__ERRNO__", $?).
                                    "</FONT>");
            print closeLogSection ();
            return undef;
        }
    }
    print closeLogSection ();
    return 1;
}

sub eximIOExport {

    my $keys = { @_ };
    my $exim_tmp_dir = $keys->{DIR};
    my $direction    = $keys->{LEVEL};
    $direction       = "LOCAL" if (not $direction);
    my $ret;

    return undef if (not eximIOStart (LEVEL => $direction));

    print addLogSection (gettext ("Exporting archive ..."));
    print addLogLine    ( "" );

    print addPreLogLine (gettext ("Load required variables ..."));

    ## Get required parameters from the configuration file
    my @arcs   = getRequiredList( 'EXPORT_IMPORT_'.$direction.'_EXPORT' );
    my $device = getRequired( 'EXPORT_IMPORT_'.$direction.'_DEVICE' );

    print addPreLogLine (i18nGettext ("Changing to directory __DIR__ ...", "__DIR__", 
$exim_tmp_dir));
    if (not chdir $exim_tmp_dir) {
        print addErrorLog (gettext ("failed"));
        print closeLogSection();
        eximIOStop (LEVEL => $direction);
        return undef;
    }

    print addPreLogLine (gettext ("Running the export command(s) ..."));
    foreach my $arc (@arcs)
    {
        ## building the command
        $arc = $query->subVar( $arc, '@__DEVICE__@', $device );
        $arc = $query->subVar( $arc, '@__SRC__@',    $exim_tmp_dir );

        print addPreLogLine ($arc);
        $ret = `$arc 2>&1`;
        if( $? != 0 ) {
            print addErrorLog(gettext ("Export failed!"));
            print addPreLogLine($ret);
            print closeLogSection();
            eximIOStop (LEVEL => $direction);
            return undef;
        }
    }

    print addPreLogLine (gettext ("Archive created successfully."));
    print closeLogSection();

    $return =  eximIOTest (LEVEL => $direction);

    if ($return)
    {
        return eximIOStop (LEVEL => $direction);
    } else {
        eximIOStop (LEVEL => $direction);
        return undef;
    }
}

sub eximIOImport {

    my $keys = { @_ };
    my $exim_tmp_dir = $keys->{DIR};
    my $direction    = $keys->{LEVEL};
    $direction       = "LOCAL" if (not $direction);
    my $ret;

    return undef if (not eximIOStart (LEVEL => $direction));

    if (not eximIOTest (LEVEL => $direction))
    {
        eximIOStop (LEVEL => $direction);
        return undef;
    }

    print addLogSection (gettext ("Importing archive ..."));
    print addLogLine    ( "" );

    print addPreLogLine (gettext ("Load required variables ..."));

    ## Get required parameters from the configuration file
    my @arcs   = getRequired( 'EXPORT_IMPORT_'.$direction.'_IMPORT' );
    my $device = getRequired( 'EXPORT_IMPORT_'.$direction.'_DEVICE' );

    print addPreLogLine (i18nGettext ("Changing to directory __DIR__ ...", "__DIR__", 
$exim_tmp_dir));
    if (not chdir $exim_tmp_dir) {
        print addErrorLog (gettext ("failed"));
        print closeLogSection ();
        eximIOStop (LEVEL => $direction);
        return undef;
    }

    print addPreLogLine(gettext ("Running the import command(s) ..."));
    foreach my $arc (@arcs)
    {
        ## Build the right $cmd with substitution of the $dest
        $arc = $query->subVar( $arc, '@__DEVICE__@', $device );
        $arc = $query->subVar( $arc, '@__DEST__@',   $exim_tmp_dir );

        print addPreLogLine($arc);
        $ret = `$arc 2>&1`;
        if( $? != 0 ) {
            print addErrorLog(gettext ("Import failed!"));
            print closeLogSection ();
            eximIOStop (LEVEL => $direction);
            return undef;
       }
    }
    print closeLogSection ();

    return eximIOStop (LEVEL => $direction);
}

sub eximIOTest {
    my $keys  = { @_ };
    my $test  = getRequired ('EXPORT_IMPORT_'.$keys->{LEVEL}.'_TEST');
    return 1 if (not $test);

    ## preparing IO-operation
    print addLogSection (gettext ("Test the archive ..."));

    my $device = getRequired ('EXPORT_IMPORT_'.$keys->{LEVEL}.'_DEVICE');
    $test      = $query->subVar($test, '@__DEVICE__@', $device);

    print addPreLogLine ($test);
    $ret = `$test 2>&1`;
    if( $? != 0 ) {
        print addLogLine ("<FONT COLOR=#ff0000>".gettext ("FAILED")."</FONT>");
        print addErrorLog(i18nGettext ("Testing archive failed!"));
        print closeLogSection();
        return undef;
    }
    addLogLine (gettext ("OK"));
    print closeLogSection ();
    return 1;
}

######################################
## functions for DB-backup/recovery ##
######################################

#####################################################
##                general warning                  ##
#####################################################
## * all actions are handled by this function      ##
##   (except of html-header and -footer)           ##
## * use importDB only on an empty DB              ##
## * if importDB detects an already existing       ##
##   object it only signal this event and continue ##
## * every import of an object is documented in    ##
##   the logs if you use OpenCA::DB and importDB   ##
## * replayLog only use the logs and replay all    ##
##   actions of the CA or RAServer                 ##
## * if you want to use replayLog you MUST create  ##
##   the database again to get consistent state,   ##
##   if you replay on a not newly created database ##
##   then the result is undefined                  ##
#####################################################

sub exportDB {

  ## create initial structure
  my $dir = createStructure ();
  if (not defined $dir or not $dir) {
    return undef;
  }

  ## structure
  my $list      = {
    CERTIFICATE    => [ "VALID", "EXPIRED", "REVOKED", "SUSPENDED" ],
    REQUEST        => [ "PENDING", "APPROVED", "ARCHIVED", "DELETED", "RENEW" ],
    CA_CERTIFICATE => [ "VALID", "EXPIRED" ],
    CRL            => [ "VALID" ],
    CRR            => [ "PENDING", "APPROVED", "ARCHIVED", "DELETED" ],
    LOG            => [ "ALL" ],
                   };

  ## iterate over all types of object
  foreach my $object (keys %{$list}) {

    if ( ($object =~ /LOG/) and (getRequired ('DBmodule') !~ /DBI/i) ) {
      next;
    }

    ## iterate over all states
    foreach my $status (@{$list->{$object}}) {

      exportObjects ( DATATYPE => $object, STATUS => $status, DIR => $dir, BACKUP => 1 
);

    }

  }

  ## create the archive
  return undef if (not eximIOExport ( DIR => $dir ));

  ## remove the hole structure
  return undef if (not removeDirectory ( $dir ));

  return 1;
}

sub importDB {

  ## create initial structure
  my $dir = createDirectory ();
  if (not defined $dir or not $dir) {
    return undef;
  }

  ## extract archive
  if (not eximIOImport ( DIR => $dir )) {
    return undef;
  }

  ## structure
  my $list      = {
    CERTIFICATE    => [ "VALID", "EXPIRED", "REVOKED", "SUSPENDED" ],
    REQUEST        => [ "PENDING", "APPROVED", "ARCHIVED", "DELETED", "RENEW" ],
    CA_CERTIFICATE => [ "VALID", "EXPIRED" ],
    CRL            => [ "VALID" ],
    CRR            => [ "PENDING", "APPROVED", "ARCHIVED", "DELETED" ],
    LOG            => [ "ALL" ],
                   };

  ## iterate over all types of object
  foreach my $object (keys %{$list}) {

    if ( ($object =~ /LOG/) and (getRequired ('DBmodule') !~ /DBI/i) ) {
      next;
    }

    ## iterate over all states
    foreach my $status (@{$list->{$object}}) {

      importObjects ( DATATYPE => $object, STATUS => $status, DIR => $dir, 
ALLOW_STATE_INJECTION => 1 );

    }

  }

  ## remove the hole structure
  return undef if (not removeDirectory ( $dir ));

  return 1;
}

## this function recovers a database only from the logs!
## so if you want to have a secure replay you can use
## this function (we are doing datalogging)
sub replayLog {
  
  if ( getRequired ('DBmodule') !~ /DBI/i ) {
    print addPreLogLine ( "<FONT COLOR=#FF0000>".gettext ("FAILURE: You can only 
replay the logs if you are using a SQL-database")."</FONT>");
    print addPreLogLine ( "<FONT COLOR=#FF0000>".gettext ("ABORTING ...")."</FONT>");
    print closeLogSection ();
    return undef;
  }

  ## create initial structure
  my $dir = createDirectory ();
  if (not defined $dir or not $dir) {
    print addPreLogLine ( "<FONT COLOR=#FF0000>".gettext("FAILURE: Cannot create 
temporary directory")."</FONT>" );
    print closeLogSection ();
    return undef;
  }

  ## extract archive
  if (not eximIOImport ( DIR => $dir )) {
    return undef;
  }

  ## start output
  print addLogSection (gettext ("Replaying logs (on a new and empty sql-database only) 
..."));

  my $directory = $dir."/LOG/ALL";
  opendir( DIR, $directory );
  my @dirList = grep (/^[^\.]/, readdir( DIR ));
  closedir( DIR );

  if (not scalar @dirList) {
    print addPreLogLine ("<i>".gettext ("The log is empty.")."</i>");
  }
  for (my $i=1; $i <= scalar @dirList; $i++) {

    ## setup filename
    my $filename = $directory."/".$i.".log";

    ## load the file
    my $content = $tools->getFile ( $filename );

    ## load the datatype
    my ( $object ) = ( $content =~ /^([^\n]*)/ );
    $content =~ s/^[^\n]*\n//;

    ## load the status
    my ( $status ) = ( $content =~ /^([^\n]*)/ );
    $content =~ s/^[^\n]*\n//;

    ## write back the file
    ( $filename ) = ( $content =~ /^([^\n]*)/ );
    $content =~ s/^[^\n]*\n//;

    ## write back filename
    $filename = $dir."/LOG/".$filename;
    if (not $tools->saveFile (FILENAME => $filename, DATA => $content)) {
      print addPreLogLine ( "<FONT COLOR=#FF0000>".gettext ("FAILURE: Cannot write 
file")."</FONT>");
      print addPreLogLine ( "<FONT COLOR=#FF0000>".i18nGettext("FILE: __FILE__", 
"__FILE__", $filename)."</FONT>");
      print addPreLogLine ( "<FONT COLOR=#FF0000>".gettext ("ABORTING ...")."</FONT>");
      print closeLogSection ();
      return undef;
    }

    ## create object
    my $db_object;
    if ($object =~ /CERTIFICATE/) {
      $db_object = new OpenCA::X509 ( SHELL  => $cryptoShell,
                                      INFILE => $filename,
                                      FORMAT => "PEM" );
    } elsif ($object =~ /^(REQUEST|CRR)$/) {
      $db_object = new OpenCA::REQ ( SHELL  => $cryptoShell,
                                     INFILE => $filename);
    } else {
      $db_object = new OpenCA::CRL ( INFILE => $filename,
                                     SHELL  => $cryptoShell );
    }
    if (not defined $db_object or not $db_object) {
      print addPreLogLine ( "<FONT COLOR=#FF0000>".gettext ("FAILURE: Cannot create 
object from file")."</FONT>");
      print addPreLogLine ( "<FONT COLOR=#FF0000>".i18nGettext ("FILE: __FILE__", 
"__FILE__", $filename)."</FONT>");
      print addPreLogLine ( "<FONT COLOR=#FF0000>".gettext ("ABORTING ...")."</FONT>");
      print closeLogSection ();
      return undef;
    }

    if ( defined $db->storeItem ( DATATYPE => $status."_".$object,
                                  OBJECT   => $db_object,
                                  MODE     => "UPDATE" )) {
      $filename =~ s/.*\///;
      print addPreLogLine (i18nGettext ("__STATUS_____OBJECT__ updated from __FILE__.",
                                        "__STATUS__", $status,
                                        "__OBJECT__", $object,
                                        "__FILE__", $filename));
    } else {
      if ( defined $db->storeItem ( DATATYPE => $status."_".$object,
                                    OBJECT   => $db_object,
                                    MODE     => "INSERT" )) {
        $filename =~ s/.*\///;
        print addPreLogLine (i18nGettext ("__STATUS_____OBJECT__ inserted from 
__FILE__.",
                                          "__STATUS__", $status,
                                          "__OBJECT__", $object,
                                          "__FILE__", $filename));
      } else {
        print addPreLogLine ( "<FONT COLOR=#FF0000>".gettext ("FAILURE: Cannot 
insert/update object")."</FONT>");
        print addPreLogLine ( "<FONT COLOR=#FF0000>".i18nGettext ("FILE: __FILE__", 
"__FILE__", $filename)."</FONT>");
        print addPreLogLine ( "<FONT COLOR=#FF0000>".gettext ("ABORTING 
...")."</FONT>");
        print closeLogSection ();
        return undef;
      }
    }
  }

  ## end output
  print closeLogSection ();

  ## remove the hole structure
  return undef if (not removeDirectory ( $dir ));

  return 1;
}

###########################
## functions for objects ##
###########################

# Input: DATATYPE and/or STATUS
# Output: array with the ex-/imported Objects

# determine status and datatype
sub eximObjectsGetDatatype {
  my $keys = { @_ };
  my @result = ();

  # determine status
  if ($keys->{STATUS}) {
    $result [1] = $keys->{STATUS};
  } else {
    $result [1] = $keys->{DATATYPE};
    $result [1] =~ s/_.*$//;
    $result [1] = "" if ($result [1] =~ /^(CA|CERTIFICATE|REQUEST|CRR|CRL|LOG)$/);
  }
  
  # determine datatype
  $result [0] = $keys->{DATATYPE};
  $result [0] =~ s/^$result[1]_// if ($result [1]);

  return @result;
}

sub exportObjects {
  my $keys = { @_ };
  my @datatype = eximObjectsGetDatatype ( @_ );

  print addLogSection ( i18nGettext ("Exporting __STATUS__ __OBJECT__ ...",
                                     "__STATUS__", lc $datatype [1],
                                     "__OBJECT__", $datatype [0]) );

  ## load objects
  my @list;
  if ($datatype [1] and ($datatype [0] !~ /LOG/)) {
    @list = $db->searchItems ( DATATYPE => $datatype [1]."_".$datatype [0] );
  } elsif ($datatype [0] !~ /LOG/) {
    @list = $db->searchItems ( DATATYPE => $datatype [0] );
  } else {
    @list = $db->searchItems ( DATATYPE => $datatype [0] );
  }

  ## write objects
  my @result = ();
  if (not defined @list and $db->errno()) {
    ## error detected
    print addErrorLog (i18nGettext ("Database failed with errorcode __ERRNO__.",
                                    "__ERRNO__", $db->errno()));
    print addErrorLog ($db->errval());
    return undef;
  }
  if (not scalar @list) {
    print addPreLogLine ("<i>".gettext ("No objects are present.")."</i>");
  }
  my $count = 0;
  foreach my $value (@list) {

    my $txtItem;
    my $serial;
    my $format;

    my $log = 0;
    if ($datatype [0] =~ /LOG/) {
       $log = 1;
       $count++;
       $datatype [0] = $value-> [0];
       $datatype [1] = $value-> [1];
       my $h   = $value-> [2];
       $value  = undef;
       $value  = $h;
    } else {
       next if (not $keys->{BACKUP} and
                not eximMustBeExported (DATATYPE => $datatype [1]."_".$datatype [0],
                                        MODE     => $keys->{MODE},
                                        KEY      => $value->getSerial ($datatype [0]))
               );
    }

    ## get content, serial and format for file
    $txtItem = $value->getItem ();
    $serial  = $value->getSerial ($datatype [0]);
    if( $datatype [0] =~ /(REQUEST|CRR)/i ) {
      $format = $value->getParsed()->{TYPE};
    } else {
      $format = "PEM";
    }
    $format =~ s/\s/_/g;

    ## corrections for logs
    if ($log) {

      # filename
      $txtItem = $serial.".".(lc $format)."\n".$txtItem;
      # status
      $txtItem = $datatype [1]."\n".$txtItem;
      # datatype
      $txtItem = $datatype [0]."\n".$txtItem;

      $datatype [0] = "LOG";
      $datatype [1] = "ALL";
      $format       = "log";
      $serial       = $count;
    }

    ## write file
    my $filename = $keys->{DIR}."/".$datatype [0]."/".$datatype 
[1]."/".$serial.".".(lc $format);
    if ($tools->saveFile (FILENAME => $filename,
                          DATA     => $txtItem)) {
      print addPreLogLine ($serial.".".(lc $format));
      push (@result, $serial);
    } else {
      print addPreLogLine ( "<FONT COLOR=#FF0000>".i18nGettext ("FAILURE: __SERIAL__ 
(__FORMAT__).",
                                                                "__SERIAL__", $serial,
                                                                "__FORMAT__", lc 
$format)."</FONT>");
      print addPreLogLine ( "<FONT COLOR=#FF0000>".i18nGettext ("FILE: __FILE__", 
"__FILE__", $filename)."</FONT>");
    }
  }

  print closeLogSection ();

  return @result;

}

## parameters are:
##     STATUS                - state of object
##     DATATYPE              - datatype of object perhaps with state as prefix
##     DIR                   - temporary directory of import
##     ALLOW_STATE_INJECTION - true or false
##     ENFORCE               - true or false (deprecated)
##     MODE                  - upload, download, receive, enroll

sub importObjects {
  my $keys = { @_ };
  my @datatype = eximObjectsGetDatatype ( @_ );
  my $DEBUG = 0;

  print addLogSection (i18nGettext ("Importing __STATUS__ __OBJECT__ ...",
                                    "__STATUS__", lc $datatype [1],
                                    "__OBJECT__", $datatype [0]) );

  if ( ($datatype [0] =~ /LOG/) and (getRequired ('DBmodule') !~ /DBI/i) ) {
    print addPreLogLine (gettext ("Logs are only available on SQL-Databases!"));
    print closeLogSection ();
    return ();
  }

  my $dir = $keys->{DIR};

  my $directory = $dir."/".$datatype [0]."/".$datatype [1];
  opendir( DIR, $directory );
  my @dirList = grep (/^[^\.]/, readdir( DIR ));
  closedir( DIR );

  my @result = ();
  if (not scalar @dirList) {
    print addPreLogLine ("<i>".gettext ("No objects are present.")."</i>");
  }
  foreach my $value (@dirList) {

    ## setup filename
    my $filename = $directory."/".$value;

    ## if we load the the logs we have to do a little bit more
    my $log = 0;
    if ($datatype [0] =~ /LOG/) {
      $log = 1;
      $keys->{ALLOW_STATE_INJECTION} = 1; 

      ## value
      $value =~ s/\.log$//;

      ## load the file
      my $content = $tools->getFile ( $filename );

      ## load the datatype
      ( $datatype [0] ) = ( $content =~ /^([^\n]*)/ );
      $content =~ s/^[^\n]*\n//;

      ## load the status
      ( $datatype [1] ) = ( $content =~ /^([^\n]*)/ );
      $content =~ s/^[^\n]*\n//;

      ## write back the file
      ( $filename ) = ( $content =~ /^([^\n]*)/ );
      $content =~ s/^[^\n]*\n//;

      ## write back filename
      $filename = $dir."/LOG/".$filename;
      if (not $tools->saveFile (FILENAME => $filename, DATA => $content)) {
        print addPreLogLine ( "<FONT COLOR=#FF0000>".gettext ("FAILURE: Cannot write 
file")."</FONT>");
        print addPreLogLine ( "<FONT COLOR=#FF0000>".i18nGettext ("FILE: __FILE__", 
"__FILE__", $filename)."</FONT>");
        next;
      }
    }

    ## create object
    my $db_object;
    if ($datatype [0] =~ /CERTIFICATE/) {
      $db_object = new OpenCA::X509 ( SHELL  => $cryptoShell,
                                      INFILE => $filename,
                                      FORMAT => "PEM" );
    } elsif ($datatype [0] =~ /^(REQUEST|CRR)$/) {
      $db_object = new OpenCA::REQ ( SHELL  => $cryptoShell,
                                     INFILE => $filename);
    } else {
      $db_object = new OpenCA::CRL ( INFILE => $filename,
                                     SHELL  => $cryptoShell );
    }
    if (not defined $db_object or not $db_object) {
      print addPreLogLine ( "<FONT COLOR=#FF0000>".gettext ("FAILURE: Cannot create 
object from file")."</FONT>");
      print addPreLogLine ( "<FONT COLOR=#FF0000>".i18nGettext ("FILE: __FILE__", 
"__FILE__", $filename)."</FONT>");
      next;
    }

    ## insert object
    my $h;
    my $db_mode = "INSERT";
    if ($log) {
      $h = $db->storeItem ( DATATYPE        => "LOG",
                            OBJECT_DATATYPE => $datatype [1]."_".$datatype [0],
                            OBJECT          => $db_object,
                            KEY             => $value,
                            MODE            => $db_mode );
      $datatype [0] = "LOG";
      $value       .= ".log";
      $datatype [1] = "ALL";
    } else {

      ## 1a. determine the old state of the object
      ## 1b. fix states if there are more than one state
      ## 2. compare with the new state and defines a new state
      ## 3. set new state and data if necessary via updateStatus, update or insert
      ## 4. update related objects

      my $old_status;
      my $new_status = $datatype [1];
      my $next_status;

      ############### 1. ################

      if ($datatype [0] =~ /CA_CERTIFICATE/i) {
        my $item_1 = $db->getItem ( DATATYPE => "VALID_CA_CERTIFICATE",
                                    KEY      => 
$db_object->getSerial("CA_CERTIFICATE") );
        my $item_2 = $db->getItem ( DATATYPE => "EXPIRED_CA_CERTIFICATE",
                                    KEY      => 
$db_object->getSerial("CA_CERTIFICATE") );
        if ($item_1 and $item_2) {
          $old_status = "EXPIRED";
          $db->deleteItem ( DATATYPE => "VALID_CA_CERTIFICATE",
                            KEY      => $db_object->getSerial("CA_CERTIFICATE") );
        } elsif ($item_2) {
          $old_status = "EXPIRED";
        } elsif ($item_1) {
          $old_status = "VALID";
        } else {
          $old_status = undef;
        }
      } elsif ($datatype [0] =~ /CRL/i) {
        ## nothing todo
      } elsif ($datatype [0] =~ /CERTIFICATE/i) {
        my $item_1 = $db->getItem ( DATATYPE => "VALID_CERTIFICATE",
                                    KEY      => $db_object->getSerial() );
        my $item_2 = $db->getItem ( DATATYPE => "EXPIRED_CERTIFICATE",
                                    KEY      => $db_object->getSerial() );
        my $item_3 = $db->getItem ( DATATYPE => "SUSPENDED_CERTIFICATE",
                                    KEY      => $db_object->getSerial() );
        my $item_4 = $db->getItem ( DATATYPE => "REVOKED_CERTIFICATE",
                                    KEY      => $db_object->getSerial() );
        if ($item_4) {
          $old_status = "REVOKED";
          $db->deleteItem ( DATATYPE =>"SUSPENDED_CERTIFICATE", KEY => 
$db_object->getSerial() )
            if ($item_3);
          $db->deleteItem ( DATATYPE =>"EXPIRED_CERTIFICATE", KEY => 
$db_object->getSerial() )
            if ($item_2);
          $db->deleteItem ( DATATYPE =>"VALID_CERTIFICATE", KEY => 
$db_object->getSerial() )
            if ($item_1);
        } elsif ($item_3) {
          $old_status = "SUSPENDED";
          $db->deleteItem ( DATATYPE =>"EXPIRED_CERTIFICATE", KEY => 
$db_object->getSerial() )
            if ($item_2);
          $db->deleteItem ( DATATYPE =>"VALID_CERTIFICATE", KEY => 
$db_object->getSerial() )
            if ($item_1);
        } elsif ($item_2) {
          $old_status = "EXPIRED";
          $db->deleteItem ( DATATYPE =>"VALID_CERTIFICATE", KEY => 
$db_object->getSerial() )
            if ($item_1);
        } elsif ($item_1) {
          $old_status = "VALID";
        } else {
          $old_status = undef;
        }
      } elsif ($datatype [0] =~ /CRR/i) {
        my $item_1 = $db->getItem ( DATATYPE => "PENDING_CRR",
                                    KEY      => $db_object->getSerial() );
        my $item_2 = $db->getItem ( DATATYPE => "APPROVED_CRR",
                                    KEY      => $db_object->getSerial() );
        my $item_3 = $db->getItem ( DATATYPE => "DELETED_CRR",
                                    KEY      => $db_object->getSerial() );
        my $item_4 = $db->getItem ( DATATYPE => "ARCHIVED_CRR",
                                    KEY      => $db_object->getSerial() );
        if ($item_4) {
          $old_status = "ARCHIVED";
          $db->deleteItem ( DATATYPE =>"DELETED_CRR", KEY => $db_object->getSerial() )
            if ($item_3);
          $db->deleteItem ( DATATYPE =>"APPROVED_CRR", KEY => $db_object->getSerial() )
            if ($item_2);
          $db->deleteItem ( DATATYPE =>"PENDING_CRR", KEY => $db_object->getSerial() )
            if ($item_1);
        } elsif ($item_3) {
          $old_status = "DELETED";
          $db->deleteItem ( DATATYPE =>"APPROVED_CRR", KEY => $db_object->getSerial() )
            if ($item_2);
          $db->deleteItem ( DATATYPE =>"PENDING_CRR", KEY => $db_object->getSerial() )
            if ($item_1);
        } elsif ($item_2) {
          $old_status = "APPROVED";
          $db->deleteItem ( DATATYPE =>"PENDING_CRR", KEY => $db_object->getSerial() )
            if ($item_1);
        } elsif ($item_1) {
          $old_status = "PENDING";
        } else {
          $old_status = undef;
        }
      } else { ## REQUEST
        my $item_1 = $db->getItem ( DATATYPE => "PENDING_REQUEST",
                                    KEY      => $db_object->getSerial() );
        my $item_2 = $db->getItem ( DATATYPE => "APPROVED_REQUEST",
                                    KEY      => $db_object->getSerial() );
        my $item_3 = $db->getItem ( DATATYPE => "DELETED_REQUEST",
                                    KEY      => $db_object->getSerial() );
        my $item_4 = $db->getItem ( DATATYPE => "ARCHIVED_REQUEST",
                                    KEY      => $db_object->getSerial() );
        if ($item_4) {
          $old_status = "ARCHIVED";
          $db->deleteItem ( DATATYPE =>"DELETED_REQUEST", KEY => 
$db_object->getSerial() )
            if ($item_3);
          $db->deleteItem ( DATATYPE =>"APPROVED_REQUEST", KEY => 
$db_object->getSerial() )
            if ($item_2);
          $db->deleteItem ( DATATYPE =>"PENDING_REQUEST", KEY => 
$db_object->getSerial() )
            if ($item_1);
        } elsif ($item_3) {
          $old_status = "DELETED";
          $db->deleteItem ( DATATYPE =>"APPROVED_REQUEST", KEY => 
$db_object->getSerial() )
            if ($item_2);
          $db->deleteItem ( DATATYPE =>"PENDING_REQUEST", KEY => 
$db_object->getSerial() )
            if ($item_1);
        } elsif ($item_2) {
          $old_status = "APPROVED";
          $db->deleteItem ( DATATYPE =>"PENDING_REQUEST", KEY => 
$db_object->getSerial() )
            if ($item_1);
        } elsif ($item_1) {
          $old_status = "PENDING";
        } else {
          $old_status = undef;
        }
      }

      if ($DEBUG) {
        print "export-import.lib: importObjects: Phase 1<br>\n";
        print "export-import.lib: importObjects: old_status = ".$old_status."<br>\n";
        print "export-import.lib: importObjects: new_status = ".$new_status."<br>\n";
        print "export-import.lib: importObjects: next_status = ".$next_status."<br>\n";
      }

      ################### 2. #############################

      if ($datatype [0] =~ /CA_CERTIFICATE/i) {
        if ( ($old_status =~ /EXPIRED/i) or ($new_status =~ /EXPIRED/i) ) {
          $next_status = "EXPIRED";
        } else {
          $next_status = "VALID";
        }
      } elsif ($datatype [0] =~ /CRL/i) {
        $next_status = "VALID";
      } elsif ($datatype [0] =~ /CERTIFICATE/i) {
        if ( ($old_status =~ /REVOKED/i) or ($new_status =~ /REVOKED/i) ) {
          $next_status = "REVOKED";
        } elsif ( ($old_status =~ /SUSPENDED/i) or ($new_status =~ /SUSPENDED/i) ) {
          if ( ($old_status =~ /SUSPENDED/i) and ($new_status =~ /SUSPENDED/i) ) {
            $next_status = "SUSPENDED";
          } elsif ($db->searchItems ( DATATYPE => "ARCHIVED_CRR", 
REVOKE_CERTIFICATE_SERIAL => $db_object->getSerial() ) or
              $db->searchItems ( DATATYPE => "APPROVED_CRR", REVOKE_CERTIFICATE_SERIAL 
=> $db_object->getSerial() ) or
              $db->searchItems ( DATATYPE => "PENDING_CRR", REVOKE_CERTIFICATE_SERIAL 
=> $db_object->getSerial() ) ) {
            $next_status = "SUSPENDED";
          } elsif ( ($old_status =~ /EXPIRED/i) or ($new_status =~ /EXPIRED/i) ) {
            $next_status = "EXPIRED";
          } else {
            $next_status = "VALID";
          }
        } elsif ( ($old_status =~ /EXPIRED/i) or ($new_status =~ /EXPIRED/i) ) {
          $next_status = "EXPIRED";
        } else {
          $next_status = "VALID";
        }
      } elsif ($datatype [0] =~ /CRR/i) {
        if ( ($old_status =~ /ARCHIVED/i) or ($new_status =~ /ARCHIVED/i) ) {
          $next_status = "ARCHIVED";
        } elsif ( ($old_status =~ /DELETED/i) or ($new_status =~ /DELETED/i) ) {
          $next_status = "DELETED";
        } elsif ( ($old_status =~ /APPROVED/i) or ($new_status =~ /APPROVED/i) ) {
          $next_status = "APPROVED";
        } else {
          $next_status = "PENDING";
        }
      } else { ## REQUEST
        if ( ($old_status =~ /ARCHIVED/i) or ($new_status =~ /ARCHIVED/i) ) {
          $next_status = "ARCHIVED";
        } elsif ( ($old_status =~ /DELETED/i) or ($new_status =~ /DELETED/i) ) {
          $next_status = "DELETED";
        } elsif ( ($old_status =~ /APPROVED/i) or ($new_status =~ /APPROVED/i) ) {
          $next_status = "APPROVED";
        } else {
          $next_status = "PENDING";
        }
      }

      if ($DEBUG) {
        print "export-import.lib: importObjects: Phase 2<br>\n";
        print "export-import.lib: importObjects: old_status = ".$old_status."<br>\n";
        print "export-import.lib: importObjects: new_status = ".$new_status."<br>\n";
        print "export-import.lib: importObjects: next_status = ".$next_status."<br>\n";
      }

      ########################## 3. ###########################

      if ($old_status and ($old_status eq $next_status)) {
        $db_mode = "UPDATE";
        if ($keys->{ALLOW_STATE_INJECTION})
        {
            $h = $db->storeItem ( DATATYPE => $next_status."_".$datatype [0],
                                  OBJECT   => $db_object,
                                  MODE     => $db_mode );
        } else {
            $h = undef;
        }
        ## cannot enforce !
      } elsif ($old_status) {
        $db_mode = "UPDATE";
        if ($keys->{ALLOW_STATE_INJECTION})
        {
            $h = $db->updateStatus ( DATATYPE => $old_status."_".$datatype [0],
                                     NEWTYPE  => $next_status."_".$datatype [0],
                                     OBJECT   => $db_object );
            ## try to enforce
            if ( not defined $h and $keys->{ENFORCE} )
            {
                $db_mode = "INSERT";
                $h = $db->storeItem ( DATATYPE => $next_status."_".$datatype [0],
                                      OBJECT   => $db_object,
                                      MODE     => $db_mode );
                if ( not defined $h )
                {
                    $db_mode = "UPDATE";
                    $h = $db->storeItem ( DATATYPE => $next_status."_".$datatype [0],
                                          OBJECT   => $db_object,
                                          MODE     => $db_mode );
                }
            }
        } else {
            $h = undef;
        }
      } else {
        $db_mode = "INSERT";
        $h = $db->storeItem ( DATATYPE => $next_status."_".$datatype [0],
                              OBJECT   => $db_object,
                              MODE     => $db_mode );
        ## try to enforce
        if ( not defined $h and $keys->{ENFORCE} and $keys->{ALLOW_STATE_INJECTION}) {
          $db_mode = "UPDATE";
          $h = $db->storeItem ( DATATYPE => $next_status."_".$datatype [0],
                                OBJECT   => $db_object,
                                MODE     => $db_mode );
        }
      }

      if (defined $h and $keys->{MODE})
      {
          my $logdir  = getRequired ('LOG_'.uc($keys->{MODE}).'_DIR');
          my $logfile = $logdir."/".eximGetModuleID($dir)."_".$datatype 
[1]."_".$datatype[0].".log";
          if ( not open (FD, ">>".$logfile) or
               not print (FD "\n".$db_object->getSerial($datatype[0])) or
               not close (FD)
             )
          {
              print addPreLogLine (i18nGettext ("__IMPORTFILE__ cannot be logged in 
__LOG_FILE__",
                                                "__IMPORTFILE__", $value,
                                                "__LOG_FILE__", $logfile));
          }
      }

      ######################### 4. #############################

      if (defined $h)
      {

          ##// check for correct certificate's state if CRR is on the way or successful

          if ( ($datatype [0] =~ /CRR/i) and ($next_status !~ /DELETED/i) ) {

            my $cert_serial = $db_object->getParsed()->{REVOKE_CERTIFICATE_SERIAL};

            my $item_1 = $db->getItem ( DATATYPE => "VALID_CERTIFICATE",
                                        KEY      => $cert_serial );
            my $item_2 = $db->getItem ( DATATYPE => "EXPIRED_CERTIFICATE",
                                        KEY      => $cert_serial );
            my $item_3 = $db->getItem ( DATATYPE => "SUSPENDED_CERTIFICATE",
                                        KEY      => $cert_serial );

            my $item = undef;
            if ($item_1) {
              $item = $item_1;
              $old_cert_status = "VALID";
            } elsif ($item_2) {
              $item = $item_2;
              $old_cert_status = "EXPIRED";
            } elsif ($item_3) {
              $item = $item_3;
              $old_cert_status = "SUSPENDED";
            }

            if ($item) {
              if ($next_status =~ /ARCHIVED/i) {
                $db->updateStatus (DATATYPE => $old_cert_status."_CERTIFICATE",
                                   NEWTYPE  => "REVOKED_CERTIFICATE",
                                   OBJECT   => $item);
              } elsif ($old_cert_status !~ /SUSPENDED/i) {
                $db->updateStatus (DATATYPE => $old_cert_status."_CERTIFICATE",
                                   NEWTYPE  => "SUSPENDED_CERTIFICATE",
                                   OBJECT   => $item);
              }
            }
          }

          ## delete all CRRs which are on the way if one CRR is archived (successful)

          if ( ($datatype [0] =~ /CRR/i) and ($next_status =~ /ARCHIVED/i) ) {

            my $cert_serial = $db_object->getParsed()->{REVOKE_CERTIFICATE_SERIAL};

            my @list = $db->searchItems ( DATATYPE => "PENDING_CRR",
                                        REVOKE_CERTIFICATE_SERIAL => $cert_serial );
            foreach my $item (@list) {
              $db->updateStatus ( DATATYPE => "PENDING_CRR",
                                  NEWTYPE  => "DELETED_CRR",
                                  OBJECT   => $item);
            }

            my @list = $db->searchItems ( DATATYPE => "APPROVED_CRR",
                                        REVOKE_CERTIFICATE_SERIAL => $cert_serial );
            foreach my $item (@list) {
              $db->updateStatus ( DATATYPE => "APPROVED_CRR",
                                  NEWTYPE  => "DELETED_CRR",
                                  OBJECT   => $item);
            }

          }

          ##// check correct certificate's state if CRR is deleted

          if ( ($datatype [0] =~ /CRR/i) and ($next_status =~ /DELETED/i) ) {

            my $cert_serial = $db_object->getParsed()->{REVOKE_CERTIFICATE_SERIAL};

            my @list_1 = $db->searchItems ( DATATYPE => "PENDING_CRR",
                                        REVOKE_CERTIFICATE_SERIAL => $cert_serial );
            my @list_2 = $db->searchItems ( DATATYPE => "APPROVED_CRR",
                                        REVOKE_CERTIFICATE_SERIAL => $cert_serial );
            my @list_3 = $db->searchItems ( DATATYPE => "ARCHIVED_CRR",
                                        REVOKE_CERTIFICATE_SERIAL => $cert_serial );

            my $old_status;
            my $item;
            if (@list_1 or @list_2 or @list_3) {
              my $item_1 = $db->getItem ( DATATYPE => "VALID_CERTIFICATE",
                                          KEY      => $cert_serial );
              my $item_2 = $db->getItem ( DATATYPE => "EXPIRED_CERTIFICATE",
                                          KEY      => $cert_serial );
              my $item_3 = $db->getItem ( DATATYPE => "SUSPENDED_CERTIFICATE",
                                          KEY      => $cert_serial );
              my $item_4 = $db->getItem ( DATATYPE => "REVOKED_CERTIFICATE",
                                          KEY      => $cert_serial );
              if ($item_4) {
                $old_status = "REVOKED";
                $item = $item_4;
                $db->deleteItem ( DATATYPE =>"SUSPENDED_CERTIFICATE", KEY => 
$cert_serial )
                  if ($item_3);
                $db->deleteItem ( DATATYPE =>"EXPIRED_CERTIFICATE", KEY => 
$cert_serial )
                  if ($item_2);
                $db->deleteItem ( DATATYPE =>"VALID_CERTIFICATE", KEY => $cert_serial )
                  if ($item_1);
              } elsif ($item_3) {
                $old_status = "SUSPENDED";
                $item = $item_3;
                $db->deleteItem ( DATATYPE =>"EXPIRED_CERTIFICATE", KEY => 
$cert_serial )
                  if ($item_2);
                $db->deleteItem ( DATATYPE =>"VALID_CERTIFICATE", KEY => $cert_serial )
                  if ($item_1);
              } elsif ($item_2) {
                $old_status = "EXPIRED";
                $item = $item_2;
                $db->deleteItem ( DATATYPE =>"VALID_CERTIFICATE", KEY => $cert_serial )
                  if ($item_1);
              } elsif ($item_1) {
                $old_status = "VALID";
                $item = $item_1;
              } else {
                $old_status = undef;
              }
            }

            if ($old_status !~ /REVOKED/i) {
              if (scalar @list_3) {
                ##// certificate's state is revoked
                $db->updateStatus ( DATATYPE => $old_status."_CERTIFICATE",
                                    NEWTYPE  => "REVOKED_CERTIFICATE",
                                    OBJECT   => $item);
              } elsif (scalar @list_1 or scalar @list_2) {
                ##// certificate's state is suspended
                $db->updateStatus ( DATATYPE => $old_status."_CERTIFICATE",
                                    NEWTYPE  => "SUSPENDED_CERTIFICATE",
                                    OBJECT   => $item);
              } else {
                ##// certificate's state is valid (or expired) again
                $db->updateStatus ( DATATYPE => $old_status."_CERTIFICATE",
                                    NEWTYPE  => "VALID_CERTIFICATE",
                                    OBJECT   => $item);
              }
            }

          }

      } ## end of if loop (defined $h)

      ############################### finished import of object 
###########################

    }

    ## errordetection
    if (defined $h) {
      push (@result, $db_object);

      if ($db_mode =~ /UPDATE/) {
        print addPreLogLine (i18nGettext ("__IMPORTFILE__ updated", "__IMPORTFILE__", 
$value));
      } else {
        print addPreLogLine (i18nGettext ("__IMPORTFILE__ inserted", "__IMPORTFILE__", 
$value));
      }
    } else {
      # serial
      my $serial = $db_object->getSerial ($datatype [0]);
      ## advanced information
      if ($db->searchItems ( DATATYPE => $datatype [0], KEY => $serial ))
      {
        if ($keys->{MODE} and not $keys->{ALLOW_STATE_INJECTION})
        {
            my $logdir  = getRequired ('LOG_'.uc($keys->{MODE}).'_DIR');
            my $logfile = $logdir."/".eximGetModuleID($dir)."_".$datatype 
[1]."_".$datatype[0].".log";
            if ( not open (FD, ">>".$logfile) or
                 not print (FD "\n".$db_object->getSerial($datatype[0])) or
                 not close (FD)
               )
            {
                print addPreLogLine (i18nGettext ("__IMPORTFILE__ cannot be logged in 
__LOG_FILE__",
                                                  "__IMPORTFILE__", $value,
                                                  "__LOG_FILE__", $logfile));
            }
        }
        if ($db_mode !~ /UPDATE/) {
          print addPreLogLine ( "<FONT COLOR=#FF0000>".gettext ("WARNING: Cannot 
insert object but object is present in database")."</FONT>");
          print addPreLogLine ( "<FONT COLOR=#FF0000>".i18nGettext ("FILE: __FILE__", 
"__FILE__", $filename)."</FONT>");
        } else {
          print addPreLogLine ( "<FONT COLOR=#FF0000>".gettext ("WARNING: Cannot 
update object but object is present in database")."</FONT>");
          print addPreLogLine ( "<FONT COLOR=#FF0000>".i18nGettext ("FILE: __FILE__", 
"__FILE__", $filename)."</FONT>");
        }
      } elsif ($db_mode !~ /UPDATE/) {
        print addPreLogLine ( "<FONT COLOR=#FF0000>".gettext ("FAILURE: Cannot insert 
object and object is not present in database")."</FONT>");
        print addPreLogLine ( "<FONT COLOR=#FF0000>".i18nGettext ("FILE: __FILE__", 
"__FILE__", $filename)."</FONT>");
      } else {
        print addPreLogLine ( "<FONT COLOR=#FF0000>".gettext ("FAILURE: Cannot insert 
and/or update object and object is not present in database")."</FONT>");
        print addPreLogLine ( "<FONT COLOR=#FF0000>".i18nGettext ("FILE: __FILE__", 
"__FILE__", $filename)."</FONT>");
      }
    }
  }

  print closeLogSection ();

  return @result;

}

############################
## functions for Requests ##
############################

## the requests are only archived during the import of the certificates
## to handle crashed disks etc.

sub eximEnrollCSRs {

    my $exim_tmp_dir = $_[0];

    foreach my $state (eximGetStates (DATATYPE => "CSR", MODE => "ENROLL"))
    {
        exportObjects ( DATATYPE => "${state}_REQUEST", DIR => $exim_tmp_dir, MODE => 
"ENROLL" );
    }

    return 1;
}

sub eximUploadCSRs {

    my $exim_tmp_dir = $_[0];

    foreach my $state (eximGetStates (DATATYPE => "CSR", MODE => "UPLOAD"))
    {
        exportObjects ( DATATYPE => "${state}_REQUEST", DIR => $exim_tmp_dir, MODE => 
"UPLOAD" );
    }

    return 1;
}

sub eximReceiveCSRs {

    my $exim_tmp_dir = $_[0];

    foreach my $state (eximGetStates (DATATYPE => "CSR", MODE => "RECEIVE"))
    {
        importObjects ( DATATYPE => "${state}_REQUEST", DIR => $exim_tmp_dir, MODE => 
"RECEIVE" );
    }

    return 1;
}

sub eximDownloadCSRs {

    my $exim_tmp_dir = $_[0];

    foreach my $state (eximGetStates (DATATYPE => "CSR", MODE => "DOWNLOAD"))
    {
        importObjects ( DATATYPE              => "${state}_REQUEST",
                        DIR                   => $exim_tmp_dir,
                        MODE                  => "DOWNLOAD",
                        ALLOW_STATE_INJECTION => 1);
    }

    return 1;
}

###############################
## functions for Certifcates ##
###############################

sub eximEnrollCerts {

    my $exim_tmp_dir = $_[0];

    foreach my $state (eximGetStates (DATATYPE => "CERTIFICATE", MODE => "ENROLL"))
    {
        exportObjects ( DATATYPE => "${state}_CERTIFICATE", DIR => $exim_tmp_dir, MODE 
=> "ENROLL" );
    }
    eximEnrollCSRs ($exim_tmp_dir);

    return 1;
}

sub eximDownloadCerts {

  my $keys = { @_ };

  my $exim_tmp_dir = $keys->{TMP};
  my $certDir = getRequired ( 'CertDir' );

  my  @list;
  foreach my $state (eximGetStates (DATATYPE => "CERTIFICATE", MODE => "DOWNLOAD"))
  {
      @list = importObjects ( DATATYPE => "${state}_CERTIFICATE", DIR => 
$exim_tmp_dir, MODE => "DOWNLOAD" );
  }
  eximDownloadCSRs ($exim_tmp_dir);

  my $dir = $exim_tmp_dir."/CERTIFICATE/VALID/";

  return 1 if (not $keys->{LDAP}); 

  if ( $keys->{LDAP} ) {
    print addLogSection( gettext ("Importing Certificates into ldap ... "));

    if ( not scalar @list) {
      print addPreLogLine ("<i>".gettext ("No certificates present.")."</i>");
    }
    foreach my $data (@list) {
      my $result = eximObjectToLDAP ( CERTIFICATE => $data );
      my $ret;
      if ( not $result or not $result->{STATUS} ) {
        $ret = "\n<FONT COLOR=#FF0000>".i18nGettext ("Cannot write CERTIFICATE 
__CERT_SERIAL__ to LDAP",
                                                     "__CERT_SERIAL__", 
$data->getSerial ())."</FONT>";
      } else {
        $ret = "\n".i18nGettext ("CERTIFICATE __CERT_SERIAL__ is available via LDAP",
                                 "__CERT_SERIAL__", $data->getSerial ());
      }
      print addPreLogLine ($ret);
    }
  }

  ##// what I'm doing here???
  ## perhaps this code is outdated
  ## upating lastImport
  my $txt = "";
  my $line;
  foreach $line  (@list) {
    $txt .= $line->getSerial ()."\n";
  };
  unlink( "$certDir/lastImport.txt" );
  if (not $tools->saveFile (FILENAME => "$certDir/lastImport.txt",
                            DATA     => $txt ) ) {
    print addPreLogLine ("<FONT COLOR=#FF0000>".
                         i18nGettext ("Cannot update file __FILE__ with certificates 
of last import",
                                      "__FILE__", "$certDir/lastImport.txt").
                         "</FONT>");
  }
  print closeLogSection();

  return 1;
}

##################################
## functions for CA-Certifcates ##
##################################

sub eximEnrollCAs {

    my $exim_tmp_dir = $_[0];

    foreach my $state (eximGetStates (DATATYPE => "CA_CERTIFICATE", MODE => "ENROLL"))
    {
        exportObjects ( DATATYPE => "${state}_CA_CERTIFICATE", DIR => $exim_tmp_dir, 
MODE => "ENROLL" );
    }

    return 1;
}

sub eximDownloadCAs {

  my $keys = { @_ };

  my $exim_tmp_dir = $keys->{TMP};

  my @list;
  foreach my $state (eximGetStates (DATATYPE => "CA_CERTIFICATE", MODE => "DOWNLOAD"))
  {
      @list = importObjects ( DATATYPE => "${state}_CA_CERTIFICATE", DIR => 
$exim_tmp_dir, MODE => "DOWNLOAD", ENFORCE => 1 );
  }
  if ($keys->{LDAP}) {

    print addLogSection( gettext ("Importing CA-Certificates into ldap ... "));

    ## get newest ca-cert
    my $cacert = LDAP_get_ca ();

    if (not $cacert) {
      print addPreLogLine ("<FONT COLOR=#FF0000>".gettext ("Cannot load 
CA-certificate")."</FONT>");
    } else {
      ## update LDAP
      my $result = eximObjectToLDAP ( AUTHORITY_CERTIFICATE => $cacert );
      if ( not $result or not $result->{STATUS} ) {
        print addPreLogLine ("<FONT COLOR=#FF0000>".i18nGettext ("Cannot write 
CA-Certificate __CERT_SERIAL__ to LDAP",
                                                                 "__CERT_SERIAL__", 
$cacert->getSerial("CA_CERTIFICATE")).
                             "</FONT>" );
      } else {
        print addPreLogLine (i18nGettext ("CA-Certificate __CERT_SERIAL__ is available 
via LDAP",
                                          "__CERT_SERIAL__", 
$cacert->getSerial("CA_CERTIFICATE")));
      }
    }
    print closeLogSection();
  }

  print addLogSection (gettext("Make CA-Certificate available on the server ..."));
  my @cacerts = $db->searchItems ( DATATYPE => "VALID_CA_CERTIFICATE" );
  my $key;
  my $serial = -1;
  my $cert_data = "";
  my $cert_der  = "";
  my $cert_txt  = "";
  foreach my $cert (@cacerts) {
    if ( $cert->getSerial () > $serial ) {
      $serial    = $cert->getSerial ();
      $key       = $cert->getSerial ("CA_CERTIFICATE");
      $cert_data = $cert->getPEM ();
      $cert_der  = $cert->getDER ();
      $cert_txt  = $cert->getTXT ();
    }
  }
  $tools->saveFile ( FILENAME => "${exim_tmp_dir}/${key}.pem", DATA => $cert_data);
  my $CACert = getRequired ( 'CACertificate');
  if( not $tools->copyFiles ( SRC  => "${exim_tmp_dir}/${key}.pem",
                                 DEST => $CACert ) ) {
    print addLogLine ( gettext ("FAILED.") );
    print addPreLogLine( "<FONT COLOR=#FF0000>".
                         i18nGettext ("Copying latest ca-certificate into the RAServer 
failed (from __FILE__ to __TARGET__).",
                                      "__FILE__", "${exim_tmp_dir}/${key}.pem",
                                      "__TARGET__", $CACert).
                         "</FONT>");
    print closeLogSection ();
    return 0;
  }
  $tools->saveFile ( FILENAME => "${exim_tmp_dir}/${key}.der", DATA => $cert_der);
  my $CACertDER = getRequired ( 'CACertificateDER');
  if( not $tools->copyFiles ( SRC  => "${exim_tmp_dir}/${key}.der",
                                 DEST => $CACertDER ) ) {
    print addLogLine ( "FAILED." );
    print addPreLogLine( "<FONT COLOR=#FF0000>".
                         i18nGettext ("Copying latest ca-certificate into the RAServer 
failed (from __FILE__ to __TARGET__).",
                                      "__FILE__", "${exim_tmp_dir}/${key}.der",
                                      "__TARGET__", $CACertDER).
                         "</FONT>");
    print closeLogSection ();
    return 0;
  }
  $tools->saveFile ( FILENAME => "${exim_tmp_dir}/${key}.txt", DATA => $cert_txt);
  my $CACertTXT = getRequired ( 'CACertificateTXT');
  if( not $tools->copyFiles ( SRC  => "${exim_tmp_dir}/${key}.txt",
                                 DEST => $CACertTXT ) ) {
    print addLogLine ( "FAILED." );
    print addPreLogLine( "<FONT COLOR=#FF0000>".
                         i18nGettext ("Copying latest ca-certificate into the RAServer 
failed (from __FILE__ to __TARGET__).",
                                      "__FILE__", "${exim_tmp_dir}/${key}.txt",
                                      "__TARGET__", $CACertTXT).
                         "</FONT>");
    print closeLogSection ();
    return 0;
  }
  print addLogLine ("OK.");
  print closeLogSection (); 

  #// Now we copy the CA's certificate to the chain dir
  my $cacertCRT = getRequired ('CACertificateCRT');
  if (not $tools->copyFiles( SRC => $CACert,
                     DEST => $cacertCRT )) {
    print addLogSection( "<FONT COLOR=#FF0000>".
                         i18nGettext ("Copying latest ca-certificate into the RAServer 
failed (from __FILE__ to __TARGET__).",
                                      "__FILE__", "${exim_tmp_dir}/${key}.pem",
                                      "__TARGET__", $CACertCRT).
                         "</FONT>");
    print closeLogSection ();
    return 0;
  }

  ##// Let's make Chain verification
  print addLogSection(gettext ("Re-Building CA Chain ... "));
  my $chainDir = getRequired ( 'ChainDir' );
  chdir( "${chainDir}" );
  ## what for command?
  my $makeCmd = getRequired ('MakePath');
  my $ret = `$makeCmd clean ; $makeCmd 2>&1`;
  if ( $? ) {
    print addLogLine ("<FONT COLOR=#FF0000>".gettext ("FAILED")."</FONT>");
    print closeLogSection();
    return 0;
  } else {
    print addLogLine(gettext ("Ok."));
  }
  print closeLogSection();

  return 1;
}


########################
## functions for CRRs ##
########################

sub eximEnrollCRRs {

    my $exim_tmp_dir = $_[0];

    foreach my $state (eximGetStates (DATATYPE => "CRR", MODE => "ENROLL"))
    {
        exportObjects ( DATATYPE => "${state}_CRR", DIR => $exim_tmp_dir, MODE => 
"ENROLL" );
    }

    return 1;
}

sub eximUploadCRRs {

    my $exim_tmp_dir = $_[0];

    foreach my $state (eximGetStates (DATATYPE => "CRR", MODE => "UPLOAD"))
    {
        exportObjects ( DATATYPE => "${state}_CRR", DIR => $exim_tmp_dir, MODE => 
"UPLOAD" );
    }

    return 1;
}

sub eximReceiveCRRs {

    my $exim_tmp_dir = $_[0];

    foreach my $state (eximGetStates (DATATYPE => "CRR", MODE => "RECEIVE"))
    {
        importObjects ( DATATYPE => "${state}_CRR", DIR => $exim_tmp_dir, MODE => 
"RECEIVE" );
    }

    return 1;
}

sub eximDownloadCRRs {

    my $exim_tmp_dir = $_[0];

    foreach my $state (eximGetStates (DATATYPE => "CRR", MODE => "DOWNLOAD"))
    {
        importObjects ( DATATYPE => "${state}_CRR",
                        DIR => $exim_tmp_dir,
                        MODE => "DOWNLOAD",
                        ALLOW_STATE_INJECTION => 1 );
    }

    return 1;
}

########################
## functions for CRLs ##
########################

sub eximEnrollCRLs {

  my $exim_tmp_dir = $_[0];

  foreach my $state (eximGetStates (DATATYPE => "CRL", MODE => "ENROLL"))
  {
      exportObjects ( DATATYPE => "${state}_CRL", DIR => $exim_tmp_dir, MODE => 
"ENROLL" );
  }
  eximEnrollCRRs ($exim_tmp_dir);

  return 1;
}

sub eximDownloadCRLs {

  my $keys = { @_ };

  my $exim_tmp_dir = $keys->{TMP};

  my @list;
  foreach my $state (eximGetStates (DATATYPE => "CRL", MODE => "DOWNLOAD"))
  {
      @list = importObjects ( DATATYPE => "${state}_CRL", DIR => $exim_tmp_dir, MODE 
=> "DOWNLOAD", ENFORCE => 1 );
  }
  eximDownloadCRRs ($exim_tmp_dir);

  return 1 if (not defined (@list) or not scalar @list);

  if ( $keys->{LDAP} ) {
    print addLogSection(gettext ("Importing CRL into LDAP ... "));

    ## get newest CRL
    my $crl = LDAP_get_crl ();

    if (not $crl) {
      print addPreLogLine ("<FONT COLOR=#FF0000>".gettext("Cannot load 
CRL")."</FONT>");
    } else {
      my $result = eximObjectToLDAP ( CRL => $crl );
      if ( not $result or not $result->{STATUS} ) {
        print addPreLogLine ( "<FONT COLOR=#FF0000>".
                              gettext ("Cannot write CRL to LDAP").
                              "\n\t".
                              i18nGettext ("Last Update: __LAST_UPDATE__",
                                           "__LAST_UPDATE__", 
$crl->getParsed()->{LAST_UPDATE}).
                              "\n\t".
                              i18nGettext ("Next Update: __NEXT_UPDATE__",
                                           "__NEXT_UPDATE__", 
$crl->getParsed()->{NEXT_UPDATE}).
                              "\n".
                              "</FONT>");
      } else {
        print addPreLogLine (
                              gettext ("Added CRL to LDAP").
                              "\n\t".
                              i18nGettext ("Last Update: __LAST_UPDATE__",
                                           "__LAST_UPDATE__", 
$crl->getParsed()->{LAST_UPDATE}).
                              "\n\t".
                              i18nGettext ("Next Update: __NEXT_UPDATE__",
                                           "__NEXT_UPDATE__", 
$crl->getParsed()->{NEXT_UPDATE}).
                              "\n");
      }
    }
    print closeLogSection ();
  }

  my $crlDir = getRequired ( 'CRLDir');

  print addLogSection(gettext ("Importing CRL into servers ... "));

  my $serial = 0;
  my $data;
  foreach my $tmpCRL (@list) {

    if ($cryptoShell->getNumericDate ($tmpCRL->getParsed()->{LAST_UPDATE}) > $serial) {
      $serial = $cryptoShell->getNumericDate ($tmpCRL->getParsed()->{LAST_UPDATE});
      $data = $tmpCRL;
    }
  }

  ## RAServer
  if (not $tools->saveFile ( FILENAME=>"$crlDir/cacrl.pem",
                             DATA=>$data->getPEM())) {
    print addPreLogLine ( "<FONT COLOR=#FF0000>".
                          i18nGettext ("Cannot update CRL on RAServer. FILE: __FILE__",
                                       "__FILE__", "$crlDir/cacrl.pem").
                          "</FONT>");
  }
  if (not $tools->saveFile ( FILENAME=>"$crlDir/cacrl.der",
                             DATA=>$data->getDER())) {
    print addPreLogLine ( "<FONT COLOR=#FF0000>".
                          i18nGettext ("Cannot update CRL on RAServer. FILE: __FILE__",
                                       "__FILE__", "$crlDir/cacrl.der").
                          "</FONT>");
  }
  if (not $tools->saveFile ( FILENAME=>"$crlDir/cacrl.crl",
                             DATA=>$data->getDER())) {
    print addPreLogLine ( "<FONT COLOR=#FF0000>".
                          i18nGettext ("Cannot update CRL on RAServer. FILE: __FILE__",
                                       "__FILE__", "$crlDir/cacrl.crl").
                          "</FONT>");
  }
  if (not $tools->saveFile ( FILENAME=>"$crlDir/cacrl.txt",
                             DATA=>$data->getTXT())) {
    print addPreLogLine ( "<FONT COLOR=#FF0000>".
                          i18nGettext ("Cannot update CRL on RAServer. FILE: __FILE__",
                                       "__FILE__", "$crlDir/cacrl.txt").
                          "</FONT>");
  }

  print addPreLogLine (
              gettext ("Added CRL to servers").
              "\n\t".
              i18nGettext ("Last Update: __LAST_UPDATE__",
                           "__LAST_UPDATE__", $data->getParsed()->{LAST_UPDATE}).
              "\n\t".
              i18nGettext ("Next Update: __NEXT_UPDATE__",
                           "__NEXT_UPDATE__", $data->getParsed()->{NEXT_UPDATE}).
              "\n");

  print closeLogSection();

  return 1;
}

#################################
## functions for Configuration ##
#################################

sub eximEnrollConfiguration {

  my $exim_tmp_dir = $_[0];
  my $dir = $exim_tmp_dir."/Configuration";

  if ( not createDirectory ($dir) ) {
    return 0;
  }

#  my $openssl     = getRequired ( 'sslconfig'   );
  my $rbac_dir    = getRequired ( 'RBAC_DIR'    );
#  my $openssl_dir = getRequired ( 'OPENSSL_DIR' );
#  my $ext_dir     = getRequired ( 'EXT_DIR'     );
  my $config_dir  = $rbac_dir;

  $config_dir  =~ s/\/[^\/]*$//;
  $rbac_dir    =~ s/^.*\///g;
#  $openssl_dir =~ s/^.*\///g;
#  $ext_dir     =~ s/^.*\///g;

  my $tmpdir = $dir;
  if( not chdir( "$tmpdir" )) {
    print addErrorLog( i18nGettext ("Failed changing dir to __DIR__!", "__DIR__", 
$tmpdir) );
    print closeLogSection ();
    return 0;
  }

#  ## bring openssl.cnf to tmp-dir
#
#  print addLogSection("Exporting the OpenSSL-configurationfile of the CA ... ");
#  $ret = `cp $openssl . 2>&1`;
#  if( $? != 0 ) {
#    print addErrorLog("Cannot copy $openssl to $tmpdir!");
#    print addLogLine( "cp $openssl ." );
#    print closeLogSection ();
#    return 0;
#  }
#  print addLogLine( "Ok." );
#  print closeLogSection ();

  ## bring RBAC/ to tmp-dir

  print addLogSection(gettext("Exporting the RBAC-configuration ... "));
  mkdir $tmpdir if (not -d $tmpdir);
  my $ret = `cd $config_dir; tar -cf - $rbac_dir | tar -xf - -C $tmpdir 2>&1`;
  if( $? != 0 ) {
    print addErrorLog(i18nGettext ("Cannot copy __SRC_DIR__ to __DEST_DIR__!",
                                   "__SRC_DIR__", $rbac_dir,
                                   "__DEST_DIR__", $tmpdir));
    print addLogLine( "cd $config_dir; tar -cf - $rbac_dir | tar -xf - -C $tmpdir" );
    print closeLogSection ();
    return 0;
  }
  print addLogLine( gettext ("Ok.") );
  print closeLogSection ();

#  ## bring OpenSSL/ to tmp-dir
#
#  print addLogSection("Exporting the OpenSSL-configuration of the roles ... ");
#  $ret = `cd $config_dir; tar -c $openssl_dir | tar -x -C $tmpdir 2>&1`;
#  if( $? != 0 ) {
#    print addErrorLog("Cannot copy $openssl_dir to $tmpdir!");
#    print addLogLine( "cd $config_dir; tar -c $openssl_dir | tar -x -C $tmpdir" );
#    print closeLogSection ();
#    return 0;
#  }
#  print addLogLine( "Ok." );
#  print closeLogSection ();

#  ## bring extfiles/ to tmp-dir
#
#  print addLogSection("Exporting the configuration of the extensions of the roles ... 
");
#  $ret = `cd $config_dir; tar -c $ext_dir | tar -x -C $tmpdir 2>&1`;
#  if( $? != 0 ) {
#    print addErrorLog("Cannot copy $ext_dir to $tmpdir!");
#    print addLogLine( "cd $config_dir; tar -c $ext_dir | tar -x -C $tmpdir" );
#    print closeLogSection ();
#    return 0;
#  }
#  print addLogLine( "Ok." );
#  print closeLogSection ();

  return 1;
}

sub eximDownloadConfiguration {

  my $exim_tmp_dir = $_[0];
  my $dir = $exim_tmp_dir."/Configuration";

#  my $openssl     = getRequired ( 'sslconfig'   );
  my $rbac_dir    = getRequired ( 'RBAC_DIR'    );
#  my $openssl_dir = getRequired ( 'OPENSSL_DIR' );
#  my $ext_dir     = getRequired ( 'EXT_DIR'     );
  my $config_dir  = $rbac_dir;
 
  $config_dir  =~ s/\/[^\/]*$//;
  $rbac_dir    =~ s/^.*\///g;
#  $openssl_dir =~ s/^.*\///g;
#  $ext_dir     =~ s/^.*\///g;                                                         
         

  my ( @lastExport );

  my $tmpdir = $dir;
  if (not chdir ( $tmpdir ) ) {
    print addErrorLog( i18nGettext ("Cannot change directory to __DIR__!", "__DIR__", 
$tmpdir));
    print closeLogSection ();
    return 0;
  }

#  ## importing openssl.cnf
#
#  my $sslconfig = $openssl;
#  $sslconfig =~ s/.*\///g;
#  print addLogSection("Importing the OpenSSL-configurationfile of the CA ... ");
#  $ret = `cp $sslconfig $openssl 2>&1`;
#  if( $? != 0 ) {
#    print addErrorLog("Cannot copy $sslconfig to $openssl!");
#    print addLogLine( "cp $sslconfig $openssl" );
#    print closeLogSection ();
#    return 0;
#  }
#  print addLogLine( "Ok." );
#  print closeLogSection ();

  ## importing RBAC/

  print addLogSection(gettext("Importing the RBAC-configuration ... "));
  my $ret = `tar -cf - $rbac_dir | tar -xf - -C $config_dir 2>&1`;
  if( $? != 0 ) {
    print addErrorLog(i18nGettext ("Cannot copy __SRC_DIR__ to __DEST_DIR__!",
                                   "__SRC_DIR__", $rbac_dir,
                                   "__DEST_DIR__", $config_dir));
    print addLogLine( "tar -cf - $rbac_dir | tar -xf - -C $config_dir" );
    print closeLogSection ();
    return 0;
  }
  print addLogLine( gettext("Ok.") );
  print closeLogSection ();

#  ## importing OpenSSL/
#
#  print addLogSection("Importing the OpenSSL-configuration of the roles  ... ");
#  $ret = `tar -c $openssl_dir | tar -x -C $config_dir 2>&1`;
#  if( $? != 0 ) {
#    print addErrorLog("Cannot copy $openssl_dir to $config_dir!");
#    print addLogLine( "tar -c $openssl_dir | tar -x -C $config_dir" );
#    print closeLogSection ();
#    return 0;
#  }
#  print addLogLine( "Ok." );
#  print closeLogSection ();

#  ## importing extfiles/
#
#  print addLogSection("Importing the configuration of the extensions of the roles ... 
");
#  $ret = `tar -c $ext_dir | tar -x -C $config_dir 2>&1`;
#  if( $? != 0 ) {
#    print addErrorLog("Cannot copy $ext_dir to $config_dir!");
#    print addLogLine( "tar -c $ext_dir | tar -x -C $config_dir" );
#    print closeLogSection ();
#    return 0;
#  }
#  print addLogLine( "Ok." );
#  print closeLogSection ();

  return 1;
}

#########################
## functions for Mails ##
#########################

sub eximEnrollMails {

    my $exim_tmp_dir = $_[0];

    print addLogSection(gettext("Exporting the Mails ... "));

    my $cert = libDBGetFirstItem ("VALID_CERTIFICATE");
    if (not $cert)
    {
        print addPreLogLine ("<i>".gettext ("No certificates are present.")."</i>");
        print closeLogSection ();
        return 1;
    }
    do
    {
        foreach my $type (eximGetStates (DATATYPE => "MAIL", MODE => "ENROLL"))
        {
            next if (not $type);
            if (eximMustBeExported (DATATYPE => uc($type)."_MAIL",
                                    MODE => "ENROLL",
                                    KEY => $cert->getSerial()))
            {
                my $msg = getRequired 
(uc($type)."_MAIL_DIR")."/".$cert->getSerial().".msg";
                next if (not -f $msg);
                if (not $tools->copyFiles (SRC => $msg, DEST => 
$exim_tmp_dir."/MAIL/".uc($type)))
                {
                    print addPreLogLine ( "<FONT COLOR=#FF0000>".
                                          i18nGettext ("FAILURE: __SERIAL__",
                                                       "__SERIAL__", 
$cert->getSerial()).
                                          "</FONT>");
                    print addPreLogLine ( "<FONT COLOR=#FF0000>".
                                          i18nGettext ("FILE: __FILE__", "__FILE__", 
$msg).
                                          "</FONT>");
                } else {
                    print addPreLogLine ($msg);
                }
            }
        }

        $cert = $db->getNextItem (DATATYPE => "VALID_CERTIFICATE", KEY => 
$cert->getSerial());
    } while ($cert);

    print closeLogSection ();

    return 1;
}

sub eximDownloadMails {

    my $exim_tmp_dir = $_[0];
 
    foreach my $type (eximGetStates (DATATYPE => "MAIL", MODE => "DOWNLOAD"))
    {
        next if (not $type);

        print addLogSection(gettext ("Importing the Mails (".uc($type).") ... "));

        my $directory = $exim_tmp_dir."/MAIL/".uc($type);
        opendir( DIR, $directory );
        my @dirList = grep (/^[^\.]/, readdir( DIR ));
        closedir( DIR );

        if (not scalar @dirList) {
            print addPreLogLine ("<i>".gettext ("No mails are present.")."</i>");
        }
        foreach my $value (@dirList) {

            if (not $tools->copyFiles (SRC => $directory."/".$value, DEST => 
getRequired (uc($type)."_MAIL_DIR")))
            {
                print addPreLogLine ("<FONT COLOR=#FF0000>".
                                     i18nGettext ("__MSG__ cannot be copied to 
__DIR__!",
                                                  "__MSG__", $directory."/".$value,
                                                  "__DIR__", getRequired 
(uc($type)."_MAIL_DIR")).
                                     "</FONT>");
            } else {
                $value =~ s/.msg//;
                my $logdir  = getRequired ('LOG_DOWNLOAD_DIR');
                my $logfile = 
$logdir."/".eximGetModuleID($exim_tmp_dir)."_".uc($type)."_MAIL.log";
                if ( not open (FD, ">>".$logfile) or
                     not print (FD "\n".$value) or
                     not close (FD)
                   )
                {
                    print addPreLogLine (i18nGettext ("__IMPORTFILE__ cannot be logged 
in __LOG_FILE__",
                                                      "__IMPORTFILE__", 
$directory."/".$value.".msg",
                                                      "__LOG_FILE__", $logfile));
                } else {
                    print addPreLogLine ($directory."/".$value.".msg");
                }
            }
        }
        print closeLogSection ();
    }

    ## perhaps I have to send the mails ?
    ## coded in mail-utils.lib
    if (getRequired ('SEND_MAIL_DURING_IMPORT') and
        (getRequired ('SEND_MAIL_DURING_IMPORT') !~ /^NO$/i)) {
        sendPreparedMails ("default");
        sendPreparedMails ("crin");
    }

    return 1;
}

###################################
## functions for batchprocessors ##
###################################

sub eximEnrollBP {

  my $exim_tmp_dir = $_[0];
  my $dir = $exim_tmp_dir."/batch";

  if ( not createDirectory ($dir) ) {
    return 0;
  }

  my $bp_dir    = getRequired ( 'BP_DIR' );

  print addLogSection(gettext ("Exporting the data from the batchprocessors ... "));
  mkdir $dir if (not -d $dir);
  my $ret = `cd $bp_dir; tar -cf - * | tar -xf - -C $dir 2>&1`;
  if( $? != 0 ) {
    print addErrorLog(i18nGettext ("Cannot copy __SRC_DIR__ to __DEST_DIR__!",
                                   "__SRC_DIR__", $bp_dir,
                                   "__DEST_DIR__", $dir));
    print addLogLine( "cd $bp_dir; tar -cf - * | tar -xf - -C $dir" );
    print closeLogSection ();
    return 0;
  }
  print addLogLine( gettext ("Ok.") );
  print closeLogSection ();

  return 1;
}

sub eximDownloadBP {

  my $exim_tmp_dir = $_[0];
  my $dir = $exim_tmp_dir."/batch";

  my $bp_dir    = getRequired ( 'BP_DIR'    );
 
  print addLogSection(gettext ("Importing the data from the batchprocessors ... "));
  my $ret = `cd $dir; tar -cf - * | tar -xf - -C $bp_dir 2>&1`;
  if( $? != 0 ) {
    print addErrorLog(i18nGettext ("Cannot copy __SRC_DIR__ to __DEST_DIR__!",
                                   "__SRC_DIR__", $dir,
                                   "__DEST_DIR__", $bp_dir));
    print addLogLine( "cd $dir; tar -cf - * | tar -xf - -C $bp_dir" );
    print closeLogSection ();
    return 0;
  }
  print addLogLine( gettext ("Ok.") );
  print closeLogSection ();

  return 1;
}

##########################################
## ldap import and export functionality ##
##########################################

sub eximObjectToLDAP {

  my $keys = { @_ };
 
  ## determine type of object
  if ( $keys->{CERTIFICATE} ) {
    ## create object in LDAP
    my $result = addLDAPobject ( CERTIFICATE => $keys->{CERTIFICATE} );
    if ( not $result or not $result->{STATUS} ) {
      return $result;
    }
    ## add attribute
    return addLDAPattribute ( CERTIFICATE => $keys->{CERTIFICATE},
                              NOPRINT     => 1 );
  } elsif ( $keys->{AUTHORITY_CERTIFICATE} ) {
    ## create object in LDAP
    my $result = addLDAPobject ( CERTIFICATE => $keys->{AUTHORITY_CERTIFICATE} );
    if ( not $result and not $result->{STATUS} ) {
      return $result;
    }
    ## add attribute
    return addLDAPattribute ( AUTHORITY_CERTIFICATE => $keys->{AUTHORITY_CERTIFICATE},
                              NOPRINT               => 1 );
  } elsif ( $keys->{CRL} ) {
    ## create object in LDAP is not necessary because it is the CA
    ## add attribute
    return addLDAPattribute ( CRL     => $keys->{CRL},
                              NOPRINT => 1 );
  } elsif ( $keys->{AUTHORITY_CRL} ) {
    ## create object in LDAP is not necessary because it is the CA
    ## add attribute
    return addLDAPattribute ( AUTHORITY_CRL => $keys->{AUTHORITY_CRL},
                              NOPRINT       => 1 );
  } else {
    return { STATUS => 0, CODE => -999, DESC => gettext ("No appropriate object 
specified.")};
  }
}

###########################
## export/import commits ##
###########################

## the higher level is at every time correct
## therefore we report all imported

## * there is only one certificate state which we must pass through
##   the hierarchy - valid
## * all other certificate states can be determined from requests
##   and timestamps
## * CRLs can only be valid
## * CA-certificates can only be valid and expired

## DIR - temporary directory
## ID  - ModuleID of other level

sub eximUploadCommit {

    my $keys = { @_ };

    return eximExportCommit (
               DIR => $_[0],
               MODE => "DOWNLOAD"
                            );
}

sub eximEnrollCommit {
    return eximExportCommit (
               DIR => $_[0],
               MODE => "RECEIVE"
                            );
}

sub eximExportCommit {
    my $keys = { @_ };
    my $tmpdir = $keys->{DIR};
    my $filter = uc($keys->{MODE});
    my $logdir  = getRequired ('LOG_'.$filter.'_DIR');
    my $logfiles;

    $tmpdir = $_[0] if (not $tmpdir);

    $logfiles = $logdir."/*.log";

    $tools->copyFiles (SRC => $logfiles, DEST => $tmpdir."/LOG/".$filter);
    eximSetModuleID ($tmpdir);
}

sub eximDownloadCommit {

    return eximImportCommit (
               DIR => $_[0],
               MODE => "UPLOAD"
                            );
}

sub eximReceiveCommit {

    return eximImportCommit (
               DIR => $_[0],
               MODE => "ENROLL"
                            );
}

sub eximImportCommit {
    my $keys = { @_ };
    my $tmpdir = $keys->{DIR};

    my $filter = eximGetModuleID ($tmpdir);

    my $mode = "DOWNLOAD";
    $mode = "RECEIVE" if ($keys->{MODE} !~ /ENROLL/);

    ## check for special rules in the configuration
    my @list = getRequiredList ('EXPORT_IMPORT_MODULES');
    my $special = 0;
    foreach my $item (@list)
    {
        $special = 1 if ($item == $filter);
    }

    ## check CRRs and CSRs
    foreach my $object ("CRR", "CSR", "CA_CERTIFICATE", "CERTIFICATE", "CRL", "MAIL")
    {
        next if ($object =~ /CA_CERTIFICATE/ and $keys->{MODE} =~ /UPLOAD/);
        next if ($object =~ /CERTIFICATE/    and $keys->{MODE} =~ /UPLOAD/);
        next if ($object =~ /CRL/            and $keys->{MODE} =~ /UPLOAD/);
        next if ($object =~ /MAIL/           and $keys->{MODE} =~ /UPLOAD/);

        ## check state
        my $config = $keys->{MODE}.'_'.$object.'_STATES';
        $config = $filter."_".$config if ($special);

        my @stateList = getRequiredList ($config);

        my $datatype = $object;
        $datatype = "REQUEST" if ($object =~ /CSR/);

        foreach my $state (@stateList)
        {
            ## load file
            $filename_org    = 
"$tmpdir/LOG/$mode/".getRequired('ModuleID')."_${state}_${datatype}.log";
            $filename_target = getRequired 
('LOG_'.$keys->{MODE}.'_DIR')."/${filter}_${state}_${datatype}.log";
            if (not $tools->copyFiles (SRC=> $filename_org, DEST => $filename_target))
            {
                ## blabla
            }
        }
    }
}

sub eximSetModuleID {
    my $tmpdir = $_[0];
    $tools->saveFile (FILENAME => $tmpdir."/module.id",
                      DATA     => getRequired ('ModuleID'));
}

sub eximGetModuleID {
    my $tmpdir = $_[0];
    $export_module = $tools->getFile ($tmpdir."/module.id");
    return $export_module;
}

sub eximGetStates {

    my $keys = { @_ };
    my @status;
    my $filter = "";

    $filter .= $keys->{MODE}."_".$keys->{DATATYPE}."_STATES";
    my $moduleID = eximGetModuleID ($tmpdir);

    ## check for special rules in the configuration
    my @list = getRequiredList ('EXPORT_IMPORT_MODULES');
    my $special = 0;
    foreach my $item (@list)
    {
        $special = 1 if ($item == $moduleID);
    }
    $filter = $moduleID."_".$config if ($special);

    return getRequiredList ($filter);
}

sub eximMustBeExported {
    my $keys = { @_ };
    my $datatype = $keys->{DATATYPE};
    my $mode     = uc($keys->{MODE});
    my $key      = $keys->{KEY};

    my $logdir = getRequired ('LOG_'.$mode.'_DIR');
    opendir DIR, $logdir;
    my @logfiles = grep /[0-9]*_$datatype\.log/, readdir DIR;
    closedir DIR;

    return 1 if (not scalar @logfiles);

    foreach my $file (@logfiles)
    {
        my $content = $tools->getFile ($logdir."/".$file);
        return 1 if ($content !~ /(\n$key\n|\n$key$|^$key\n|^$key$)/ );
    }

    return 0;
}

######################################
## full export/import functionality ##
######################################

sub withLDAPsupport {
  my $ldap = getRequired ('LDAP');

  if ( $ldap =~ /^(off|no)$/i ) {
    print addLogSection (gettext ("LDAP-support is deactivated"));
    print addLogLine ("");
    print closeLogSection ();
    return 0;
  } else {
    print addLogSection (gettext ("LDAP-support is activated"));
    print addLogLine ("");
    print closeLogSection ();
    return 1;
  }
}
    
sub withLDAPautomatic {
  my $ldap = getRequired ('updateLDAPautomatic');

  if ( $ldap =~ /^(off|no)$/i ) {
    print addLogSection ("Automatic LDAP-update is deactivated");
    print addLogLine ("");
    print closeLogSection ();
    return 0;
  } else {
    print addLogSection ("Automatic LDAP-update is activated");
    print addLogLine ("");
    print closeLogSection ();
    return 1;
  }
}
    
1;

Reply via email to