20080520 automated text backup of an ldap directory - plembo/onemoretech GitHub Wiki

title: Automated Text Backup of an LDAP Directory link: https://onemoretech.wordpress.com/2008/05/20/automated-text-backup-of-an-ldap-directory/ author: lembobro description: post_id: 527 created: 2008/05/20 19:38:35 created_gmt: 2008/05/20 19:38:35 comment_status: open post_name: automated-text-backup-of-an-ldap-directory status: publish post_type: post

Automated Text Backup of an LDAP Directory

This can be done lots of ways. What I normally do is write a small perl script that runs under the system user’s cron on the directory host itself. Having a daily (at least) backup of an LDAP directory’s entries is helpful not only in a full recovery scenario, but also for point restores of individual entries that might have been accidentally deleted.

The directory software vendor’s ldapsearch, or whatever ldapsearch comes with the system, can be used. There is sometimes a trick to this. For example, Oracle’s ldapsearch requires that $ORACLE_HOME be explicitly set for the executing user. As a result, this needs to be declared within any script executed under cron, since cron does not by default bring in the user’s own session variables during execution.

Here’s an example of what I’m talking about, first for a generic LDAP directory using the system’s ldapsearch, and next for the special case of an Oracle Internet Directory:

OpenLDAP Backup

`

#!/usr/bin/perl
# bakldap.pl Backs up LDAP directory to LDIF file to allow
#  restore of lost entries.
my($dirHost,$dirUsr,$dirPass);
require "/etc/buapp.conf";
my $ENVIRON = "prod";
my $domain = "dc=example,dc=com";
my $query = "(objectclass=*)";
my $errfile = "/var/log/bakldap.log";
my $bakdir = "/export/backup";
#
open LOGZ, ">$errfile" or die $!;
#
my $timestamp = localtime();
print LOGZ "$timestamptBegin LDIF backup of $dirHost LDAPn";
#
do_backup();
cleanup();
#
close LOGZ;
#
sub do_backup {
#
 my %backups = ("$bakdir/$ENVIRON-ldapdse.ldif.$today","",
	   "$bakdir/$ENVIRON-ldapdit.ldif.$today","$realm",
	   "$bakdir/$ENVIRON-ldapusr.ldif.$today","ou=People,$realm",
	   "$bakdir/$ENVIRON-ldapgrp.ldif.$today","ou=Groups,$realm"
			);
#
 while ( my ($file, $container ) = each(%backups) ) {
#
	print LOGZ "tBacking up $containern";
#
	my $result = system("$OH/bin/ldapsearch -x -LLL -h $dirHost
-D "$dirUsr" -w $dirPass -b "$container" -s sub "$query" >$file");
#
	print LOGZ "$result";
#
 }
#
}
#
sub cleanup {
#
 opendir(DIR,"$bakdir") or die "Can't open directory: $!n";
 my @files = readdir DIR;
 closedir DIR;
#
 chdir($bakdir);
#
 for my $file(@files) {
#
   print LOGZ "tchecking $filen";
	if (-M $file > 10) {
	    print LOGZ "tDeleting $file in $dirn";
	    unlink($file);
#
	}
  }
}
__END__;

`

Oracle Internet Directory Backup:

`

#!/usr/bin/perl
# bakloid.pl Backs up OID directory to LDIF file to allow
# restore of lost entries.
my $HOME = $ENV{'HOME'};
#
our($porclhost,$orclUsr,$porclpass,$today);
require "/etc/buapp.conf";
#
my $oidHost = $porclhost;
my $oidPass = $porclpass;
my $ENVIRON = "prod";
my $realm = "dc=example,dc=com";
my $query = "(objectclass=*)";
my $errfile = "$HOME/logs/bakoid.log";
my $OH = "/u01/app/oracle/product/oid";
$ENV{'ORACLE_HOME'} = $OH;
my $bakdir = "/u01/app/oracle/backup";
#
open LOGZ, ">$errfile" or die $!;
#
my $timestamp = localtime();
print LOGZ "$timestamptBegin LDIF backup of $oidHost OIDn";
#
do_backup();
cleanup();
#
close LOGZ;
#
sub do_backup {
#
 my %backups = ("$bakdir/$ENVIRON-oidall.ldif.$today","",
	   "$bakdir/$ENVIRON-oidarw.ldif.$today","$realm",
	   "$bakdir/$ENVIRON-oidusr.ldif.$today","cn=Users,$realm",
	   "$bakdir/$ENVIRON-oidgrp.ldif.$today","cn=Groups,$realm"
		);
#
 while ( my ($file, $container ) = each(%backups) ) {
#
	print LOGZ "tBacking up $containern";
#
        my $result = system("$OH/bin/ldapsearch -L -h $oidHost
-D "$oidUsr" -w $oidPass -b "$container" -s sub "$query" >$file");
#
	print LOGZ "$result";
#
 }
#
}
#
sub cleanup {
#
 opendir(DIR,"$bakdir") or die "Can't open directory: $!n";
 my @files = readdir DIR;
 closedir DIR;
#
 chdir($bakdir);
#
 for my $file(@files) {
#
   print LOGZ "tchecking $filen";
	if (-M $file > 10) {
	    print LOGZ "tDeleting $file in $dirn";
	    unlink($file);
#
	}
  }
}
__END__;

`

Notice that in each case I’ve established a backup directory/folder to store the files and also use a config file for values like host names and passwords. The former should be located someplace it’s easy to find. In this case I’ve chosen to locate it on a separate volume as /export/backup for the generic script (the OpenLDAP database is found under /var/lib/ldap), while the script for Oracle goes to /u01/app/oracle/backup (the database for OID is normally located on a completely separate host).

Using a config file helps secure sensitive data like passwords while allowing the main script to be readable by all for troubleshooting purposes. It also permits you to standardize the script and drive host-by-host changes through the config file — which is where configuration info belongs.

Oh yes, and as an added bonus I’ve thrown in a subroutine that automatically deletes any backups that are 10 days old or more.

Copyright 2004-2019 Phil Lembo