Alexey Chetroi wrote:

As soon as I try to export the certs from the CA, "Enroll data to
lower level of hierarchy", I get the following message:

Error 700
General Error. Database failed with errorcode 2162021.
OpenCA::DB->getNextItem: Cannot
open database (2141013) OpenCA::DB->dbOpen: No status specified..

This occurred immediately following the display of "Exporting
Mails..." on the web page.
I'm experiencing the same problem on Debian Woody. Could anybody
give us any hints?
....

Yes, you're right. That's why I've modified ca_node.conf and ra_node.conf
export/import sesctions and changed /dev/fd0 to /tmp/somefile, but also
has this problem. In my test setup I've installed ca and ra/pub components in different directories on the same machine.
Could you please compare the attached version of export-import.lib with the one in src/common/lib/functions/export-import.lib?

I find a bug for exporting mails in 0.9.1 shortly before the release. There is one additional line in the function eximEnrollMails. This line checks the result of a function ($type should exist to run the loop). The fixed version is correctly tagged but perhaps I released an old version.

Sorry 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 ("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