Author: nhosoi
Update of /cvs/dirsec/ldapserver/ldap/admin/src/scripts In directory cvs-int.fedora.redhat.com:/tmp/cvs-serv5158/ldap/admin/src/scripts
Modified Files: template-cl-dump.pl template-ns-newpwpolicy.pl template-repl-monitor-cgi.pl template-verify-db.pl Added Files: template-bak2db.pl.in template-cl-dump.pl.in template-db2bak.pl.in template-db2index.pl.in template-db2ldif.pl.in template-ldif2db.pl.in template-ns-accountstatus.pl.in template-ns-activate.pl.in template-ns-inactivate.pl.in template-ns-newpwpolicy.pl.in template-repl-monitor-cgi.pl.in template-repl-monitor.pl.in template-verify-db.pl.in Log Message: Resolves: #212098 Summary: Use autoconf to generate task perl script templates Changes: 1) added template files to AC_CONFIG_FILES list 2) added db_bindir and ldapsdk_bindir to pass their tools path to the template files. The paths are hardcoded for now.
--- NEW FILE template-bak2db.pl.in --- #{{PERL-EXEC}} # # BEGIN COPYRIGHT BLOCK # This Program is free software; you can redistribute it and/or modify it under # the terms of the GNU General Public License as published by the Free Software # Foundation; version 2 of the License. # # This Program is distributed in the hope that it will be useful, but WITHOUT # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS # FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. # # You should have received a copy of the GNU General Public License along with # this Program; if not, write to the Free Software Foundation, Inc., 59 Temple # Place, Suite 330, Boston, MA 02111-1307 USA. # # In addition, as a special exception, Red Hat, Inc. gives You the additional # right to link the code of this Program with code not covered under the GNU # General Public License ("Non-GPL Code") and to distribute linked combinations # including the two, subject to the limitations in this paragraph. Non-GPL Code # permitted under this exception must only link to the code of this Program # through those well defined interfaces identified in the file named EXCEPTION # found in the source code files (the "Approved Interfaces"). The files of # Non-GPL Code may instantiate templates or use macros or inline functions from # the Approved Interfaces without causing the resulting work to be covered by # the GNU General Public License. Only Red Hat, Inc. may make changes or # additions to the list of Approved Interfaces. You must obey the GNU General # Public License in all respects for all of the Program code and other code used # in conjunction with the Program except the Non-GPL Code covered by this # exception. If you modify this file, you may extend this exception to your # version of the file, but you are not obligated to do so. If you do not wish to # provide this exception without modification, you must delete this exception # statement from your version and license this file solely under the GPL without # exception. # # # Copyright (C) 2001 Sun Microsystems, Inc. Used by permission. # Copyright (C) 2005 Red Hat, Inc. # All rights reserved. # END COPYRIGHT BLOCK #
sub usage { print(STDERR "Usage: $0 [-v] -D rootdn { -w password | -w - | -j filename } \n"); print(STDERR " : -a dirname [-t dbtype]\n"); print(STDERR " Opts: -D rootdn - Directory Manager\n"); print(STDERR " : -w password - Directory Manager's password\n"); print(STDERR " : -w - - Prompt for Directory Manager's password\n"); print(STDERR " : -j filename - Read Directory Manager's password from file\n"); print(STDERR " : -a dirname - backup directory\n"); print(STDERR " : -t dbtype - database type (default: ldbm database)\n"); print(STDERR " : -n backend - name of backend instance to restore\n"); print(STDERR " : -v - verbose\n"); } $taskname = ""; $archivedir = ""; $dbtype = "ldbm database"; $instance = ""; $prefix = "{{DS-ROOT}}"; $verbose = 0; $rootdn = ""; $passwd = ""; $passwdfile = ""; $i = 0; while ($i <= $#ARGV) { if ("$ARGV[$i]" eq "-a") { # backup directory $i++; $archivedir = $ARGV[$i]; } elsif ("$ARGV[$i]" eq "-D") { # Directory Manager $i++; $rootdn = $ARGV[$i]; } elsif ("$ARGV[$i]" eq "-w") { # Directory Manager's password $i++; $passwd = $ARGV[$i]; } elsif ("$ARGV[$i]" eq "-j") { # Read Directory Manager's password from a file $i++; $passwdfile = $ARGV[$i]; } elsif ("$ARGV[$i]" eq "-t") { # database type $i++; $dbtype = $ARGV[$i]; } elsif ("$ARGV[$i]" eq "-n") { # backend instance name $i++; $instance = $ARGV[$i]; } elsif ("$ARGV[$i]" eq "-v") { # verbose $verbose = 1; } else { &usage; exit(1); } $i++; } if ($passwdfile ne ""){ # Open file and get the password unless (open (RPASS, $passwdfile)) { die "Error, cannot open password file $passwdfile\n"; } $passwd = <RPASS>; chomp($passwd); close(RPASS); } elsif ($passwd eq "-"){ # Read the password from terminal die "The '-w -' option requires an extension library (Term::ReadKey) which is not\n", "part of the standard perl distribution. If you want to use it, you must\n", "download and install the module. You can find it at\n", "http://www.perl.com/CPAN/CPAN.html%5Cn"; # Remove the previous line and uncomment the following 6 lines once you have installed Term::ReadKey module. # use Term::ReadKey; # print "Bind Password: "; # ReadMode('noecho'); # $passwd = ReadLine(0); # chomp($passwd); # ReadMode('normal'); } if ( $rootdn eq "" || $passwd eq "") { &usage; exit(1); } ($s, $m, $h, $dy, $mn, $yr, $wdy, $ydy, $r) = localtime(time); $mn++; $yr += 1900; $taskname = "restore_${yr}_${mn}_${dy}_${h}_${m}_${s}"; if ($archivedir eq "") { &usage; exit(1); } use File::Spec; $isabs = File::Spec->file_name_is_absolute( $archivedir ); if (!$isabs) { $archivedir = File::Spec->rel2abs( $archivedir ); } $dn = "dn: cn=$taskname, cn=restore, cn=tasks, cn=config\n"; $misc = "changetype: add\nobjectclass: top\nobjectclass: extensibleObject\n"; $cn = "cn: $taskname\n"; if ($instance ne "") { $nsinstance = "nsInstance: ${instance}\n"; } $nsarchivedir = "nsArchiveDir: $archivedir\n"; $nsdbtype = "nsDatabaseType: $dbtype\n"; $entry = "${dn}${misc}${cn}${nsinstance}${nsarchivedir}${nsdbtype}"; $vstr = ""; if ($verbose != 0) { $vstr = "-v"; } $ENV{'PATH'} = '$prefix@ldapsdk_bindir@:$prefix/usr/lib:@ldapsdk_bindir@:/usr/lib'; $ENV{'LD_LIBRARY_PATH'} = '$prefix@nss_libdir@:$prefix/usr/lib:@nss_libdir@:/usr/lib'; $ENV{'SHLIB_PATH'} = '$prefix@nss_libdir@:$prefix/usr/lib:@nss_libdir@:/usr/lib'; open(FOO, "| ldapmodify $vstr -h {{SERVER-NAME}} -p {{SERVER-PORT}} -D "$rootdn" -w "$passwd" -a" ); print(FOO "$entry"); close(FOO);
--- NEW FILE template-cl-dump.pl.in --- #{{PERL-EXEC}} # BEGIN COPYRIGHT BLOCK # This Program is free software; you can redistribute it and/or modify it under # the terms of the GNU General Public License as published by the Free Software # Foundation; version 2 of the License. # # This Program is distributed in the hope that it will be useful, but WITHOUT # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS # FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. # # You should have received a copy of the GNU General Public License along with # this Program; if not, write to the Free Software Foundation, Inc., 59 Temple # Place, Suite 330, Boston, MA 02111-1307 USA. # # In addition, as a special exception, Red Hat, Inc. gives You the additional # right to link the code of this Program with code not covered under the GNU # General Public License ("Non-GPL Code") and to distribute linked combinations # including the two, subject to the limitations in this paragraph. Non-GPL Code # permitted under this exception must only link to the code of this Program # through those well defined interfaces identified in the file named EXCEPTION # found in the source code files (the "Approved Interfaces"). The files of # Non-GPL Code may instantiate templates or use macros or inline functions from # the Approved Interfaces without causing the resulting work to be covered by # the GNU General Public License. Only Red Hat, Inc. may make changes or # additions to the list of Approved Interfaces. You must obey the GNU General # Public License in all respects for all of the Program code and other code used # in conjunction with the Program except the Non-GPL Code covered by this # exception. If you modify this file, you may extend this exception to your # version of the file, but you are not obligated to do so. If you do not wish to # provide this exception without modification, you must delete this exception # statement from your version and license this file solely under the GPL without # exception. # # # Copyright (C) 2001 Sun Microsystems, Inc. Used by permission. # Copyright (C) 2005 Red Hat, Inc. # All rights reserved. # END COPYRIGHT BLOCK ################################################################################### # # FILE: cl-dump.pl # # SYNOPSIS: # # cl-dump.pl [-h host] [-p port] [-D bind-dn] -w bind-password | -P bind-cert\ # [-r replica-roots] [-o output-file] [-c] [-v]\n"; # # cl-dump.pl -i changelog-ldif-file-with-base64encoding [-o output-file] [-c]\n"; # # DESCRIPTION: # Dump and decode Directory Server replication change log # # OPTIONS: # # -c Dump and interpret CSN only. This option can be used with or # without -i option. # # -D bind-dn # Directory server's bind DN. Default to "cn=Directory Manager" if # the option is omitted. # # -h host # Directory server's host. Default to the server where the script # is running. # # -i changelog-ldif-file-with-base64encoding # If you already have a ldif-like changelog, but the changes # in that file are encoded, you may use this option to # decode that ldif-like changelog. # # -o output-file # Path name for the final result. Default to STDOUT if omitted. # # -p port # Directory server's port. Default to 389. # # -P bind-cert # Pathname of binding certificate DB # # -r replica-roots # Specify replica roots whose changelog you want to dump. The replica # roots may be seperated by comma. All the replica roots would be # dumped if the option is omitted. # # -v Print the version of this script. # # -w bind-password # Password for the bind DN # # RESTRICTION: # If you are not using -i option, the script should be run when the server # is running, and from where the server's changelog directory is accessible. # # DIAGNOSIS: # For environment variable issues, see script template-repl-monitor.pl under # DSHOME/bin/slapd/admin/scripts # ################################################################################ # enable the use of our bundled perldap with our bundled ldapsdk libraries # all of this nonsense can be omitted if the mozldapsdk and perldap are # installed in the operating system locations (e.g. /usr/lib /usr/lib/perl5) $prefix = "{{DS-ROOT}}";
$ENV{'LD_LIBRARY_PATH'} = '$prefix@nss_libdir@:$prefix/usr/lib:@nss_libdir@:/usr/lib'; $ENV{'SHLIB_PATH'} = '$prefix@nss_libdir@:$prefix/usr/lib:@nss_libdir@:/usr/lib';
$usage="Usage: $0 [-h host] [-p port] [-D bind-dn] [-w bind-password | -P bind-cert] [-r replica-roots] [-o output-file] [-c] [-v]\n\n $0 -i changelog-ldif-file-with-base64encoding [-o output-file] [-c]";
use Getopt::Std; # Parse command line arguments use Mozilla::LDAP::Conn; # LDAP module for Perl use Mozilla::LDAP::Utils; # LULU, utilities. use Mozilla::LDAP::API; # Used to parse LDAP URL use MIME::Base64; # Decode
# Global variables
$version = "Directory Server Changelog Dump - Version 1.0";
#main { # Turn off buffered I/O $| = 1;
# Check for legal options if (!getopts('h:p:D:w:P:r:o:cvi:')) { print $usage; exit -1; }
exit -1 if &validateArgs;
if ($opt_v) { print OUTPUT "$version\n"; exit; }
if (!$opt_i) { &cl_dump_and_decode; } elsif ($opt_c) { &grep_csn ($opt_i); } else { &cl_decode ($opt_i); }
close (OUTPUT); }
# Validate the parameters sub validateArgs { my ($rc) = 0;
%ld = Mozilla::LDAP::Utils::ldapArgs(); chop ($ld{host} = `hostname`) if !$opt_h; $ld{bind} = "cn=Directory Manager" if !$opt_D; @allreplicas = ($opt_r) if ($opt_r); if ($opt_o && ! open (OUTPUT, ">$opt_o")) { print "Can't create output file $opt_o\n"; $rc = -1; } # Open STDOUT if option -o is missing open (OUTPUT, ">-") if !$opt_o;
return $rc; }
# Dump and decode changelog # OUTPUT should have been opened before this call sub cl_dump_and_decode { # Open the connection my ($conn) = new Mozilla::LDAP::Conn (%ld); if (!$conn) { print OUTPUT qq/Can't connect to $ld{host}:$ld{port} as "$ld{bind}"\n/; return -1; }
# Get the changelog dir my ($changelogdir); my ($entry) = $conn->search ("cn=changelog5,cn=config", "sub", "(objectClass=*)"); while ($entry) { $changelogdir = $entry->{"nsslapd-changelogdir"}[0]; last if $changelogdir; $entry = $conn->nextEntry (); }
# Get all the replicas on the server if -r option is not specified if (!$opt_r) { $entry = $conn->search ("cn=mapping tree,cn=config", "sub", "(objectClass=nsDS5Replica)"); while ($entry) { push (@allreplicas, "$entry->{nsDS5ReplicaRoot}[0]"); $entry = $conn->nextEntry (); } }
# Dump the changelog for the replica my (@ldifs); my ($replica); my ($gotldif); my ($ldif); foreach (@allreplicas) { # Reset the script's start time $^T = time;
$replica = $_; $gotldif = 0;
# Can't move this line before entering the loop: # no ldif file generated other than for the first # replica. $entry = $conn->newEntry(); $entry->setDN ("cn=replica,cn="$_",cn=mapping tree,cn=config"); $entry->setValues('nsDS5Task', 'CL2LDIF'); $conn->update ($entry);
#Decode the dumped changelog @ldifs = <$changelogdir/*.ldif>; foreach (@ldifs) { # Skip older ldif files next if ($#ldifs > 0 && (-M $_ > 0)); $ldif = $_; $gotldif = 1; &print_header ($replica, 0); if ($opt_c) { &grep_csn ($_); } else { &cl_decode ($_); } # Test op -M doesn't work well so we use rename # here to avoid reading the same ldif file more # than once. rename ($ldif, "$ldif.done"); } &print_header ($replica, "Not Found") if !$gotldif; } $conn->close; }
sub print_header { my ($replica, $ldif) = @_; print OUTPUT "\n# Replica Root: $replica" if $replica; print OUTPUT "\n# LDIF File : $ldif\n" if $ldif; }
# Grep and interpret CSNs # OUTPUT should have been opened before this call sub grep_csn { open (INPUT, "@_") || return; &print_header (0, @_);
my ($csn, $maxcsn, $modts); while (<INPUT>) { next if ($_ !~ /(csn:)|(ruv:)/i); if (/ruv:\s*{.+}\s+(\w+)\s+(\w+)\s+(\w*)/i) { # # RUV with two CSNs and an optional lastModifiedTime # $csn = &csn_to_string($1); $maxcsn = &csn_to_string($2); $modts = $3; if ( $modts =~ /^0+$/ ) { $modts = ""; } else { $modts = &csn_to_string($modts); } } elsif (/csn:\s*(\w+)\s+/i || /ruv:\s*{.+}\s+(\w+)\s+/i) { # # Single CSN # $csn = &csn_to_string($1); $maxcsn = ""; $modts = ""; } else { printf OUTPUT; next; } chop; printf OUTPUT "$_ ($csn"; printf OUTPUT "; $maxcsn" if $maxcsn; printf OUTPUT "; $modts" if $modts; printf OUTPUT ")\n"; } }
sub csn_to_string { my ($csn, $tm, $seq, $masterid, $subseq); my ($sec, $min, $hour, $mday, $mon, $year);
$csn = "@_"; return $csn if !$csn;
($tm, $seq, $masterid, $subseq) = unpack("a8 a4 a4 a4", $csn); $tm = hex($tm); $seq = hex($seq); $masterid = hex($masterid); $subseq = hex($subseq); ($sec, $min, $hour, $mday, $mon, $year) = localtime ($tm); $mon++; $year += 1900; foreach ($sec, $min, $hour, $mday, $mon) { $_ = "0".$_ if ($_ < 10); } $csn = "$mon/$mday/$year $hour:$min:$sec"; $csn .= " $seq $subseq" if ( $seq != 0 || $subseq != 0 );
return $csn; }
# Decode the changelog # OUTPUT should have been opened before this call sub cl_decode { open (INPUT, "@_") || return; &print_header (0, @_);
my ($encoded); undef $encoded; while (<INPUT>) { # Try to accomodate "changes" in 4.X and "change" in 6.X if (/^changes?::\s*(\S*)/i) { print OUTPUT "change::\n"; $encoded = $1; next; } if (!defined ($encoded)) { print OUTPUT; next; } if ($_ eq "\n") { print OUTPUT MIME::Base64::decode($encoded); print OUTPUT "\n"; undef $encoded; next; } /^\s*(\S+)\s*\n/; $encoded .= $1; } }
--- NEW FILE template-db2bak.pl.in --- #{{PERL-EXEC}} # # BEGIN COPYRIGHT BLOCK # This Program is free software; you can redistribute it and/or modify it under # the terms of the GNU General Public License as published by the Free Software # Foundation; version 2 of the License. # # This Program is distributed in the hope that it will be useful, but WITHOUT # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS # FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. # # You should have received a copy of the GNU General Public License along with # this Program; if not, write to the Free Software Foundation, Inc., 59 Temple # Place, Suite 330, Boston, MA 02111-1307 USA. # # In addition, as a special exception, Red Hat, Inc. gives You the additional # right to link the code of this Program with code not covered under the GNU # General Public License ("Non-GPL Code") and to distribute linked combinations # including the two, subject to the limitations in this paragraph. Non-GPL Code # permitted under this exception must only link to the code of this Program # through those well defined interfaces identified in the file named EXCEPTION # found in the source code files (the "Approved Interfaces"). The files of # Non-GPL Code may instantiate templates or use macros or inline functions from # the Approved Interfaces without causing the resulting work to be covered by # the GNU General Public License. Only Red Hat, Inc. may make changes or # additions to the list of Approved Interfaces. You must obey the GNU General # Public License in all respects for all of the Program code and other code used # in conjunction with the Program except the Non-GPL Code covered by this # exception. If you modify this file, you may extend this exception to your # version of the file, but you are not obligated to do so. If you do not wish to # provide this exception without modification, you must delete this exception # statement from your version and license this file solely under the GPL without # exception. # # # Copyright (C) 2001 Sun Microsystems, Inc. Used by permission. # Copyright (C) 2005 Red Hat, Inc. # All rights reserved. # END COPYRIGHT BLOCK #
sub usage { print(STDERR "Usage: $0 [-v] -D rootdn { -w password | -w - | -j filename } \n"); print(STDERR " [-a dirname] [-t dbtype]\n"); print(STDERR " Opts: -D rootdn - Directory Manager\n"); print(STDERR " : -w password - Directory Manager's password\n"); print(STDERR " : -w - - Prompt for Directory Manager's password\n"); print(STDERR " : -j filename - Read Directory Manager's password from file\n"); print(STDERR " : -a dirname - backup directory\n"); print(STDERR " : -t dbtype - database type (default: ldbm database)\n"); print(STDERR " : -v - verbose\n"); } $taskname = ""; $archivedir = ""; $dbtype = "ldbm database"; $prefix = "{{DS-ROOT}}"; $mybakdir = "{{BAK-DIR}}"; $verbose = 0; $rootdn = ""; $passwd = ""; $passwdfile = ""; $i = 0; while ($i <= $#ARGV) { if ("$ARGV[$i]" eq "-a") { # backup directory $i++; $archivedir = $ARGV[$i]; } elsif ("$ARGV[$i]" eq "-D") { # Directory Manager $i++; $rootdn = $ARGV[$i]; } elsif ("$ARGV[$i]" eq "-w") { # Directory Manager's password $i++; $passwd = $ARGV[$i]; } elsif ("$ARGV[$i]" eq "-j") { # Read Directory Manager's password from a file $i++; $passwdfile = $ARGV[$i]; } elsif ("$ARGV[$i]" eq "-t") { # database type $i++; $dbtype = $ARGV[$i]; } elsif ("$ARGV[$i]" eq "-v") { # verbose $verbose = 1; } else { &usage; exit(1); } $i++; } if ($passwdfile ne ""){ # Open file and get the password unless (open (RPASS, $passwdfile)) { die "Error, cannot open password file $passwdfile\n"; } $passwd = <RPASS>; chomp($passwd); close(RPASS); } elsif ($passwd eq "-"){ # Read the password from terminal die "The '-w -' option requires an extension library (Term::ReadKey) which is not\n", "part of the standard perl distribution. If you want to use it, you must\n", "download and install the module. You can find it at\n", "http://www.perl.com/CPAN/CPAN.html%5Cn"; # Remove the previous line and uncomment the following 6 lines once you have installed Term::ReadKey module. # use Term::ReadKey; # print "Bind Password: "; # ReadMode('noecho'); # $passwd = ReadLine(0); # chomp($passwd); # ReadMode('normal'); } if ( $rootdn eq "" || $passwd eq "") { &usage; exit(1); } ($s, $m, $h, $dy, $mn, $yr, $wdy, $ydy, $r) = localtime(time); $mn++; $yr += 1900; $taskname = "backup_${yr}_${mn}_${dy}_${h}_${m}_${s}"; if ($archivedir eq "") { $archivedir = "${bakdir}{{SEP}}bak{{SEP}}${yr}_${mn}_${dy}_${h}_${m}_${s}"; } $dn = "dn: cn=$taskname, cn=backup, cn=tasks, cn=config\n"; $misc = "changetype: add\nobjectclass: top\nobjectclass: extensibleObject\n"; $cn = "cn: $taskname\n"; $nsarchivedir = "nsArchiveDir: $archivedir\n"; $nsdbtype = "nsDatabaseType: $dbtype\n"; $entry = "${dn}${misc}${cn}${nsarchivedir}${nsdbtype}"; $vstr = ""; if ($verbose != 0) { $vstr = "-v"; } $ENV{'PATH'} = '$prefix@ldapsdk_bindir@:$prefix/usr/lib:@ldapsdk_bindir@:/usr/lib'; $ENV{'LD_LIBRARY_PATH'} = '$prefix@nss_libdir@:$prefix/usr/lib:@nss_libdir@:/usr/lib'; $ENV{'SHLIB_PATH'} = '$prefix@nss_libdir@:$prefix/usr/lib:@nss_libdir@:/usr/lib'; open(FOO, "| ldapmodify $vstr -h {{SERVER-NAME}} -p {{SERVER-PORT}} -D "$rootdn" -w "$passwd" -a" ); print(FOO "$entry"); close(FOO);
--- NEW FILE template-db2index.pl.in --- #{{PERL-EXEC}} # # BEGIN COPYRIGHT BLOCK # This Program is free software; you can redistribute it and/or modify it under # the terms of the GNU General Public License as published by the Free Software # Foundation; version 2 of the License. # # This Program is distributed in the hope that it will be useful, but WITHOUT # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS # FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. # # You should have received a copy of the GNU General Public License along with # this Program; if not, write to the Free Software Foundation, Inc., 59 Temple # Place, Suite 330, Boston, MA 02111-1307 USA. # # In addition, as a special exception, Red Hat, Inc. gives You the additional # right to link the code of this Program with code not covered under the GNU # General Public License ("Non-GPL Code") and to distribute linked combinations # including the two, subject to the limitations in this paragraph. Non-GPL Code # permitted under this exception must only link to the code of this Program # through those well defined interfaces identified in the file named EXCEPTION # found in the source code files (the "Approved Interfaces"). The files of # Non-GPL Code may instantiate templates or use macros or inline functions from # the Approved Interfaces without causing the resulting work to be covered by # the GNU General Public License. Only Red Hat, Inc. may make changes or # additions to the list of Approved Interfaces. You must obey the GNU General # Public License in all respects for all of the Program code and other code used # in conjunction with the Program except the Non-GPL Code covered by this # exception. If you modify this file, you may extend this exception to your # version of the file, but you are not obligated to do so. If you do not wish to # provide this exception without modification, you must delete this exception # statement from your version and license this file solely under the GPL without # exception. # # # Copyright (C) 2001 Sun Microsystems, Inc. Used by permission. # Copyright (C) 2005 Red Hat, Inc. # All rights reserved. # END COPYRIGHT BLOCK #
sub usage { print(STDERR "Usage: $0 [-v] -D rootdn { -w password | -w - | -j filename } \n"); print(STDERR " -n instance [-t attributeName[:indextypes[:matchingrules]]]\n"); print(STDERR " Opts: -D rootdn - Directory Manager\n"); print(STDERR " : -w password - Directory Manager's password\n"); print(STDERR " : -w - - Prompt for Directory Manager's password\n"); print(STDERR " : -j filename - Read Directory Manager's password from file\n"); print(STDERR " : -n instance - instance to be indexed\n"); print(STDERR " : -t attributeName[:indextypes[:matchingrules]]\n"); print(STDERR " - attribute: name of the attribute to be indexed\n"); print(STDERR " If omitted, all the indexes defined \n"); print(STDERR " for that instance are generated.\n"); print(STDERR " - indextypes: comma separated index types\n"); print(STDERR " - matchingrules: comma separated matrules\n"); print(STDERR " Example: -t foo:eq,pres\n"); print(STDERR " : -v - verbose\n"); }
$instance = ""; $rootdn = ""; $passwd = ""; $passwdfile = ""; $attribute_arg = ""; $vlvattribute_arg = ""; $verbose = 0;
$prefix = "{{DS-ROOT}}";
$ENV{'PATH'} = '$prefix@ldapsdk_bindir@:$prefix/usr/lib:@ldapsdk_bindir@:/usr/lib'; $ENV{'LD_LIBRARY_PATH'} = '$prefix@nss_libdir@:$prefix/usr/lib:@nss_libdir@:/usr/lib'; $ENV{'SHLIB_PATH'} = '$prefix@nss_libdir@:$prefix/usr/lib:@nss_libdir@:/usr/lib';
$i = 0; while ($i <= $#ARGV) { if ("$ARGV[$i]" eq "-n") { # instance $i++; $instance = $ARGV[$i]; } elsif ("$ARGV[$i]" eq "-D") { # Directory Manager $i++; $rootdn = $ARGV[$i]; } elsif ("$ARGV[$i]" eq "-w") { # Directory Manager's password $i++; $passwd = $ARGV[$i]; } elsif ("$ARGV[$i]" eq "-j") { # Read Directory Manager's password from a file $i++; $passwdfile = $ARGV[$i]; } elsif ("$ARGV[$i]" eq "-t") { # Attribute to index $i++; $attribute_arg = $ARGV[$i]; } elsif ("$ARGV[$i]" eq "-T") { # Vlvattribute to index $i++; $vlvattribute_arg = $ARGV[$i]; } elsif ("$ARGV[$i]" eq "-v") { # verbose $verbose = 1; } else { &usage; exit(1); } $i++; }
if ($passwdfile ne ""){ # Open file and get the password unless (open (RPASS, $passwdfile)) { die "Error, cannot open password file $passwdfile\n"; } $passwd = <RPASS>; chomp($passwd); close(RPASS); } elsif ($passwd eq "-"){ # Read the password from terminal die "The '-w -' option requires an extension library (Term::ReadKey) which is not\n", "part of the standard perl distribution. If you want to use it, you must\n", "download and install the module. You can find it at\n", "http://www.perl.com/CPAN/CPAN.html%5Cn"; # Remove the previous line and uncomment the following 6 lines once you have installed Term::ReadKey module. # use Term::ReadKey; # print "Bind Password: "; # ReadMode('noecho'); # $passwd = ReadLine(0); # chomp($passwd); # ReadMode('normal'); }
if ( $rootdn eq "" || $passwd eq "" ) { &usage; exit(1); }
$vstr = ""; if ($verbose != 0) { $vstr = "-v"; }
($s, $m, $h, $dy, $mn, $yr, $wdy, $ydy, $r) = localtime(time); $mn++; $yr += 1900; $taskname = "db2index_${yr}_${mn}_${dy}_${h}_${m}_${s}";
if ( $instance eq "" ) { &usage; exit(1); }
# No attribute name has been specified: let's get them from the configuration $attribute=""; $indexes_list=""; $vlvattribute=""; $vlvindexes_list=""; chdir("$prefix{{SEP}}usr{{SEP}}bin"); if ( $attribute_arg eq "" && $vlvattribute_arg eq "" ) { # Get the list of indexes from the entry $indexes_list="ldapsearch $vstr -h {{SERVER-NAME}} -p {{SERVER-PORT}} -D "$rootdn" -w "$passwd" -s one " . "-b "cn=index,cn="$instance", cn=ldbm database,cn=plugins,cn=config" "(&(objectclass=*)(nsSystemIndex=false))" cn"; # build the values of the attribute nsIndexAttribute open(LDAP1, "$indexes_list |"); while (<LDAP1>) { s/\n //g; if (/^cn: (.*)\n/) { $IndexAttribute="nsIndexAttribute"; $attribute="$attribute$IndexAttribute: $1\n"; } } close(LDAP1); if ( $attribute eq "" ) { # No attribute to index, just exit exit(0); }
# Get the list of indexes from the entry $vlvindexes_list="ldapsearch $vstr -h {{SERVER-NAME}} -p {{SERVER-PORT}} -D "$rootdn" -w "$passwd" -s sub -b "cn="$instance", cn=ldbm database,cn=plugins,cn=config" "objectclass=vlvIndex" cn";
# build the values of the attribute nsIndexVlvAttribute open(LDAP1, "$vlvindexes_list |"); while (<LDAP1>) { s/\n //g; if (/^cn: (.*)\n/) { $vlvIndexAttribute="nsIndexVlvAttribute"; $vlvattribute="$vlvattribute$vlvIndexAttribute: $1\n"; } } close(LDAP1); } else { if ( $attribute_arg ne "" ) { $attribute="nsIndexAttribute: $attribute_arg\n"; } if ( $vlvattribute_arg ne "" ) { $vlvattribute="nsIndexVlvAttribute: $vlvattribute_arg\n"; } }
# Build the task entry to add
$dn = "dn: cn=$taskname, cn=index, cn=tasks, cn=config\n"; $misc = "changetype: add\nobjectclass: top\nobjectclass: extensibleObject\n"; $cn = "cn: $taskname\n"; $nsinstance = "nsInstance: ${instance}\n";
$entry = "${dn}${misc}${cn}${nsinstance}${attribute}${vlvattribute}"; open(FOO, "| ldapmodify $vstr -h {{SERVER-NAME}} -p {{SERVER-PORT}} -D "$rootdn" -w "$passwd" -a" ); print(FOO "$entry"); close(FOO);
--- NEW FILE template-db2ldif.pl.in --- #{{PERL-EXEC}} # # BEGIN COPYRIGHT BLOCK # This Program is free software; you can redistribute it and/or modify it under # the terms of the GNU General Public License as published by the Free Software # Foundation; version 2 of the License. # # This Program is distributed in the hope that it will be useful, but WITHOUT # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS # FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. # # You should have received a copy of the GNU General Public License along with # this Program; if not, write to the Free Software Foundation, Inc., 59 Temple # Place, Suite 330, Boston, MA 02111-1307 USA. # # In addition, as a special exception, Red Hat, Inc. gives You the additional # right to link the code of this Program with code not covered under the GNU # General Public License ("Non-GPL Code") and to distribute linked combinations # including the two, subject to the limitations in this paragraph. Non-GPL Code # permitted under this exception must only link to the code of this Program # through those well defined interfaces identified in the file named EXCEPTION # found in the source code files (the "Approved Interfaces"). The files of # Non-GPL Code may instantiate templates or use macros or inline functions from # the Approved Interfaces without causing the resulting work to be covered by # the GNU General Public License. Only Red Hat, Inc. may make changes or # additions to the list of Approved Interfaces. You must obey the GNU General # Public License in all respects for all of the Program code and other code used # in conjunction with the Program except the Non-GPL Code covered by this # exception. If you modify this file, you may extend this exception to your # version of the file, but you are not obligated to do so. If you do not wish to # provide this exception without modification, you must delete this exception # statement from your version and license this file solely under the GPL without # exception. # # # Copyright (C) 2001 Sun Microsystems, Inc. Used by permission. # Copyright (C) 2005 Red Hat, Inc. # All rights reserved. # END COPYRIGHT BLOCK #
sub usage { print(STDERR "Usage: $0 [-v] -D rootdn { -w password | -w - | -j filename } \n"); print(STDERR " {-n instance}* | {-s include}* [{-x exclude}*] \n"); print(STDERR " [-m] [-M] [-u] [-C] [-N] [-U] [-a filename]\n"); print(STDERR " Opts: -D rootdn - Directory Manager\n"); print(STDERR " : -w password - Directory Manager's password\n"); print(STDERR " : -w - - Prompt for Directory Manager's password\n"); print(STDERR " : -j filename - Read Directory Manager's password from file\n"); print(STDERR " : -n instance - instance to be exported\n"); print(STDERR " : -a filename - output ldif file\n"); print(STDERR " : -s include - included suffix(es)\n"); print(STDERR " : -x exclude - excluded suffix(es)\n"); print(STDERR " : -m - minimal base64 encoding\n"); print(STDERR " : -M - output ldif is stored in multiple files\n"); print(STDERR " these files are named : <instance>_<filename>\n"); print(STDERR " by default, all instances are stored in <filename>\n"); print(STDERR " : -r - export replica\n"); print(STDERR " : -u - do not export unique id\n"); print(STDERR " : -C - use main db file only\n"); print(STDERR " : -N - suppress printing sequential number\n"); print(STDERR " : -U - output ldif is not folded\n"); print(STDERR " : -E - Decrypt encrypted data when exporting\n"); print(STDERR " : -1 - do not print version line\n"); print(STDERR " : -v - verbose\n"); }
@instances = ( "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" ); @included = ( "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" ); @excluded = ( "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" ); $maxidx = 50; $nowrap = 0; $nobase64 = 0; $noversion = 0; $nouniqueid = 0; $useid2entry = 0; $onefile = 1; $printkey = 1; $taskname = ""; $ldiffile = ""; $doreplica = 0; $prefix = "{{DS-ROOT}}"; $ldifdir = "{{LDIF-DIR}}"; $servid = "{{SERV-ID}}"; $verbose = 0; $rootdn = ""; $passwd = ""; $passwdfile = ""; $i = 0; $insti = 0; $incli = 0; $excli = 0; $decrypt_on_export = 0; while ($i <= $#ARGV) { if ( "$ARGV[$i]" eq "-n" ) { # instances $i++; if ($insti < $maxidx) { $instances[$insti] = $ARGV[$i]; $insti++; } else { &usage; exit(1); } } elsif ("$ARGV[$i]" eq "-s") { # included suffix $i++; if ($incli < $maxidx) { $included[$incli] = $ARGV[$i]; $incli++; } else { &usage; exit(1); } } elsif ("$ARGV[$i]" eq "-x") { # excluded suffix $i++; if ($excli < $maxidx) { $excluded[$excli] = $ARGV[$i]; $excli++; } else { &usage; exit(1); } } elsif ("$ARGV[$i]" eq "-a") { # ldif file $i++; $ldiffile = $ARGV[$i]; } elsif ("$ARGV[$i]" eq "-D") { # Directory Manager $i++; $rootdn = $ARGV[$i]; } elsif ("$ARGV[$i]" eq "-w") { # Directory Manager's password $i++; $passwd = $ARGV[$i]; } elsif ("$ARGV[$i]" eq "-j") { # Read Directory Manager's password from a file $i++; $passwdfile = $ARGV[$i]; } elsif ("$ARGV[$i]" eq "-M") { # multiple ldif file $onefile = 0; } elsif ("$ARGV[$i]" eq "-o") { # one ldif file $onefile = 1; } elsif ("$ARGV[$i]" eq "-u") { # no dump unique id $nouniqueid = 1; } elsif ("$ARGV[$i]" eq "-C") { # use id2entry $useid2entry = 1; } elsif ("$ARGV[$i]" eq "-N") { # does not print key $printkey = 0; } elsif ("$ARGV[$i]" eq "-r") { # export replica $doreplica = 1; } elsif ("$ARGV[$i]" eq "-m") { # no base64 $nobase64 = 1; } elsif ("$ARGV[$i]" eq "-U") { # no wrap $nowrap = 1; } elsif ("$ARGV[$i]" eq "-1") { # no version line $noversion = 1; } elsif ("$ARGV[$i]" eq "-E") { # decrypt $decrypt_on_export = 1; } elsif ("$ARGV[$i]" eq "-v") { # verbose $verbose = 1; } else { &usage; exit(1); } $i++; } if ($passwdfile ne ""){ # Open file and get the password unless (open (RPASS, $passwdfile)) { die "Error, cannot open password file $passwdfile\n"; } $passwd = <RPASS>; chomp($passwd); close(RPASS); } elsif ($passwd eq "-"){ # Read the password from terminal die "The '-w -' option requires an extension library (Term::ReadKey) which is not\n", "part of the standard perl distribution. If you want to use it, you must\n", "download and install the module. You can find it at\n", "http://www.perl.com/CPAN/CPAN.html%5Cn"; # Remove the previous line and uncomment the following 6 lines once you have installed Term::ReadKey module. # use Term::ReadKey; # print "Bind Password: "; # ReadMode('noecho'); # $passwd = ReadLine(0); # chomp($passwd); # ReadMode('normal'); } if (($instances[0] eq "" && $included[0] eq "") || $rootdn eq "" || $passwd eq "") { &usage; exit(1); } ($s, $m, $h, $dy, $mn, $yr, $wdy, $ydy, $r) = localtime(time); $mn++; $yr += 1900; $taskname = "export_${yr}_${mn}_${dy}_${h}_${m}_${s}"; if ($ldiffile eq "") { $ldiffile = "${ldifdir}{{SEP}}${servid}-${yr}_${mn}_${dy}_${h}_${m}_${s}.ldif"; } $dn = "dn: cn=$taskname, cn=export, cn=tasks, cn=config\n"; $misc = "changetype: add\nobjectclass: top\nobjectclass: extensibleObject\n"; $cn = "cn: $taskname\n"; $i = 0; $nsinstance = ""; while ("" ne "$instances[$i]") { $nsinstance = "${nsinstance}nsInstance: $instances[$i]\n"; $i++; } $i = 0; $nsincluded = ""; while ("" ne "$included[$i]") { $nsincluded = "${nsincluded}nsIncludeSuffix: $included[$i]\n"; $i++; } $i = 0; $nsexcluded = ""; while ("" ne "$excluded[$i]") { $nsexcluded = "${nsexcluded}nsExcludeSuffix: $excluded[$i]\n"; $i++; } $nsreplica = ""; if ($doreplica != 0) { $nsreplica = "nsExportReplica: true\n"; } $nsnobase64 = ""; if ($nobase64 != 0) { $nsnobase64 = "nsMinimalEncoding: true\n"; } $nsnowrap = ""; if ($nowrap != 0) { $nsnowrap = "nsNoWrap: true\n"; } $nsnoversion = ""; if ($noversion != 0) { $nsnoversion = "nsNoVersionLine: true\n"; } $nsnouniqueid = ""; if ($nouniqueid != 0) { $nsnouniqueid = "nsDumpUniqId: false\n"; } $nsuseid2entry = ""; if ($useid2entry != 0) { $nsuseid2entry = "nsUseId2Entry: true\n"; } $nsonefile = ""; if ($onefile != 0) { $nsonefile = "nsUseOneFile: true\n"; } if ($onefile == 0) { $nsonefile = "nsUseOneFile: false\n"; } $nsexportdecrypt = ""; if ($decrypt_on_export != 0) { $nsexportdecrypt = "nsExportDecrypt: true\n"; } $nsprintkey = ""; if ($printkey == 0) { $nsprintkey = "nsPrintKey: false\n"; } $nsldiffile = "nsFilename: ${ldiffile}\n"; $entry = "${dn}${misc}${cn}${nsinstance}${nsincluded}${nsexcluded}${nsreplica}${nsnobase64}${nsnowrap}${nsnoversion}${nsnouniqueid}${nsuseid2entry}${nsonefile}${nsexportdecrypt}${nsprintkey}${nsldiffile}"; $vstr = ""; if ($verbose != 0) { $vstr = "-v"; } $ENV{'PATH'} = '$prefix@ldapsdk_bindir@:$prefix/usr/lib:@ldapsdk_bindir@:/usr/lib'; $ENV{'LD_LIBRARY_PATH'} = '$prefix@nss_libdir@:$prefix/usr/lib:@nss_libdir@:/usr/lib'; $ENV{'SHLIB_PATH'} = '$prefix@nss_libdir@:$prefix/usr/lib:@nss_libdir@:/usr/lib'; open(FOO, "| ldapmodify $vstr -h {{SERVER-NAME}} -p {{SERVER-PORT}} -D "$rootdn" -w "$passwd" -a" ); print(FOO "$entry"); close(FOO);
--- NEW FILE template-ldif2db.pl.in --- #{{PERL-EXEC}} # # BEGIN COPYRIGHT BLOCK # This Program is free software; you can redistribute it and/or modify it under # the terms of the GNU General Public License as published by the Free Software # Foundation; version 2 of the License. # # This Program is distributed in the hope that it will be useful, but WITHOUT # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS # FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. # # You should have received a copy of the GNU General Public License along with # this Program; if not, write to the Free Software Foundation, Inc., 59 Temple # Place, Suite 330, Boston, MA 02111-1307 USA. # # In addition, as a special exception, Red Hat, Inc. gives You the additional # right to link the code of this Program with code not covered under the GNU # General Public License ("Non-GPL Code") and to distribute linked combinations # including the two, subject to the limitations in this paragraph. Non-GPL Code # permitted under this exception must only link to the code of this Program # through those well defined interfaces identified in the file named EXCEPTION # found in the source code files (the "Approved Interfaces"). The files of # Non-GPL Code may instantiate templates or use macros or inline functions from # the Approved Interfaces without causing the resulting work to be covered by # the GNU General Public License. Only Red Hat, Inc. may make changes or # additions to the list of Approved Interfaces. You must obey the GNU General # Public License in all respects for all of the Program code and other code used # in conjunction with the Program except the Non-GPL Code covered by this # exception. If you modify this file, you may extend this exception to your # version of the file, but you are not obligated to do so. If you do not wish to # provide this exception without modification, you must delete this exception # statement from your version and license this file solely under the GPL without # exception. # # # Copyright (C) 2001 Sun Microsystems, Inc. Used by permission. # Copyright (C) 2005 Red Hat, Inc. # All rights reserved. # END COPYRIGHT BLOCK #
sub usage { print(STDERR "Usage: $0 [-v] -D rootdn { -w password | -w - | -j filename } \n"); print(STDERR " -n instance | {-s include}* [{-x exclude}*] [-O] [-c]\n"); print(STDERR " [-g [string]] [-G namespace_id] {-i filename}*\n"); print(STDERR " Opts: -D rootdn - Directory Manager\n"); print(STDERR " : -w password - Directory Manager's password\n"); print(STDERR " : -w - - Prompt for Directory Manager's password\n"); print(STDERR " : -j filename - Read Directory Manager's password from file\n"); print(STDERR " : -n instance - instance to be imported to\n"); print(STDERR " : -i filename - input ldif file(s)\n"); print(STDERR " : -s include - included suffix\n"); print(STDERR " : -x exclude - excluded suffix(es)\n"); print(STDERR " : -O - only create core db, no attr indexes\n"); print(STDERR " : -c size - merge chunk size\n"); print(STDERR " : -g [string] - string is "none" or "deterministic"\n"); print(STDERR " : none - unique id is not generated\n"); print(STDERR " : deterministic - generate name based unique id (-G name)\n"); print(STDERR " : by default - generate time based unique id\n"); print(STDERR " : -G name - namespace id for name based uniqueid (-g deterministic)\n"); print(STDERR " : -E - Encrypt data when importing\n"); print(STDERR " : -v - verbose\n"); }
@ldiffiles = ( "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" ); @included = ( "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" ); @excluded = ( "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" ); $maxidx = 50; $instance = ""; $noattrindexes = 0; $mergechunksiz = 0; $genuniqid = "time"; $uniqidname = ""; $taskname = ""; $prefix = "{{DS-ROOT}}"; $verbose = 0; $rootdn = ""; $passwd = ""; $passwdfile = ""; $i = 0; $ldifi = 0; $incli = 0; $excli = 0; $encrypt_on_import = 0; while ($i <= $#ARGV) { if ( "$ARGV[$i]" eq "-i" ) { # ldiffiles $i++; if ($ldifi < $maxidx) { $ldiffiles[$ldifi] = $ARGV[$i]; $ldifi++; } else { &usage; exit(1); } } elsif ("$ARGV[$i]" eq "-s") { # included suffix $i++; if ($incli < $maxidx) { $included[$incli] = $ARGV[$i]; $incli++; } else { &usage; exit(1); } } elsif ("$ARGV[$i]" eq "-x") { # excluded suffix $i++; if ($excli < $maxidx) { $excluded[$excli] = $ARGV[$i]; $excli++; } else { &usage; exit(1); } } elsif ("$ARGV[$i]" eq "-n") { # instance $i++; $instance = $ARGV[$i]; } elsif ("$ARGV[$i]" eq "-D") { # Directory Manager $i++; $rootdn = $ARGV[$i]; } elsif ("$ARGV[$i]" eq "-w") { # Directory Manager's password $i++; $passwd = $ARGV[$i]; } elsif ("$ARGV[$i]" eq "-j") { # Read Directory Manager's password from a file $i++; $passwdfile = $ARGV[$i]; } elsif ("$ARGV[$i]" eq "-O") { # no attr indexes $noattrindexes = 1; } elsif ("$ARGV[$i]" eq "-c") { # merge chunk size $i++; $mergechunksiz = $ARGV[$i]; } elsif ("$ARGV[$i]" eq "-g") { # generate uniqueid if (("$ARGV[$i+1]" ne "") && !("$ARGV[$i+1]" =~ /^-/)) { $i++; if ("$ARGV[$i]" eq "none") { $genuniqid = $ARGV[$i]; } elsif ("$ARGV[$i]" eq "deterministic") { $genuniqid = $ARGV[$i]; } } } elsif ("$ARGV[$i]" eq "-G") { # namespace id $i++; $uniqidname = $ARGV[$i]; } elsif ("$ARGV[$i]" eq "-v") { # verbose $verbose = 1; } elsif ("$ARGV[$i]" eq "-E") { # encrypt on import $encrypt_on_import = 1; } else { &usage; exit(1); } $i++; } if ($passwdfile ne ""){ # Open file and get the password unless (open (RPASS, $passwdfile)) { die "Error, cannot open password file $passwdfile\n"; } $passwd = <RPASS>; chomp($passwd); close(RPASS); } elsif ($passwd eq "-"){ # Read the password from terminal die "The '-w -' option requires an extension library (Term::ReadKey) which is not\n", "part of the standard perl distribution. If you want to use it, you must\n", "download and install the module. You can find it at\n", "http://www.perl.com/CPAN/CPAN.html%5Cn"; # Remove the previous line and uncomment the following 6 lines once you have installed Term::ReadKey module. # use Term::ReadKey; # print "Bind Password: "; # ReadMode('noecho'); # $passwd = ReadLine(0); # chomp($passwd); # ReadMode('normal'); } if (($instance eq "" && $included[0] eq "") || $ldiffiles[0] eq "" || $rootdn eq "" || $passwd eq "") { &usage; exit(1); } ($s, $m, $h, $dy, $mn, $yr, $wdy, $ydy, $r) = localtime(time); $mn++; $yr += 1900; $taskname = "import_${yr}_${mn}_${dy}_${h}_${m}_${s}"; $dn = "dn: cn=$taskname, cn=import, cn=tasks, cn=config\n"; $misc = "changetype: add\nobjectclass: top\nobjectclass: extensibleObject\n"; $cn = "cn: $taskname\n"; if ($instance ne "") { $nsinstance = "nsInstance: ${instance}\n"; } $i = 0; $nsldiffiles = ""; while ("" ne "$ldiffiles[$i]") { $nsldiffiles = "${nsldiffiles}nsFilename: $ldiffiles[$i]\n"; $i++; } $i = 0; $nsincluded = ""; while ("" ne "$included[$i]") { $nsincluded = "${nsincluded}nsIncludeSuffix: $included[$i]\n"; $i++; } $i = 0; $nsexcluded = ""; while ("" ne "$excluded[$i]") { $nsexcluded = "${nsexcluded}nsExcludeSuffix: $excluded[$i]\n"; $i++; } $nsnoattrindexes = ""; if ($noattrindexes != 0) { $nsnoattrindexes = "nsImportIndexAttrs: false\n"; } $nsimportencrypt = ""; if ($encrypt_on_import != 0) { $nsimportencrypt = "nsImportEncrypt: true\n"; } $nsmergechunksiz = "nsImportChunkSize: ${mergechunksiz}\n"; $nsgenuniqid = "nsUniqueIdGenerator: ${genuniqid}\n"; $nsuniqidname = ""; if ($uniqidname ne "") { $nsuniqidname = "nsUniqueIdGeneratorNamespace: ${uniqidname}\n"; } $entry = "${dn}${misc}${cn}${nsinstance}${nsincluded}${nsexcluded}${nsldiffiles}${nsnoattrindexes}${nsimportencrypt}${nsmergechunksiz}${nsgenuniqid}${nsuniqidname}"; $vstr = ""; if ($verbose != 0) { $vstr = "-v"; } $ENV{'PATH'} = '$prefix@ldapsdk_bindir@:$prefix/usr/lib:@ldapsdk_bindir@:/usr/lib'; $ENV{'LD_LIBRARY_PATH'} = '$prefix@nss_libdir@:$prefix/usr/lib:@nss_libdir@:/usr/lib'; $ENV{'SHLIB_PATH'} = '$prefix@nss_libdir@:$prefix/usr/lib:@nss_libdir@:/usr/lib'; open(FOO, "| ldapmodify $vstr -h {{SERVER-NAME}} -p {{SERVER-PORT}} -D "$rootdn" -w "$passwd" -a" ); print(FOO "$entry"); close(FOO);
--- NEW FILE template-ns-accountstatus.pl.in --- #{{PERL-EXEC}} # # BEGIN COPYRIGHT BLOCK # This Program is free software; you can redistribute it and/or modify it under # the terms of the GNU General Public License as published by the Free Software # Foundation; version 2 of the License. # # This Program is distributed in the hope that it will be useful, but WITHOUT # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS # FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. # # You should have received a copy of the GNU General Public License along with # this Program; if not, write to the Free Software Foundation, Inc., 59 Temple # Place, Suite 330, Boston, MA 02111-1307 USA. # # In addition, as a special exception, Red Hat, Inc. gives You the additional # right to link the code of this Program with code not covered under the GNU # General Public License ("Non-GPL Code") and to distribute linked combinations # including the two, subject to the limitations in this paragraph. Non-GPL Code # permitted under this exception must only link to the code of this Program # through those well defined interfaces identified in the file named EXCEPTION # found in the source code files (the "Approved Interfaces"). The files of # Non-GPL Code may instantiate templates or use macros or inline functions from # the Approved Interfaces without causing the resulting work to be covered by # the GNU General Public License. Only Red Hat, Inc. may make changes or # additions to the list of Approved Interfaces. You must obey the GNU General # Public License in all respects for all of the Program code and other code used # in conjunction with the Program except the Non-GPL Code covered by this # exception. If you modify this file, you may extend this exception to your # version of the file, but you are not obligated to do so. If you do not wish to # provide this exception without modification, you must delete this exception # statement from your version and license this file solely under the GPL without # exception. # # # Copyright (C) 2001 Sun Microsystems, Inc. Used by permission. # Copyright (C) 2005 Red Hat, Inc. # All rights reserved. # END COPYRIGHT BLOCK #
############################### # SUB-ROUTINES ###############################
sub usage_and_exit { print (STDERR "$cmd [-D rootdn] { -w password | -w - | -j filename } \n"); print (STDERR " [-p port] [-h host] -I DN-to-$operation\n\n"); print (STDERR "May be used to $operation a user or a domain of users\n\n"); print (STDERR "Arguments:\n"); print (STDERR " -? - help\n"); print (STDERR " -D rootdn - Provide a Directory Manager DN. Default= '$defrootdn'\n"); print (STDERR " -w password - Provide a password for the Directory Manager DN\n"); print (STDERR " -w - - Prompt for the Directory Manager's password\n"); print (STDERR " -j filename - Read the Directory Manager's password from file\n"); print (STDERR " -p port - Provide a port. Default= '$defport'\n"); print (STDERR " -h host - Provide a host name. Default= '$defhost'\n"); print (STDERR " -I DN-to-$operation - Single entry DN or role DN to $operation\n"); exit 100; }
sub debug { # print " ==> @_"; }
sub out { print "@_"; }
# -------------------------- # Check if the entry is part of a locked role: # i.e.: for each role member (nsroledn) of nsdisabledrole, check if # * it is the same as the entry # * the entry is member of role (==has nsroledn attributes), compare each of # them with the nsroledn of nsdisabledrole # * if nsroledn of nsdisabledrole are complex, go through each of them # argv[0] is the local file handler # argv[1] is the entry (may be a single entry DN or a role DN) # argv[2] is the base for the search # --------------------------
$throughRole="";
sub indirectLock { # For recursivity, file handler must be local my $L_filehandle=$_[0]; $L_filehandle++;
my $L_entry=$_[1]; # Remove useless space my @L_intern=split /([,])/,$L_entry; my $L_result=""; foreach $L_part (@L_intern) { $L_part=~s/^ +//; $L_part=~ tr/A-Z/a-z/; $L_result="$L_result$L_part"; } $L_entry=$L_result;
my $L_base=$_[2]; my $L_search; my $L_currentrole; my $L_retCode;
my $L_local;
`$ldapsearch -p $port -h $host -D "$rootdn" -w "$rootpw" -s base -b "$L_base" "(|(objectclass=*)(objectclass=ldapsubentry))" nsroledn >> {{DEV-NULL}} 2>&1 `; $retCode=$?; if ( $retCode != 0 ) { $retCode=$?>>8; return 1; }
# Check if the role is a nested role @L_Nested="$ldapsearch -p $port -h $host -D "$rootdn" -w "$rootpw" -s base -b "$L_base" "(|(objectclass=nsNestedRoleDefinition)(objectclass=ldapsubentry))" "; # L_isNested == 1 means that we are going through a nested role, so for each member of that # nested role, check that the member is below the scope of the nested $L_isNested=@L_Nested;
# Not Direct Lock, Go through roles if any $L_search="$ldapsearch -p $port -h $host -D "$rootdn" -w "$rootpw" -s base -b "$L_base" "(|(objectclass=*)(objectclass=ldapsubentry))" nsroledn ";
debug("\t-->indirectLock: check if $L_entry is part of a locked role from base $L_base\n\n");
unless (open ($L_filehandle, "$L_search |")) { out("Can't open file $L_filehandle\n"); exit; } while (<$L_filehandle>) {
s/\n //g; if (/^nsroledn: (.*)\n/) { $L_currentrole = $1;
# Remove useless space my @L_intern=split /([,])/,$L_currentrole; my $L_result=""; foreach $L_part (@L_intern) { $L_part=~s/^ +//; $L_part=~ tr/A-Z/a-z/; $L_result="$L_result$L_part"; } $L_currentrole=$L_result;
debug("\t-- indirectLock loop: current nsroledn $L_currentrole of base $L_base\n"); if ( $L_isNested == 1 ) { if ( checkScope($L_currentrole, $L_base) == 0 ) { # Scope problem probably a bad conf, skip the currentrole next; } }
if ( $L_currentrole eq $L_entry ) { # the entry is a role that is directly locked # i.e, nsroledn of nsdisabledrole contains the entry $throughRole=$L_base; $throughRole=~ tr/A-Z/a-z/;
# skipDisabled means that we've just found that the entry (which is a role) # is locked directly (==its DN is part of nsroledn attributes) # we just want to know now, if it is locked through another role # at least, one if ( $skipDisabled == 1 ) { # direct inactivation $directLocked=1; # just go through that test once $skipDisabled=0; next; } debug("\t-- 1 indirectLock: $L_currentrole locked throughRole == $throughRole\n"); return 0; }
$L_retCode=memberOf($L_currentrole, $L_entry); if ( $L_retCode == 0 && $single == 1 ) { $throughRole=$L_currentrole; $throughRole=~ tr/A-Z/a-z/; if ( $skipManaged == 1 ) { if ( $L_currentrole eq $nsManagedDisabledRole) { # Try next nsroledn $directLocked=1; $skipManaged=0; next; } } debug("\t-- 2 indirectLock: $L_currentrole locked throughRole == $throughRole\n"); return 0; }
# Only for the first iteration # the first iteration is with nsdisabledrole as base, other # loops are deeper $L_local=$skipDisabled; $skipDisabled=0; # the current nsroledn may be a complex role, just go through # its won nsroledn $L_retCode=indirectLock($L_filehandle,$L_entry, $L_currentrole);
# Because of recursivity, to keep the initial value for the first level $skipDisabled=$L_local;
if ( $L_retCode == 0 ) { $throughRole=$L_currentrole; $throughRole=~ tr/A-Z/a-z/; debug("\t-- 3 indirectLock: $L_entry locked throughRole == $throughRole\n"); return 0; } } }
close($L_filehandle);
debug("\t<--indirectLock: no more nsroledn to process\n"); return 1; }
# -------------------------- # Check if nsroledn is part of the entry attributes # argv[0] is a role DN (nsroledn attribute) # argv[1] is the entry # -------------------------- sub memberOf { my $L_nsroledn=$_[0]; $L_nsroledn=~ tr/A-Z/a-z/;
my $L_entry=$_[1];
my $L_search; my $L_currentrole;
$L_search="$ldapsearch -p $port -h $host -D "$rootdn" -w "$rootpw" -s base -b "$L_entry" "(|(objectclass=*)(objectclass=ldapsubentry))" nsrole";
debug("\t\t-->memberOf: $L_search: check if $L_entry has $L_nsroledn as nsroledn attribute\n");
open (LDAP2, "$L_search |"); while (<LDAP2>) { s/\n //g; if (/^nsrole: (.*)\n/) { $L_currentrole = $1; $L_currentrole=~ tr/A-Z/a-z/; if ( $L_currentrole eq $L_nsroledn ) { # the parm is part of the $L_entry nsroledn debug("\t\t<--memberOf: $L_entry locked through $L_nsroledn\n"); return 0; } } } close(LDAP2);
# the parm is not part of the $L_entry nsroledn debug("\t\t<--memberOf: $L_entry not locked through $L_nsroledn\n"); return 1; }
# -------------------------- # Remove the rdn of a DN # argv[0] is a DN # -------------------------- sub removeRdn { $L_entry=$_[0];
@L_entryToTest=split /([,])/,$L_entry; debug("removeRdn: entry to split: $L_entry**@L_entryToTest\n");
$newDN=""; $removeRDN=1; foreach $part (@L_entryToTest) { $part=~ s/^ +//; $part=~ tr/A-Z/a-z/; if ( $removeRDN <= 2 ) { $removeRDN=$removeRDN+1; } else { $newDN="$newDN$part"; } }
debug("removeRdn: new DN **$newDN**\n"); }
# -------------------------- # Check if L_current is below the scope of # L_nestedRole # argv[0] is a role # argv[1] is the nested role # -------------------------- sub checkScope { $L_current=$_[0]; $L_nestedRole=$_[1];
debug("checkScope: check if $L_current is below $L_nestedRole\n");
removeRdn($L_nestedRole); $L_nestedRoleSuffix=$newDN; debug("checkScope: nested role based: $L_nestedRoleSuffix\n");
$cont=1; while ( ($cont == 1) && ($L_current ne "") ) { removeRdn($L_current); $currentDn=$newDN; debug("checkScope: current DN to check: $currentDn\n");
if ( $currentDn eq $L_nestedRoleSuffix ) { debug("checkScope: DN match!!!\n"); $cont = 0; } else { $L_current=$currentDn; } }
if ( $cont == 1 ) { debug("checkScope: $_[0] and $_[1] are not compatible\n"); return 0; } else { debug("checkScope: $_[0] and $_[1] are compatible\n"); return 1; } }
############################### # MAIN ROUTINE ###############################
# Generated variable $prefix="{{DS-ROOT}}";
# Determine which command we are running if ( $0 =~ /ns-inactivate(.pl)?$/ ) { $cmd="ns-inactivate.pl"; $operation="inactivate"; $state="inactivated"; $modrole="add"; $already="already"; } elsif ( $0 =~ /ns-activate(.pl)?$/ ) { $cmd="ns-activate.pl"; $operation="activate"; $state="activated"; $modrole="delete"; $already="already"; } elsif ( $0 =~ /ns-accountstatus(.pl)?$/ ) { $cmd="ns-accountstatus.pl"; $operation="get status of"; $state="activated"; # no need for $modrole as no operation is performed $already="";
} else { out("$0: unknown command\n"); exit 100; }
debug("Running ** $cmd ** $operation\n");
$ENV{'PATH'} = '$prefix@ldapsdk_bindir@:$prefix/usr/lib:@ldapsdk_bindir@:/usr/lib'; $ENV{'LD_LIBRARY_PATH'} = '$prefix@nss_libdir@:$prefix/usr/lib:@nss_libdir@:/usr/lib'; $ENV{'SHLIB_PATH'} = '$prefix@nss_libdir@:$prefix/usr/lib:@nss_libdir@:/usr/lib';
$ldapsearch="ldapsearch -1"; $ldapmodify="ldapmodify";
# Default values $defrootdn= "{{ROOT-DN}}"; $defhost= "{{SERVER-NAME}}"; $defport= "{{SERVER-PORT}}";
# User values $rootdn= "{{ROOT-DN}}"; $rootpw= ""; $pwfile= ""; $host= "{{SERVER-NAME}}"; $port= "{{SERVER-PORT}}"; $entry= "";
$single=0; $role=0;
# Process the command line arguments while( $arg = shift) { if($arg eq "-?") { usage_and_exit(); } elsif($arg eq "-D") { $rootdn= shift @ARGV; } elsif($arg eq "-w") { $rootpw= shift @ARGV; } elsif($arg eq "-j") { $pwfile= shift @ARGV; } elsif($arg eq "-p") { $port= shift @ARGV; } elsif($arg eq "-h") { $host= shift @ARGV; } elsif($arg eq "-I") { $entry= shift @ARGV; } else { print "$arg: Unknown command line argument.\n"; usage_and_exit(); } }
if ($pwfile ne ""){ # Open file and get the password unless (open (RPASS, $pwfile)) { die "Error, cannot open password file $passwdfile\n"; } $rootpw = <RPASS>; chomp($rootpw); close(RPASS); } elsif ($rootpw eq "-"){ # Read the password from terminal die "The '-w -' option requires an extension library (Term::ReadKey) which is not\n", "part of the standard perl distribution. If you want to use it, you must\n", "download and install the module. You can find it at\n", "http://www.perl.com/CPAN/CPAN.html%5Cn"; # Remove the previous line and uncomment the following 6 lines once you have installed Term::ReadKey module. # use Term::ReadKey; # print "Bind Password: "; # ReadMode('noecho'); # $rootpw = ReadLine(0); # chomp($rootpw); # ReadMode('normal'); }
if( $rootpw eq "" ) { usage_and_exit(); }
if( $entry eq "" ) { usage_and_exit(); }
# # Check the actual existence of the entry to inactivate/activate # and at the same time, validate the various parm: port, host, rootdn, rootpw # @exist=`$ldapsearch -p $port -h $host -D "$rootdn" -w "$rootpw" -s base -b "$entry" "(objectclass=*)" dn`; $retCode1=$?; if ( $retCode1 != 0 ) { $retCode1=$?>>8; exit $retCode1; }
@isRole=`$ldapsearch -p $port -h $host -D "$rootdn" -w "$rootpw" -s base -b "$entry" "(&(objectclass=LDAPsubentry)(objectclass=nsRoleDefinition))" dn`; $nbLineRole=@isRole; $retCode2=$?; if ( $retCode2 != 0 ) { $retCode2=$?>>8; exit $retCode2; }
if ( $nbLineRole == 1 ) { debug("Groups of users\n"); $role=1; } else { debug("Single user\n"); $single=1; }
# # First of all, check the existence of the nsaccountlock attribute in the entry # $isLocked=0; if ( $single == 1 ) { $searchAccountLock="$ldapsearch -p $port -h $host -D "$rootdn" -w "$rootpw" -s base -b "$entry" "(objectclass=*)" nsaccountlock"; open (LDAP1, "$searchAccountLock |"); while (<LDAP1>) { s/\n //g; if (/^nsaccountlock: (.*)\n/) { $L_currentvalue = $1; $L_currentvalue=~ tr/A-Z/a-z/; if ( $L_currentvalue eq "true") { $isLocked=1; } elsif ( $L_currentvalue eq "false" ) { $isLocked=0; } } } close(LDAP1); } debug("Is the entry already locked? ==> $isLocked\n");
# # Get the suffix name of that entry #
# Remove the space at the beginning (just in case...) # -I "uid=jvedder , ou=People , o=sun.com" @suffix=split /([,])/,$entry; $result=""; foreach $part (@suffix) { $part=~s/^ +//; $part=~ tr/A-Z/a-z/; $result="$result$part"; } @suffixN=$result;
debug("Entry to $operation: #@suffix#\n"); debug("Entry to $operation: #@suffixN#\n");
# Get the suffix $cont=0; while ($cont == 0) { # Look if suffix is the suffix of the entry # ldapsearch -s one -b "cn=mapping tree,cn=config" "cn="uid=jvedder,ou=People,o=sun.com"" # debug("\tSuffix from the entry: #@suffixN#\n"); @mapping=`$ldapsearch -p $port -h $host -D "$rootdn" -w "$rootpw" -s one -b "cn=mapping tree, cn=config" "cn=\"@suffixN\"" cn `;
$retCode=$?; if ( $retCode != 0 ) { $retCode=$?>>8; exit $retCode; }
# If we get a result, remove the dn: # dn: cn="o=sun.com",cn=mapping tree,cn=config # cn: "o=sun.com" # shift @mapping;
foreach $res (@mapping) { # Break the string cn: "o=sun.com" into pieces @cn= split(/ /,$res);
# And remove the cn: part shift @cn;
# Now compare the suffix we extract from the mapping tree # with the suffix derived from the entry debug("\tSuffix from mapping tree: #@cn#\n"); if ( @cn eq @suffixN ) { debug("Found matching suffix\n"); $cont=1; } }
if ( $cont == 0 ) { # Remove the current rdn to try another suffix shift @suffix;
$result=""; foreach $part (@suffix) { $part=~ s/^ +//; $part=~ tr/A-Z/a-z/; $result="$result$part"; } @suffixN=$result;
debug("\t\tNothing found => go up one level in rdn #@suffix#\n"); $len=@suffix; if ( $len == 0 ) { debug("Can not find suffix. Problem\n"); $cont=2; } } } if ( $cont == 2) { out("Can not find suffix for entry $entry\n"); exit 100; }
if ( $operation eq "inactivate" ) { # # Now that we have the suffix and we know if we deal with a single entry or # a role, just try to create the COS and roles associated. # @base=( "cn=nsManagedDisabledRole,@suffixN", "cn=nsDisabledRole,@suffixN", "cn=nsAccountInactivationTmp,@suffixN", "'cn="cn=nsDisabledRole,@suffixN",cn=nsAccountInactivationTmp,@suffixN'", "cn=nsAccountInactivation_cos,@suffixN" );
$addrolescos="$ldapmodify -p $port -h $host -D "$rootdn" -w "$rootpw" -c -a >> {{DEV-NULL}} 2>&1 "; @role1=( "dn: cn=nsManagedDisabledRole,@suffixN\n", "objectclass: LDAPsubentry\n", "objectclass: nsRoleDefinition\n", "objectclass: nsSimpleRoleDefinition\n", "objectclass: nsManagedRoleDefinition\n", "cn: nsManagedDisabledRole\n\n" ); @role2=( "dn: cn=nsDisabledRole,@suffixN\n", "objectclass: top\n", "objectclass: LDAPsubentry\n", "objectclass: nsRoleDefinition\n", "objectclass: nsComplexRoleDefinition\n", "objectclass: nsNestedRoleDefinition\n", "nsRoleDN: cn=nsManagedDisabledRole,@suffixN\n", "cn: nsDisabledRole\n\n" ); @cos1=( "dn: cn=nsAccountInactivationTmp,@suffixN\n", "objectclass: top\n", "objectclass: nsContainer\n\n" ); @cos2=( "dn: cn="cn=nsDisabledRole,@suffixN",cn=nsAccountInactivationTmp,@suffixN\n", "objectclass: top\n", "objectclass: extensibleObject\n", "objectclass: costemplate\n", "objectclass: ldapsubentry\n", "cosPriority: 1\n", "nsAccountLock: true\n\n" ); @cos3=( "dn: cn=nsAccountInactivation_cos,@suffixN\n", "objectclass: top\n", "objectclass: LDAPsubentry\n", "objectclass: cosSuperDefinition\n", "objectclass: cosClassicDefinition\n", "cosTemplateDn: cn=nsAccountInactivationTmp,@suffixN\n", "cosSpecifier: nsRole\n", "cosAttribute: nsAccountLock operational\n\n" );
@all=(@role1, @role2, @cos1, @cos2, @cos3);
$i=0;
foreach $current (@base) { debug("Creating $current ??\n"); open(FD,"| $addrolescos "); print FD @{$all[$i]}; close(FD); if ( $? != 0 ) { $retCode=$?>>8; if ( $retCode == 68 ) { debug("Entry $current already exists, ignore error\n"); } else { # Probably a more serious problem. # Exit with LDAP error exit $retCode; } } else { debug("Entry $current created\n"); } $i=$i+1; } }
$skipManaged=0; $skipDisabled=0; $directLocked=0;
$nsDisabledRole="cn=nsDisabledRole,@suffixN"; $nsDisabledRole=~ tr/A-Z/a-z/;
$nsManagedDisabledRole="cn=nsManagedDisabledRole,@suffixN"; $nsManagedDisabledRole=~ tr/A-Z/a-z/;
if ( $operation eq "inactivate" ) { # Go through all the roles part of nsdisabledrole to check if the entry # is a member of one of those roles $ret=indirectLock("LDAP00", $entry, $nsDisabledRole); if ( $ret == 0 ) { if ( $throughRole ne $nsDisabledRole && $throughRole ne $nsManagedDisabledRole ) { # indirect lock out("$entry already $state through $throughRole.\n"); } else { # direct lock out("$entry already $state.\n"); } exit 100; } elsif ( $isLocked == 1 ) { # the entry is not locked through a role, may be nsaccountlock is "hardcoded" ? out("$entry already $state (probably directly).\n"); exit 103; } } elsif ( $operation eq "activate" || $operation eq "get status of" ) { $skipManaged=$single; $skipDisabled=$role;
$ret=indirectLock("LDAP00",$entry, $nsDisabledRole);
if ( $ret == 0 ) { # undirectly locked if ( $throughRole ne $nsDisabledRole && $throughRole ne $nsManagedDisabledRole ) { if ( $operation eq "activate" ) { out("$entry inactivated through $throughRole. Can not activate it individually.\n"); exit 100; } else { out("$entry inactivated through $throughRole.\n"); exit 104; } } debug("$entry locked individually\n");
if ( $operation ne "activate" ) { out("$entry inactivated.\n"); exit 103; } } elsif ( $directLocked == 0 ) { if ( $operation eq "activate" && $isLocked != 1 ) { out("$entry $already $state.\n"); exit 100; } elsif ( $isLocked != 1 ) { out("$entry $already $state.\n"); exit 102; } else { # not locked using our schema, but nsaccountlock is probably present out("$entry inactivated (probably directly).\n"); exit 103; } } elsif ( $operation ne "activate" ) { out("$entry inactivated.\n"); exit 103; } # else Locked directly, juste unlock it! debug("$entry locked individually\n"); }
# # Inactivate/activate the entry # $action="$ldapmodify -p $port -h $host -D "$rootdn" -w "$rootpw" -c >> {{DEV-NULL}} 2>&1"; if ( $single == 1 ) { @record=( "dn: $entry\n", "changetype: modify\n", "$modrole: nsRoleDN\n", "nsRoleDN: cn=nsManagedDisabledRole,@suffixN\n\n" ); } else { @record=( "dn: cn=nsDisabledRole,@suffixN\n", "changetype: modify\n", "$modrole: nsRoleDN\n", "nsRoleDN: $entry\n\n" ); } open(FD,"| $action "); print FD @record; close(FD); if ( $? != 0 ) { debug("$modrole, $entry\n"); $retCode=$?>>8; exit $retCode; }
out("$entry $state.\n"); exit 0;
--- NEW FILE template-ns-activate.pl.in --- #{{PERL-EXEC}} # # BEGIN COPYRIGHT BLOCK # This Program is free software; you can redistribute it and/or modify it under # the terms of the GNU General Public License as published by the Free Software # Foundation; version 2 of the License. # # This Program is distributed in the hope that it will be useful, but WITHOUT # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS # FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. # # You should have received a copy of the GNU General Public License along with # this Program; if not, write to the Free Software Foundation, Inc., 59 Temple # Place, Suite 330, Boston, MA 02111-1307 USA. # # In addition, as a special exception, Red Hat, Inc. gives You the additional # right to link the code of this Program with code not covered under the GNU # General Public License ("Non-GPL Code") and to distribute linked combinations # including the two, subject to the limitations in this paragraph. Non-GPL Code # permitted under this exception must only link to the code of this Program # through those well defined interfaces identified in the file named EXCEPTION # found in the source code files (the "Approved Interfaces"). The files of # Non-GPL Code may instantiate templates or use macros or inline functions from # the Approved Interfaces without causing the resulting work to be covered by # the GNU General Public License. Only Red Hat, Inc. may make changes or # additions to the list of Approved Interfaces. You must obey the GNU General # Public License in all respects for all of the Program code and other code used # in conjunction with the Program except the Non-GPL Code covered by this # exception. If you modify this file, you may extend this exception to your # version of the file, but you are not obligated to do so. If you do not wish to # provide this exception without modification, you must delete this exception # statement from your version and license this file solely under the GPL without # exception. # # # Copyright (C) 2001 Sun Microsystems, Inc. Used by permission. # Copyright (C) 2005 Red Hat, Inc. # All rights reserved. # END COPYRIGHT BLOCK #
############################### # SUB-ROUTINES ###############################
sub usage_and_exit { print (STDERR "$cmd [-D rootdn] { -w password | -w - | -j filename } \n"); print (STDERR " [-p port] [-h host] -I DN-to-$operation\n\n"); print (STDERR "May be used to $operation a user or a domain of users\n\n"); print (STDERR "Arguments:\n"); print (STDERR " -? - help\n"); print (STDERR " -D rootdn - Provide a Directory Manager DN. Default= '$defrootdn'\n"); print (STDERR " -w password - Provide a password for the Directory Manager DN\n"); print (STDERR " -w - - Prompt for the Directory Manager's password\n"); print (STDERR " -j filename - Read the Directory Manager's password from file\n"); print (STDERR " -p port - Provide a port. Default= '$defport'\n"); print (STDERR " -h host - Provide a host name. Default= '$defhost'\n"); print (STDERR " -I DN-to-$operation - Single entry DN or role DN to $operation\n"); exit 100; }
sub debug { # print " ==> @_"; }
sub out { print "@_"; }
# -------------------------- # Check if the entry is part of a locked role: # i.e.: for each role member (nsroledn) of nsdisabledrole, check if # * it is the same as the entry # * the entry is member of role (==has nsroledn attributes), compare each of # them with the nsroledn of nsdisabledrole # * if nsroledn of nsdisabledrole are complex, go through each of them # argv[0] is the local file handler # argv[1] is the entry (may be a single entry DN or a role DN) # argv[2] is the base for the search # --------------------------
$throughRole="";
sub indirectLock { # For recursivity, file handler must be local my $L_filehandle=$_[0]; $L_filehandle++;
my $L_entry=$_[1]; # Remove useless space my @L_intern=split /([,])/,$L_entry; my $L_result=""; foreach $L_part (@L_intern) { $L_part=~s/^ +//; $L_part=~ tr/A-Z/a-z/; $L_result="$L_result$L_part"; } $L_entry=$L_result;
my $L_base=$_[2]; my $L_search; my $L_currentrole; my $L_retCode;
my $L_local;
`$ldapsearch -p $port -h $host -D "$rootdn" -w "$rootpw" -s base -b "$L_base" "(|(objectclass=*)(objectclass=ldapsubentry))" nsroledn >> {{DEV-NULL}} 2>&1 `; $retCode=$?; if ( $retCode != 0 ) { $retCode=$?>>8; return 1; }
# Check if the role is a nested role @L_Nested="$ldapsearch -p $port -h $host -D "$rootdn" -w "$rootpw" -s base -b "$L_base" "(|(objectclass=nsNestedRoleDefinition)(objectclass=ldapsubentry))" "; # L_isNested == 1 means that we are going through a nested role, so for each member of that # nested role, check that the member is below the scope of the nested $L_isNested=@L_Nested;
# Not Direct Lock, Go through roles if any $L_search="$ldapsearch -p $port -h $host -D "$rootdn" -w "$rootpw" -s base -b "$L_base" "(|(objectclass=*)(objectclass=ldapsubentry))" nsroledn ";
debug("\t-->indirectLock: check if $L_entry is part of a locked role from base $L_base\n\n");
unless (open ($L_filehandle, "$L_search |")) { out("Can't open file $L_filehandle\n"); exit; } while (<$L_filehandle>) {
s/\n //g; if (/^nsroledn: (.*)\n/) { $L_currentrole = $1;
# Remove useless space my @L_intern=split /([,])/,$L_currentrole; my $L_result=""; foreach $L_part (@L_intern) { $L_part=~s/^ +//; $L_part=~ tr/A-Z/a-z/; $L_result="$L_result$L_part"; } $L_currentrole=$L_result;
debug("\t-- indirectLock loop: current nsroledn $L_currentrole of base $L_base\n"); if ( $L_isNested == 1 ) { if ( checkScope($L_currentrole, $L_base) == 0 ) { # Scope problem probably a bad conf, skip the currentrole next; } }
if ( $L_currentrole eq $L_entry ) { # the entry is a role that is directly locked # i.e, nsroledn of nsdisabledrole contains the entry $throughRole=$L_base; $throughRole=~ tr/A-Z/a-z/;
# skipDisabled means that we've just found that the entry (which is a role) # is locked directly (==its DN is part of nsroledn attributes) # we just want to know now, if it is locked through another role # at least, one if ( $skipDisabled == 1 ) { # direct inactivation $directLocked=1; # just go through that test once $skipDisabled=0; next; } debug("\t-- 1 indirectLock: $L_currentrole locked throughRole == $throughRole\n"); return 0; }
$L_retCode=memberOf($L_currentrole, $L_entry); if ( $L_retCode == 0 && $single == 1 ) { $throughRole=$L_currentrole; $throughRole=~ tr/A-Z/a-z/; if ( $skipManaged == 1 ) { if ( $L_currentrole eq $nsManagedDisabledRole) { # Try next nsroledn $directLocked=1; $skipManaged=0; next; } } debug("\t-- 2 indirectLock: $L_currentrole locked throughRole == $throughRole\n"); return 0; }
# Only for the first iteration # the first iteration is with nsdisabledrole as base, other # loops are deeper $L_local=$skipDisabled; $skipDisabled=0; # the current nsroledn may be a complex role, just go through # its won nsroledn $L_retCode=indirectLock($L_filehandle,$L_entry, $L_currentrole);
# Because of recursivity, to keep the initial value for the first level $skipDisabled=$L_local;
if ( $L_retCode == 0 ) { $throughRole=$L_currentrole; $throughRole=~ tr/A-Z/a-z/; debug("\t-- 3 indirectLock: $L_entry locked throughRole == $throughRole\n"); return 0; } } }
close($L_filehandle);
debug("\t<--indirectLock: no more nsroledn to process\n"); return 1; }
# -------------------------- # Check if nsroledn is part of the entry attributes # argv[0] is a role DN (nsroledn attribute) # argv[1] is the entry # -------------------------- sub memberOf { my $L_nsroledn=$_[0]; $L_nsroledn=~ tr/A-Z/a-z/;
my $L_entry=$_[1];
my $L_search; my $L_currentrole;
$L_search="$ldapsearch -p $port -h $host -D "$rootdn" -w "$rootpw" -s base -b "$L_entry" "(|(objectclass=*)(objectclass=ldapsubentry))" nsrole";
debug("\t\t-->memberOf: $L_search: check if $L_entry has $L_nsroledn as nsroledn attribute\n");
open (LDAP2, "$L_search |"); while (<LDAP2>) { s/\n //g; if (/^nsrole: (.*)\n/) { $L_currentrole = $1; $L_currentrole=~ tr/A-Z/a-z/; if ( $L_currentrole eq $L_nsroledn ) { # the parm is part of the $L_entry nsroledn debug("\t\t<--memberOf: $L_entry locked through $L_nsroledn\n"); return 0; } } } close(LDAP2);
# the parm is not part of the $L_entry nsroledn debug("\t\t<--memberOf: $L_entry not locked through $L_nsroledn\n"); return 1; }
# -------------------------- # Remove the rdn of a DN # argv[0] is a DN # -------------------------- sub removeRdn { $L_entry=$_[0];
@L_entryToTest=split /([,])/,$L_entry; debug("removeRdn: entry to split: $L_entry**@L_entryToTest\n");
$newDN=""; $removeRDN=1; foreach $part (@L_entryToTest) { $part=~ s/^ +//; $part=~ tr/A-Z/a-z/; if ( $removeRDN <= 2 ) { $removeRDN=$removeRDN+1; } else { $newDN="$newDN$part"; } }
debug("removeRdn: new DN **$newDN**\n"); }
# -------------------------- # Check if L_current is below the scope of # L_nestedRole # argv[0] is a role # argv[1] is the nested role # -------------------------- sub checkScope { $L_current=$_[0]; $L_nestedRole=$_[1];
debug("checkScope: check if $L_current is below $L_nestedRole\n");
removeRdn($L_nestedRole); $L_nestedRoleSuffix=$newDN; debug("checkScope: nested role based: $L_nestedRoleSuffix\n");
$cont=1; while ( ($cont == 1) && ($L_current ne "") ) { removeRdn($L_current); $currentDn=$newDN; debug("checkScope: current DN to check: $currentDn\n");
if ( $currentDn eq $L_nestedRoleSuffix ) { debug("checkScope: DN match!!!\n"); $cont = 0; } else { $L_current=$currentDn; } }
if ( $cont == 1 ) { debug("checkScope: $_[0] and $_[1] are not compatible\n"); return 0; } else { debug("checkScope: $_[0] and $_[1] are compatible\n"); return 1; } }
############################### # MAIN ROUTINE ###############################
# Generated variable $prefix="{{DS-ROOT}}";
# Determine which command we are running if ( $0 =~ /ns-inactivate(.pl)?$/ ) { $cmd="ns-inactivate.pl"; $operation="inactivate"; $state="inactivated"; $modrole="add"; $already="already"; } elsif ( $0 =~ /ns-activate(.pl)?$/ ) { $cmd="ns-activate.pl"; $operation="activate"; $state="activated"; $modrole="delete"; $already="already"; } elsif ( $0 =~ /ns-accountstatus(.pl)?$/ ) { $cmd="ns-accountstatus.pl"; $operation="get status of"; $state="activated"; # no need for $modrole as no operation is performed $already="";
} else { out("$0: unknown command\n"); exit 100; }
debug("Running ** $cmd ** $operation\n");
$ENV{'PATH'} = '$prefix@ldapsdk_bindir@:$prefix/usr/lib:@ldapsdk_bindir@:/usr/lib'; $ENV{'LD_LIBRARY_PATH'} = '$prefix@nss_libdir@:$prefix/usr/lib:@nss_libdir@:/usr/lib'; $ENV{'SHLIB_PATH'} = '$prefix@nss_libdir@:$prefix/usr/lib:@nss_libdir@:/usr/lib';
$ldapsearch="ldapsearch -1"; $ldapmodify="ldapmodify";
# Default values $defrootdn= "{{ROOT-DN}}"; $defhost= "{{SERVER-NAME}}"; $defport= "{{SERVER-PORT}}";
# User values $rootdn= "{{ROOT-DN}}"; $rootpw= ""; $pwfile= ""; $host= "{{SERVER-NAME}}"; $port= "{{SERVER-PORT}}"; $entry= "";
$single=0; $role=0;
# Process the command line arguments while( $arg = shift) { if($arg eq "-?") { usage_and_exit(); } elsif($arg eq "-D") { $rootdn= shift @ARGV; } elsif($arg eq "-w") { $rootpw= shift @ARGV; } elsif($arg eq "-j") { $pwfile= shift @ARGV; } elsif($arg eq "-p") { $port= shift @ARGV; } elsif($arg eq "-h") { $host= shift @ARGV; } elsif($arg eq "-I") { $entry= shift @ARGV; } else { print "$arg: Unknown command line argument.\n"; usage_and_exit(); } }
if ($pwfile ne ""){ # Open file and get the password unless (open (RPASS, $pwfile)) { die "Error, cannot open password file $passwdfile\n"; } $rootpw = <RPASS>; chomp($rootpw); close(RPASS); } elsif ($rootpw eq "-"){ # Read the password from terminal die "The '-w -' option requires an extension library (Term::ReadKey) which is not\n", "part of the standard perl distribution. If you want to use it, you must\n", "download and install the module. You can find it at\n", "http://www.perl.com/CPAN/CPAN.html%5Cn"; # Remove the previous line and uncomment the following 6 lines once you have installed Term::ReadKey module. # use Term::ReadKey; # print "Bind Password: "; # ReadMode('noecho'); # $rootpw = ReadLine(0); # chomp($rootpw); # ReadMode('normal'); }
if( $rootpw eq "" ) { usage_and_exit(); }
if( $entry eq "" ) { usage_and_exit(); }
# # Check the actual existence of the entry to inactivate/activate # and at the same time, validate the various parm: port, host, rootdn, rootpw # @exist=`$ldapsearch -p $port -h $host -D "$rootdn" -w "$rootpw" -s base -b "$entry" "(objectclass=*)" dn`; $retCode1=$?; if ( $retCode1 != 0 ) { $retCode1=$?>>8; exit $retCode1; }
@isRole=`$ldapsearch -p $port -h $host -D "$rootdn" -w "$rootpw" -s base -b "$entry" "(&(objectclass=LDAPsubentry)(objectclass=nsRoleDefinition))" dn`; $nbLineRole=@isRole; $retCode2=$?; if ( $retCode2 != 0 ) { $retCode2=$?>>8; exit $retCode2; }
if ( $nbLineRole == 1 ) { debug("Groups of users\n"); $role=1; } else { debug("Single user\n"); $single=1; }
# # First of all, check the existence of the nsaccountlock attribute in the entry # $isLocked=0; if ( $single == 1 ) { $searchAccountLock="$ldapsearch -p $port -h $host -D "$rootdn" -w "$rootpw" -s base -b "$entry" "(objectclass=*)" nsaccountlock"; open (LDAP1, "$searchAccountLock |"); while (<LDAP1>) { s/\n //g; if (/^nsaccountlock: (.*)\n/) { $L_currentvalue = $1; $L_currentvalue=~ tr/A-Z/a-z/; if ( $L_currentvalue eq "true") { $isLocked=1; } elsif ( $L_currentvalue eq "false" ) { $isLocked=0; } } } close(LDAP1); } debug("Is the entry already locked? ==> $isLocked\n");
# # Get the suffix name of that entry #
# Remove the space at the beginning (just in case...) # -I "uid=jvedder , ou=People , o=sun.com" @suffix=split /([,])/,$entry; $result=""; foreach $part (@suffix) { $part=~s/^ +//; $part=~ tr/A-Z/a-z/; $result="$result$part"; } @suffixN=$result;
debug("Entry to $operation: #@suffix#\n"); debug("Entry to $operation: #@suffixN#\n");
# Get the suffix $cont=0; while ($cont == 0) { # Look if suffix is the suffix of the entry # ldapsearch -s one -b "cn=mapping tree,cn=config" "cn="uid=jvedder,ou=People,o=sun.com"" # debug("\tSuffix from the entry: #@suffixN#\n"); @mapping=`$ldapsearch -p $port -h $host -D "$rootdn" -w "$rootpw" -s one -b "cn=mapping tree, cn=config" "cn=\"@suffixN\"" cn `;
$retCode=$?; if ( $retCode != 0 ) { $retCode=$?>>8; exit $retCode; }
# If we get a result, remove the dn: # dn: cn="o=sun.com",cn=mapping tree,cn=config # cn: "o=sun.com" # shift @mapping;
foreach $res (@mapping) { # Break the string cn: "o=sun.com" into pieces @cn= split(/ /,$res);
# And remove the cn: part shift @cn;
# Now compare the suffix we extract from the mapping tree # with the suffix derived from the entry debug("\tSuffix from mapping tree: #@cn#\n"); if ( @cn eq @suffixN ) { debug("Found matching suffix\n"); $cont=1; } }
if ( $cont == 0 ) { # Remove the current rdn to try another suffix shift @suffix;
$result=""; foreach $part (@suffix) { $part=~ s/^ +//; $part=~ tr/A-Z/a-z/; $result="$result$part"; } @suffixN=$result;
debug("\t\tNothing found => go up one level in rdn #@suffix#\n"); $len=@suffix; if ( $len == 0 ) { debug("Can not find suffix. Problem\n"); $cont=2; } } } if ( $cont == 2) { out("Can not find suffix for entry $entry\n"); exit 100; }
if ( $operation eq "inactivate" ) { # # Now that we have the suffix and we know if we deal with a single entry or # a role, just try to create the COS and roles associated. # @base=( "cn=nsManagedDisabledRole,@suffixN", "cn=nsDisabledRole,@suffixN", "cn=nsAccountInactivationTmp,@suffixN", "'cn="cn=nsDisabledRole,@suffixN",cn=nsAccountInactivationTmp,@suffixN'", "cn=nsAccountInactivation_cos,@suffixN" );
$addrolescos="$ldapmodify -p $port -h $host -D "$rootdn" -w "$rootpw" -c -a >> {{DEV-NULL}} 2>&1 "; @role1=( "dn: cn=nsManagedDisabledRole,@suffixN\n", "objectclass: LDAPsubentry\n", "objectclass: nsRoleDefinition\n", "objectclass: nsSimpleRoleDefinition\n", "objectclass: nsManagedRoleDefinition\n", "cn: nsManagedDisabledRole\n\n" ); @role2=( "dn: cn=nsDisabledRole,@suffixN\n", "objectclass: top\n", "objectclass: LDAPsubentry\n", "objectclass: nsRoleDefinition\n", "objectclass: nsComplexRoleDefinition\n", "objectclass: nsNestedRoleDefinition\n", "nsRoleDN: cn=nsManagedDisabledRole,@suffixN\n", "cn: nsDisabledRole\n\n" ); @cos1=( "dn: cn=nsAccountInactivationTmp,@suffixN\n", "objectclass: top\n", "objectclass: nsContainer\n\n" ); @cos2=( "dn: cn="cn=nsDisabledRole,@suffixN",cn=nsAccountInactivationTmp,@suffixN\n", "objectclass: top\n", "objectclass: extensibleObject\n", "objectclass: costemplate\n", "objectclass: ldapsubentry\n", "cosPriority: 1\n", "nsAccountLock: true\n\n" ); @cos3=( "dn: cn=nsAccountInactivation_cos,@suffixN\n", "objectclass: top\n", "objectclass: LDAPsubentry\n", "objectclass: cosSuperDefinition\n", "objectclass: cosClassicDefinition\n", "cosTemplateDn: cn=nsAccountInactivationTmp,@suffixN\n", "cosSpecifier: nsRole\n", "cosAttribute: nsAccountLock operational\n\n" );
@all=(@role1, @role2, @cos1, @cos2, @cos3);
$i=0;
foreach $current (@base) { debug("Creating $current ??\n"); open(FD,"| $addrolescos "); print FD @{$all[$i]}; close(FD); if ( $? != 0 ) { $retCode=$?>>8; if ( $retCode == 68 ) { debug("Entry $current already exists, ignore error\n"); } else { # Probably a more serious problem. # Exit with LDAP error exit $retCode; } } else { debug("Entry $current created\n"); } $i=$i+1; } }
$skipManaged=0; $skipDisabled=0; $directLocked=0;
$nsDisabledRole="cn=nsDisabledRole,@suffixN"; $nsDisabledRole=~ tr/A-Z/a-z/;
$nsManagedDisabledRole="cn=nsManagedDisabledRole,@suffixN"; $nsManagedDisabledRole=~ tr/A-Z/a-z/;
if ( $operation eq "inactivate" ) { # Go through all the roles part of nsdisabledrole to check if the entry # is a member of one of those roles $ret=indirectLock("LDAP00", $entry, $nsDisabledRole); if ( $ret == 0 ) { if ( $throughRole ne $nsDisabledRole && $throughRole ne $nsManagedDisabledRole ) { # indirect lock out("$entry already $state through $throughRole.\n"); } else { # direct lock out("$entry already $state.\n"); } exit 100; } elsif ( $isLocked == 1 ) { # the entry is not locked through a role, may be nsaccountlock is "hardcoded" ? out("$entry already $state (probably directly).\n"); exit 103; } } elsif ( $operation eq "activate" || $operation eq "get status of" ) { $skipManaged=$single; $skipDisabled=$role;
$ret=indirectLock("LDAP00",$entry, $nsDisabledRole);
if ( $ret == 0 ) { # undirectly locked if ( $throughRole ne $nsDisabledRole && $throughRole ne $nsManagedDisabledRole ) { if ( $operation eq "activate" ) { out("$entry inactivated through $throughRole. Can not activate it individually.\n"); exit 100; } else { out("$entry inactivated through $throughRole.\n"); exit 104; } } debug("$entry locked individually\n");
if ( $operation ne "activate" ) { out("$entry inactivated.\n"); exit 103; } } elsif ( $directLocked == 0 ) { if ( $operation eq "activate" && $isLocked != 1 ) { out("$entry $already $state.\n"); exit 100; } elsif ( $isLocked != 1 ) { out("$entry $already $state.\n"); exit 102; } else { # not locked using our schema, but nsaccountlock is probably present out("$entry inactivated (probably directly).\n"); exit 103; } } elsif ( $operation ne "activate" ) { out("$entry inactivated.\n"); exit 103; } # else Locked directly, juste unlock it! debug("$entry locked individually\n"); }
# # Inactivate/activate the entry # $action="$ldapmodify -p $port -h $host -D "$rootdn" -w "$rootpw" -c >> {{DEV-NULL}} 2>&1"; if ( $single == 1 ) { @record=( "dn: $entry\n", "changetype: modify\n", "$modrole: nsRoleDN\n", "nsRoleDN: cn=nsManagedDisabledRole,@suffixN\n\n" ); } else { @record=( "dn: cn=nsDisabledRole,@suffixN\n", "changetype: modify\n", "$modrole: nsRoleDN\n", "nsRoleDN: $entry\n\n" ); } open(FD,"| $action "); print FD @record; close(FD); if ( $? != 0 ) { debug("$modrole, $entry\n"); $retCode=$?>>8; exit $retCode; }
out("$entry $state.\n"); exit 0;
--- NEW FILE template-ns-inactivate.pl.in --- #{{PERL-EXEC}} # # BEGIN COPYRIGHT BLOCK # This Program is free software; you can redistribute it and/or modify it under # the terms of the GNU General Public License as published by the Free Software # Foundation; version 2 of the License. # # This Program is distributed in the hope that it will be useful, but WITHOUT # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS # FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. # # You should have received a copy of the GNU General Public License along with # this Program; if not, write to the Free Software Foundation, Inc., 59 Temple # Place, Suite 330, Boston, MA 02111-1307 USA. # # In addition, as a special exception, Red Hat, Inc. gives You the additional # right to link the code of this Program with code not covered under the GNU # General Public License ("Non-GPL Code") and to distribute linked combinations # including the two, subject to the limitations in this paragraph. Non-GPL Code # permitted under this exception must only link to the code of this Program # through those well defined interfaces identified in the file named EXCEPTION # found in the source code files (the "Approved Interfaces"). The files of # Non-GPL Code may instantiate templates or use macros or inline functions from # the Approved Interfaces without causing the resulting work to be covered by # the GNU General Public License. Only Red Hat, Inc. may make changes or # additions to the list of Approved Interfaces. You must obey the GNU General # Public License in all respects for all of the Program code and other code used # in conjunction with the Program except the Non-GPL Code covered by this # exception. If you modify this file, you may extend this exception to your # version of the file, but you are not obligated to do so. If you do not wish to # provide this exception without modification, you must delete this exception # statement from your version and license this file solely under the GPL without # exception. # # # Copyright (C) 2001 Sun Microsystems, Inc. Used by permission. # Copyright (C) 2005 Red Hat, Inc. # All rights reserved. # END COPYRIGHT BLOCK #
############################### # SUB-ROUTINES ###############################
sub usage_and_exit { print (STDERR "$cmd [-D rootdn] { -w password | -w - | -j filename } \n"); print (STDERR " [-p port] [-h host] -I DN-to-$operation\n\n"); print (STDERR "May be used to $operation a user or a domain of users\n\n"); print (STDERR "Arguments:\n"); print (STDERR " -? - help\n"); print (STDERR " -D rootdn - Provide a Directory Manager DN. Default= '$defrootdn'\n"); print (STDERR " -w password - Provide a password for the Directory Manager DN\n"); print (STDERR " -w - - Prompt for the Directory Manager's password\n"); print (STDERR " -j filename - Read the Directory Manager's password from file\n"); print (STDERR " -p port - Provide a port. Default= '$defport'\n"); print (STDERR " -h host - Provide a host name. Default= '$defhost'\n"); print (STDERR " -I DN-to-$operation - Single entry DN or role DN to $operation\n"); exit 100; }
sub debug { # print " ==> @_"; }
sub out { print "@_"; }
# -------------------------- # Check if the entry is part of a locked role: # i.e.: for each role member (nsroledn) of nsdisabledrole, check if # * it is the same as the entry # * the entry is member of role (==has nsroledn attributes), compare each of # them with the nsroledn of nsdisabledrole # * if nsroledn of nsdisabledrole are complex, go through each of them # argv[0] is the local file handler # argv[1] is the entry (may be a single entry DN or a role DN) # argv[2] is the base for the search # --------------------------
$throughRole="";
sub indirectLock { # For recursivity, file handler must be local my $L_filehandle=$_[0]; $L_filehandle++;
my $L_entry=$_[1]; # Remove useless space my @L_intern=split /([,])/,$L_entry; my $L_result=""; foreach $L_part (@L_intern) { $L_part=~s/^ +//; $L_part=~ tr/A-Z/a-z/; $L_result="$L_result$L_part"; } $L_entry=$L_result;
my $L_base=$_[2]; my $L_search; my $L_currentrole; my $L_retCode;
my $L_local;
`$ldapsearch -p $port -h $host -D "$rootdn" -w "$rootpw" -s base -b "$L_base" "(|(objectclass=*)(objectclass=ldapsubentry))" nsroledn >> {{DEV-NULL}} 2>&1 `; $retCode=$?; if ( $retCode != 0 ) { $retCode=$?>>8; return 1; }
# Check if the role is a nested role @L_Nested="$ldapsearch -p $port -h $host -D "$rootdn" -w "$rootpw" -s base -b "$L_base" "(|(objectclass=nsNestedRoleDefinition)(objectclass=ldapsubentry))" "; # L_isNested == 1 means that we are going through a nested role, so for each member of that # nested role, check that the member is below the scope of the nested $L_isNested=@L_Nested;
# Not Direct Lock, Go through roles if any $L_search="$ldapsearch -p $port -h $host -D "$rootdn" -w "$rootpw" -s base -b "$L_base" "(|(objectclass=*)(objectclass=ldapsubentry))" nsroledn ";
debug("\t-->indirectLock: check if $L_entry is part of a locked role from base $L_base\n\n");
unless (open ($L_filehandle, "$L_search |")) { out("Can't open file $L_filehandle\n"); exit; } while (<$L_filehandle>) {
s/\n //g; if (/^nsroledn: (.*)\n/) { $L_currentrole = $1;
# Remove useless space my @L_intern=split /([,])/,$L_currentrole; my $L_result=""; foreach $L_part (@L_intern) { $L_part=~s/^ +//; $L_part=~ tr/A-Z/a-z/; $L_result="$L_result$L_part"; } $L_currentrole=$L_result;
debug("\t-- indirectLock loop: current nsroledn $L_currentrole of base $L_base\n"); if ( $L_isNested == 1 ) { if ( checkScope($L_currentrole, $L_base) == 0 ) { # Scope problem probably a bad conf, skip the currentrole next; } }
if ( $L_currentrole eq $L_entry ) { # the entry is a role that is directly locked # i.e, nsroledn of nsdisabledrole contains the entry $throughRole=$L_base; $throughRole=~ tr/A-Z/a-z/;
# skipDisabled means that we've just found that the entry (which is a role) # is locked directly (==its DN is part of nsroledn attributes) # we just want to know now, if it is locked through another role # at least, one if ( $skipDisabled == 1 ) { # direct inactivation $directLocked=1; # just go through that test once $skipDisabled=0; next; } debug("\t-- 1 indirectLock: $L_currentrole locked throughRole == $throughRole\n"); return 0; }
$L_retCode=memberOf($L_currentrole, $L_entry); if ( $L_retCode == 0 && $single == 1 ) { $throughRole=$L_currentrole; $throughRole=~ tr/A-Z/a-z/; if ( $skipManaged == 1 ) { if ( $L_currentrole eq $nsManagedDisabledRole) { # Try next nsroledn $directLocked=1; $skipManaged=0; next; } } debug("\t-- 2 indirectLock: $L_currentrole locked throughRole == $throughRole\n"); return 0; }
# Only for the first iteration # the first iteration is with nsdisabledrole as base, other # loops are deeper $L_local=$skipDisabled; $skipDisabled=0; # the current nsroledn may be a complex role, just go through # its won nsroledn $L_retCode=indirectLock($L_filehandle,$L_entry, $L_currentrole);
# Because of recursivity, to keep the initial value for the first level $skipDisabled=$L_local;
if ( $L_retCode == 0 ) { $throughRole=$L_currentrole; $throughRole=~ tr/A-Z/a-z/; debug("\t-- 3 indirectLock: $L_entry locked throughRole == $throughRole\n"); return 0; } } }
close($L_filehandle);
debug("\t<--indirectLock: no more nsroledn to process\n"); return 1; }
# -------------------------- # Check if nsroledn is part of the entry attributes # argv[0] is a role DN (nsroledn attribute) # argv[1] is the entry # -------------------------- sub memberOf { my $L_nsroledn=$_[0]; $L_nsroledn=~ tr/A-Z/a-z/;
my $L_entry=$_[1];
my $L_search; my $L_currentrole;
$L_search="$ldapsearch -p $port -h $host -D "$rootdn" -w "$rootpw" -s base -b "$L_entry" "(|(objectclass=*)(objectclass=ldapsubentry))" nsrole";
debug("\t\t-->memberOf: $L_search: check if $L_entry has $L_nsroledn as nsroledn attribute\n");
open (LDAP2, "$L_search |"); while (<LDAP2>) { s/\n //g; if (/^nsrole: (.*)\n/) { $L_currentrole = $1; $L_currentrole=~ tr/A-Z/a-z/; if ( $L_currentrole eq $L_nsroledn ) { # the parm is part of the $L_entry nsroledn debug("\t\t<--memberOf: $L_entry locked through $L_nsroledn\n"); return 0; } } } close(LDAP2);
# the parm is not part of the $L_entry nsroledn debug("\t\t<--memberOf: $L_entry not locked through $L_nsroledn\n"); return 1; }
# -------------------------- # Remove the rdn of a DN # argv[0] is a DN # -------------------------- sub removeRdn { $L_entry=$_[0];
@L_entryToTest=split /([,])/,$L_entry; debug("removeRdn: entry to split: $L_entry**@L_entryToTest\n");
$newDN=""; $removeRDN=1; foreach $part (@L_entryToTest) { $part=~ s/^ +//; $part=~ tr/A-Z/a-z/; if ( $removeRDN <= 2 ) { $removeRDN=$removeRDN+1; } else { $newDN="$newDN$part"; } }
debug("removeRdn: new DN **$newDN**\n"); }
# -------------------------- # Check if L_current is below the scope of # L_nestedRole # argv[0] is a role # argv[1] is the nested role # -------------------------- sub checkScope { $L_current=$_[0]; $L_nestedRole=$_[1];
debug("checkScope: check if $L_current is below $L_nestedRole\n");
removeRdn($L_nestedRole); $L_nestedRoleSuffix=$newDN; debug("checkScope: nested role based: $L_nestedRoleSuffix\n");
$cont=1; while ( ($cont == 1) && ($L_current ne "") ) { removeRdn($L_current); $currentDn=$newDN; debug("checkScope: current DN to check: $currentDn\n");
if ( $currentDn eq $L_nestedRoleSuffix ) { debug("checkScope: DN match!!!\n"); $cont = 0; } else { $L_current=$currentDn; } }
if ( $cont == 1 ) { debug("checkScope: $_[0] and $_[1] are not compatible\n"); return 0; } else { debug("checkScope: $_[0] and $_[1] are compatible\n"); return 1; } }
############################### # MAIN ROUTINE ###############################
# Generated variable $prefix="{{DS-ROOT}}";
# Determine which command we are running if ( $0 =~ /ns-inactivate(.pl)?$/ ) { $cmd="ns-inactivate.pl"; $operation="inactivate"; $state="inactivated"; $modrole="add"; $already="already"; } elsif ( $0 =~ /ns-activate(.pl)?$/ ) { $cmd="ns-activate.pl"; $operation="activate"; $state="activated"; $modrole="delete"; $already="already"; } elsif ( $0 =~ /ns-accountstatus(.pl)?$/ ) { $cmd="ns-accountstatus.pl"; $operation="get status of"; $state="activated"; # no need for $modrole as no operation is performed $already="";
} else { out("$0: unknown command\n"); exit 100; }
debug("Running ** $cmd ** $operation\n");
$ENV{'PATH'} = '$prefix@ldapsdk_bindir@:$prefix/usr/lib:@ldapsdk_bindir@:/usr/lib'; $ENV{'LD_LIBRARY_PATH'} = '$prefix@nss_libdir@:$prefix/usr/lib:@nss_libdir@:/usr/lib'; $ENV{'SHLIB_PATH'} = '$prefix@nss_libdir@:$prefix/usr/lib:@nss_libdir@:/usr/lib';
$ldapsearch="ldapsearch -1"; $ldapmodify="ldapmodify";
# Default values $defrootdn= "{{ROOT-DN}}"; $defhost= "{{SERVER-NAME}}"; $defport= "{{SERVER-PORT}}";
# User values $rootdn= "{{ROOT-DN}}"; $rootpw= ""; $pwfile= ""; $host= "{{SERVER-NAME}}"; $port= "{{SERVER-PORT}}"; $entry= "";
$single=0; $role=0;
# Process the command line arguments while( $arg = shift) { if($arg eq "-?") { usage_and_exit(); } elsif($arg eq "-D") { $rootdn= shift @ARGV; } elsif($arg eq "-w") { $rootpw= shift @ARGV; } elsif($arg eq "-j") { $pwfile= shift @ARGV; } elsif($arg eq "-p") { $port= shift @ARGV; } elsif($arg eq "-h") { $host= shift @ARGV; } elsif($arg eq "-I") { $entry= shift @ARGV; } else { print "$arg: Unknown command line argument.\n"; usage_and_exit(); } }
if ($pwfile ne ""){ # Open file and get the password unless (open (RPASS, $pwfile)) { die "Error, cannot open password file $passwdfile\n"; } $rootpw = <RPASS>; chomp($rootpw); close(RPASS); } elsif ($rootpw eq "-"){ # Read the password from terminal die "The '-w -' option requires an extension library (Term::ReadKey) which is not\n", "part of the standard perl distribution. If you want to use it, you must\n", "download and install the module. You can find it at\n", "http://www.perl.com/CPAN/CPAN.html%5Cn"; # Remove the previous line and uncomment the following 6 lines once you have installed Term::ReadKey module. # use Term::ReadKey; # print "Bind Password: "; # ReadMode('noecho'); # $rootpw = ReadLine(0); # chomp($rootpw); # ReadMode('normal'); }
if( $rootpw eq "" ) { usage_and_exit(); }
if( $entry eq "" ) { usage_and_exit(); }
# # Check the actual existence of the entry to inactivate/activate # and at the same time, validate the various parm: port, host, rootdn, rootpw # @exist=`$ldapsearch -p $port -h $host -D "$rootdn" -w "$rootpw" -s base -b "$entry" "(objectclass=*)" dn`; $retCode1=$?; if ( $retCode1 != 0 ) { $retCode1=$?>>8; exit $retCode1; }
@isRole=`$ldapsearch -p $port -h $host -D "$rootdn" -w "$rootpw" -s base -b "$entry" "(&(objectclass=LDAPsubentry)(objectclass=nsRoleDefinition))" dn`; $nbLineRole=@isRole; $retCode2=$?; if ( $retCode2 != 0 ) { $retCode2=$?>>8; exit $retCode2; }
if ( $nbLineRole == 1 ) { debug("Groups of users\n"); $role=1; } else { debug("Single user\n"); $single=1; }
# # First of all, check the existence of the nsaccountlock attribute in the entry # $isLocked=0; if ( $single == 1 ) { $searchAccountLock="$ldapsearch -p $port -h $host -D "$rootdn" -w "$rootpw" -s base -b "$entry" "(objectclass=*)" nsaccountlock"; open (LDAP1, "$searchAccountLock |"); while (<LDAP1>) { s/\n //g; if (/^nsaccountlock: (.*)\n/) { $L_currentvalue = $1; $L_currentvalue=~ tr/A-Z/a-z/; if ( $L_currentvalue eq "true") { $isLocked=1; } elsif ( $L_currentvalue eq "false" ) { $isLocked=0; } } } close(LDAP1); } debug("Is the entry already locked? ==> $isLocked\n");
# # Get the suffix name of that entry #
# Remove the space at the beginning (just in case...) # -I "uid=jvedder , ou=People , o=sun.com" @suffix=split /([,])/,$entry; $result=""; foreach $part (@suffix) { $part=~s/^ +//; $part=~ tr/A-Z/a-z/; $result="$result$part"; } @suffixN=$result;
debug("Entry to $operation: #@suffix#\n"); debug("Entry to $operation: #@suffixN#\n");
# Get the suffix $cont=0; while ($cont == 0) { # Look if suffix is the suffix of the entry # ldapsearch -s one -b "cn=mapping tree,cn=config" "cn="uid=jvedder,ou=People,o=sun.com"" # debug("\tSuffix from the entry: #@suffixN#\n"); @mapping=`$ldapsearch -p $port -h $host -D "$rootdn" -w "$rootpw" -s one -b "cn=mapping tree, cn=config" "cn=\"@suffixN\"" cn `;
$retCode=$?; if ( $retCode != 0 ) { $retCode=$?>>8; exit $retCode; }
# If we get a result, remove the dn: # dn: cn="o=sun.com",cn=mapping tree,cn=config # cn: "o=sun.com" # shift @mapping;
foreach $res (@mapping) { # Break the string cn: "o=sun.com" into pieces @cn= split(/ /,$res);
# And remove the cn: part shift @cn;
# Now compare the suffix we extract from the mapping tree # with the suffix derived from the entry debug("\tSuffix from mapping tree: #@cn#\n"); if ( @cn eq @suffixN ) { debug("Found matching suffix\n"); $cont=1; } }
if ( $cont == 0 ) { # Remove the current rdn to try another suffix shift @suffix;
$result=""; foreach $part (@suffix) { $part=~ s/^ +//; $part=~ tr/A-Z/a-z/; $result="$result$part"; } @suffixN=$result;
debug("\t\tNothing found => go up one level in rdn #@suffix#\n"); $len=@suffix; if ( $len == 0 ) { debug("Can not find suffix. Problem\n"); $cont=2; } } } if ( $cont == 2) { out("Can not find suffix for entry $entry\n"); exit 100; }
if ( $operation eq "inactivate" ) { # # Now that we have the suffix and we know if we deal with a single entry or # a role, just try to create the COS and roles associated. # @base=( "cn=nsManagedDisabledRole,@suffixN", "cn=nsDisabledRole,@suffixN", "cn=nsAccountInactivationTmp,@suffixN", "'cn="cn=nsDisabledRole,@suffixN",cn=nsAccountInactivationTmp,@suffixN'", "cn=nsAccountInactivation_cos,@suffixN" );
$addrolescos="$ldapmodify -p $port -h $host -D "$rootdn" -w "$rootpw" -c -a >> {{DEV-NULL}} 2>&1 "; @role1=( "dn: cn=nsManagedDisabledRole,@suffixN\n", "objectclass: LDAPsubentry\n", "objectclass: nsRoleDefinition\n", "objectclass: nsSimpleRoleDefinition\n", "objectclass: nsManagedRoleDefinition\n", "cn: nsManagedDisabledRole\n\n" ); @role2=( "dn: cn=nsDisabledRole,@suffixN\n", "objectclass: top\n", "objectclass: LDAPsubentry\n", "objectclass: nsRoleDefinition\n", "objectclass: nsComplexRoleDefinition\n", "objectclass: nsNestedRoleDefinition\n", "nsRoleDN: cn=nsManagedDisabledRole,@suffixN\n", "cn: nsDisabledRole\n\n" ); @cos1=( "dn: cn=nsAccountInactivationTmp,@suffixN\n", "objectclass: top\n", "objectclass: nsContainer\n\n" ); @cos2=( "dn: cn="cn=nsDisabledRole,@suffixN",cn=nsAccountInactivationTmp,@suffixN\n", "objectclass: top\n", "objectclass: extensibleObject\n", "objectclass: costemplate\n", "objectclass: ldapsubentry\n", "cosPriority: 1\n", "nsAccountLock: true\n\n" ); @cos3=( "dn: cn=nsAccountInactivation_cos,@suffixN\n", "objectclass: top\n", "objectclass: LDAPsubentry\n", "objectclass: cosSuperDefinition\n", "objectclass: cosClassicDefinition\n", "cosTemplateDn: cn=nsAccountInactivationTmp,@suffixN\n", "cosSpecifier: nsRole\n", "cosAttribute: nsAccountLock operational\n\n" );
@all=(@role1, @role2, @cos1, @cos2, @cos3);
$i=0;
foreach $current (@base) { debug("Creating $current ??\n"); open(FD,"| $addrolescos "); print FD @{$all[$i]}; close(FD); if ( $? != 0 ) { $retCode=$?>>8; if ( $retCode == 68 ) { debug("Entry $current already exists, ignore error\n"); } else { # Probably a more serious problem. # Exit with LDAP error exit $retCode; } } else { debug("Entry $current created\n"); } $i=$i+1; } }
$skipManaged=0; $skipDisabled=0; $directLocked=0;
$nsDisabledRole="cn=nsDisabledRole,@suffixN"; $nsDisabledRole=~ tr/A-Z/a-z/;
$nsManagedDisabledRole="cn=nsManagedDisabledRole,@suffixN"; $nsManagedDisabledRole=~ tr/A-Z/a-z/;
if ( $operation eq "inactivate" ) { # Go through all the roles part of nsdisabledrole to check if the entry # is a member of one of those roles $ret=indirectLock("LDAP00", $entry, $nsDisabledRole); if ( $ret == 0 ) { if ( $throughRole ne $nsDisabledRole && $throughRole ne $nsManagedDisabledRole ) { # indirect lock out("$entry already $state through $throughRole.\n"); } else { # direct lock out("$entry already $state.\n"); } exit 100; } elsif ( $isLocked == 1 ) { # the entry is not locked through a role, may be nsaccountlock is "hardcoded" ? out("$entry already $state (probably directly).\n"); exit 103; } } elsif ( $operation eq "activate" || $operation eq "get status of" ) { $skipManaged=$single; $skipDisabled=$role;
$ret=indirectLock("LDAP00",$entry, $nsDisabledRole);
if ( $ret == 0 ) { # undirectly locked if ( $throughRole ne $nsDisabledRole && $throughRole ne $nsManagedDisabledRole ) { if ( $operation eq "activate" ) { out("$entry inactivated through $throughRole. Can not activate it individually.\n"); exit 100; } else { out("$entry inactivated through $throughRole.\n"); exit 104; } } debug("$entry locked individually\n");
if ( $operation ne "activate" ) { out("$entry inactivated.\n"); exit 103; } } elsif ( $directLocked == 0 ) { if ( $operation eq "activate" && $isLocked != 1 ) { out("$entry $already $state.\n"); exit 100; } elsif ( $isLocked != 1 ) { out("$entry $already $state.\n"); exit 102; } else { # not locked using our schema, but nsaccountlock is probably present out("$entry inactivated (probably directly).\n"); exit 103; } } elsif ( $operation ne "activate" ) { out("$entry inactivated.\n"); exit 103; } # else Locked directly, juste unlock it! debug("$entry locked individually\n"); }
# # Inactivate/activate the entry # $action="$ldapmodify -p $port -h $host -D "$rootdn" -w "$rootpw" -c >> {{DEV-NULL}} 2>&1"; if ( $single == 1 ) { @record=( "dn: $entry\n", "changetype: modify\n", "$modrole: nsRoleDN\n", "nsRoleDN: cn=nsManagedDisabledRole,@suffixN\n\n" ); } else { @record=( "dn: cn=nsDisabledRole,@suffixN\n", "changetype: modify\n", "$modrole: nsRoleDN\n", "nsRoleDN: $entry\n\n" ); } open(FD,"| $action "); print FD @record; close(FD); if ( $? != 0 ) { debug("$modrole, $entry\n"); $retCode=$?>>8; exit $retCode; }
out("$entry $state.\n"); exit 0;
--- NEW FILE template-ns-newpwpolicy.pl.in --- #{{PERL-EXEC}} # # BEGIN COPYRIGHT BLOCK # This Program is free software; you can redistribute it and/or modify it under # the terms of the GNU General Public License as published by the Free Software # Foundation; version 2 of the License. # # This Program is distributed in the hope that it will be useful, but WITHOUT # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS # FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. # # You should have received a copy of the GNU General Public License along with # this Program; if not, write to the Free Software Foundation, Inc., 59 Temple # Place, Suite 330, Boston, MA 02111-1307 USA. # # In addition, as a special exception, Red Hat, Inc. gives You the additional # right to link the code of this Program with code not covered under the GNU # General Public License ("Non-GPL Code") and to distribute linked combinations # including the two, subject to the limitations in this paragraph. Non-GPL Code # permitted under this exception must only link to the code of this Program # through those well defined interfaces identified in the file named EXCEPTION # found in the source code files (the "Approved Interfaces"). The files of # Non-GPL Code may instantiate templates or use macros or inline functions from # the Approved Interfaces without causing the resulting work to be covered by # the GNU General Public License. Only Red Hat, Inc. may make changes or # additions to the list of Approved Interfaces. You must obey the GNU General # Public License in all respects for all of the Program code and other code used # in conjunction with the Program except the Non-GPL Code covered by this # exception. If you modify this file, you may extend this exception to your # version of the file, but you are not obligated to do so. If you do not wish to # provide this exception without modification, you must delete this exception # statement from your version and license this file solely under the GPL without # exception. # # # Copyright (C) 2001 Sun Microsystems, Inc. Used by permission. # Copyright (C) 2005 Red Hat, Inc. # All rights reserved. # END COPYRIGHT BLOCK #
# enable the use of our bundled perldap with our bundled ldapsdk libraries # all of this nonsense can be omitted if the mozldapsdk and perldap are # installed in the operating system locations (e.g. /usr/lib /usr/lib/perl5) $prefix = "{{DS-ROOT}}";
$ENV{'PATH'} = '$prefix@ldapsdk_bindir@:$prefix/usr/lib:@ldapsdk_bindir@:/usr/lib'; $ENV{'LD_LIBRARY_PATH'} = '$prefix@nss_libdir@:$prefix/usr/lib:@nss_libdir@:/usr/lib'; $ENV{'SHLIB_PATH'} = '$prefix@nss_libdir@:$prefix/usr/lib:@nss_libdir@:/usr/lib'; # Add new password policy specific entries
############################################################################# # enable the use of Perldap functions require DynaLoader;
use Getopt::Std; use Mozilla::LDAP::Conn; use Mozilla::LDAP::Utils qw(:all); use Mozilla::LDAP::API qw(:api :ssl :apiv3 :constant); # Direct access to C API
############################################################################# # Default values of the variables
$opt_D = "{{ROOT-DN}}"; $opt_p = "{{SERVER-PORT}}"; $opt_h = "{{SERVER-NAME}}"; $opt_v = 0;
# Variables $ldapsearch="ldapsearch -1"; $ldapmodify="ldapmodify";
#############################################################################
sub usage { print (STDERR "ns-newpwpolicy.pl [-v] [-D rootdn] { -w password | -j filename } \n"); print (STDERR " [-p port] [-h host] -U UserDN -S SuffixDN\n\n");
print (STDERR "Arguments:\n"); print (STDERR " -? - help\n"); print (STDERR " -v - verbose output\n"); print (STDERR " -D rootdn - Directory Manager DN. Default= '$opt_D'\n"); print (STDERR " -w rootpw - password for the Directory Manager DN\n"); print (STDERR " -j filename - Read the Directory Manager's password from file\n"); print (STDERR " -p port - port. Default= $opt_p\n"); print (STDERR " -h host - host name. Default= '$opt_h'\n"); print (STDERR " -U userDN - User entry DN\n"); print (STDERR " -S suffixDN - Suffix entry DN\n"); exit 100; }
# Process the command line arguments { usage() if (!getopts('vD:w:j:p:h:U:S:'));
if ($opt_j ne ""){ die "Error, cannot open password file $opt_j\n" unless (open (RPASS, $opt_j)); $opt_w = <RPASS>; chomp($opt_w); close(RPASS); }
usage() if( $opt_w eq "" ); if ($opt_U eq "" && $opt_S eq "") { print (STDERR "Please provide at least -S or -U option.\n\n"); }
# Now, check if the user/group exists
if ($opt_S) { print (STDERR "host = $opt_h, port = $opt_p, suffixDN = "$opt_S"\n\n") if $opt_v; @base=( "cn=nsPwPolicyContainer,$opt_S", "cn="cn=nsPwPolicyEntry,$opt_S",cn=nsPwPolicyContainer,$opt_S", "cn="cn=nsPwTemplateEntry,$opt_S",cn=nsPwPolicyContainer,$opt_S", "cn=nsPwPolicy_cos,$opt_S" );
$ldapadd="$ldapmodify -p $opt_p -h $opt_h -D "$opt_D" -w "$opt_w" -c -a 2>&1"; $modifyCfg="$ldapmodify -p $opt_p -h $opt_h -D "$opt_D" -w "$opt_w" -c 2>&1";
@container=( "dn: cn=nsPwPolicyContainer,$opt_S\n", "objectclass: top\n", "objectclass: nsContainer\n\n" ); @pwpolicy=( "dn: cn="cn=nsPwPolicyEntry,$opt_S",cn=nsPwPolicyContainer,$opt_S\n", "objectclass: top\n", "objectclass: ldapsubentry\n", "objectclass: passwordpolicy\n\n" ); @template=( "dn: cn="cn=nsPwTemplateEntry,$opt_S",cn=nsPwPolicyContainer,$opt_S\n", "objectclass: top\n", "objectclass: extensibleObject\n", "objectclass: costemplate\n", "objectclass: ldapsubentry\n", "cosPriority: 1\n", "pwdpolicysubentry: cn="cn=nsPwPolicyEntry,$opt_S",cn=nsPwPolicyContainer,$opt_S\n\n" ); @cos=( "dn: cn=nsPwPolicy_cos,$opt_S\n", "objectclass: top\n", "objectclass: LDAPsubentry\n", "objectclass: cosSuperDefinition\n", "objectclass: cosPointerDefinition\n", "cosTemplateDn: cn="cn=nsPwTemplateEntry,$opt_S",cn=nsPwPolicyContainer,$opt_S\n", "cosAttribute: pwdpolicysubentry default operational-default\n\n" );
@all=(@container, @pwpolicy, @template, @cos);
$i=0;
foreach $current (@base) { open(FD,"| $ldapadd"); print FD @{$all[$i]}; close(FD); if ( $? != 0 ) { $retCode=$?>>8; if ( $retCode == 68 ) { print( STDERR "Entry "$current" already exists. Please ignore the error\n\n"); } else { # Probably a more serious problem. # Exit with LDAP error print(STDERR "Error $retcode while adding "$current". Exiting.\n"); exit $retCode; } } else { print( STDERR "Entry "$current" created\n\n") if $opt_v; } $i=$i+1; }
$modConfig = "dn:cn=config\nchangetype: modify\nreplace:nsslapd-pwpolicy-local\nnsslapd-pwpolicy-local: on\n\n"; open(FD,"| $modifyCfg "); print(FD $modConfig); close(FD); $retcode = $?; if ( $retcode != 0 ) { print( STDERR "Error $retcode while modifing "cn=config". Exiting.\n" ); exit ($retcode); } else { print( STDERR "Entry "cn=config" modified\n\n") if $opt_v; } } # end of $opt_S
if ($opt_U) { my $norm_opt_U = normalizeDN($opt_U); print (STDERR "host = $opt_h, port = $opt_p, userDN = "$norm_opt_U"\n\n") if $opt_v; $retcode = `$ldapsearch -h $opt_h -p $opt_p -b "$norm_opt_U" -s base ""`; if ($retcode != 0 ) { print( STDERR "the user entry $norm_opt_U does not exist. Exiting.\n"); exit ($retcode); } print( STDERR "the user entry $norm_opt_U found..\n\n") if $opt_v; # Now, get the parentDN @rdns = ldap_explode_dn($norm_opt_U, 0); shift @rdns; $parentDN = join(',', @rdns);
print (STDERR "parentDN is $parentDN\n\n") if $opt_v;
@base=( "cn=nsPwPolicyContainer,$parentDN", "cn="cn=nsPwPolicyEntry,$norm_opt_U",cn=nsPwPolicyContainer,$parentDN" );
$ldapadd="$ldapmodify -p $opt_p -h $opt_h -D "$opt_D" -w "$opt_w" -c -a 2>&1"; $modifyCfg="$ldapmodify -p $opt_p -h $opt_h -D "$opt_D" -w "$opt_w" -c 2>&1";
@container=( "dn: cn=nsPwPolicyContainer,$parentDN\n", "objectclass: top\n", "objectclass: nsContainer\n\n" ); @pwpolicy=( "dn: cn="cn=nsPwPolicyEntry,$norm_opt_U",cn=nsPwPolicyContainer,$parentDN\n", "objectclass: top\n", "objectclass: ldapsubentry\n", "objectclass: passwordpolicy\n\n" );
@all=(@container, @pwpolicy);
$i=0;
foreach $current (@base) { open(FD,"| $ldapadd "); print FD @{$all[$i]}; close(FD); if ( $? != 0 ) { $retCode=$?>>8; if ( $retCode == 68 ) { print( STDERR "Entry $current already exists. Please ignore the error\n\n"); } else { # Probably a more serious problem. # Exit with LDAP error print(STDERR "Error $retcode while adding "$current". Exiting.\n"); exit $retCode; } } else { print( STDERR "Entry $current created\n\n") if $opt_v; } $i=$i+1; }
$target = "cn="cn=nsPwPolicyEntry,$norm_opt_U",cn=nsPwPolicyContainer,$parentDN"; $modConfig = "dn: $norm_opt_U\nchangetype: modify\nreplace:pwdpolicysubentry\npwdpolicysubentry: $target\n\n"; open(FD,"| $modifyCfg "); print(FD $modConfig); close(FD); $retcode = $?; if ( $retcode != 0 ) { print( STDERR "Error $retcode while modifing $norm_opt_U. Exiting.\n" ); exit ($retcode); } else { print( STDERR "Entry "$norm_opt_U" modified\n\n") if $opt_v; }
$modConfig = "dn:cn=config\nchangetype: modify\nreplace:nsslapd-pwpolicy-local\nnsslapd-pwpolicy-local: on\n\n"; open(FD,"| $modifyCfg "); print(FD $modConfig); close(FD); $retcode = $?; if ( $retcode != 0 ) { print( STDERR "Error $retcode while modifing "cn=config". Exiting.\n" ); exit ($retcode); } else { print( STDERR "Entry "cn=config" modified\n\n") if $opt_v; } } # end of $opt_U }
--- NEW FILE template-repl-monitor-cgi.pl.in --- #{{PERL-EXEC}} # # BEGIN COPYRIGHT BLOCK # This Program is free software; you can redistribute it and/or modify it under # the terms of the GNU General Public License as published by the Free Software # Foundation; version 2 of the License. # # This Program is distributed in the hope that it will be useful, but WITHOUT # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS # FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. # # You should have received a copy of the GNU General Public License along with # this Program; if not, write to the Free Software Foundation, Inc., 59 Temple # Place, Suite 330, Boston, MA 02111-1307 USA. # # In addition, as a special exception, Red Hat, Inc. gives You the additional # right to link the code of this Program with code not covered under the GNU # General Public License ("Non-GPL Code") and to distribute linked combinations # including the two, subject to the limitations in this paragraph. Non-GPL Code # permitted under this exception must only link to the code of this Program # through those well defined interfaces identified in the file named EXCEPTION # found in the source code files (the "Approved Interfaces"). The files of # Non-GPL Code may instantiate templates or use macros or inline functions from # the Approved Interfaces without causing the resulting work to be covered by # the GNU General Public License. Only Red Hat, Inc. may make changes or # additions to the list of Approved Interfaces. You must obey the GNU General # Public License in all respects for all of the Program code and other code used # in conjunction with the Program except the Non-GPL Code covered by this # exception. If you modify this file, you may extend this exception to your # version of the file, but you are not obligated to do so. If you do not wish to # provide this exception without modification, you must delete this exception # statement from your version and license this file solely under the GPL without # exception. # # # Copyright (C) 2005 Red Hat, Inc. # All rights reserved. # END COPYRIGHT BLOCK #
use Cgi;
$params = ""; $params .= " -h $cgiVars{'servhost'}" if $cgiVars{'servhost'}; $params .= " -p $cgiVars{'servport'}" if $cgiVars{'servport'}; $params .= " -f $cgiVars{'configfile'}" if $cgiVars{'configfile'}; $params .= " -t $cgiVars{'refreshinterval'}" if $cgiVars{'refreshinterval'}; if ($cgiVars{'admurl'}) { $admurl = "$cgiVars{'admurl'}"; if ( $ENV{'QUERY_STRING'} ) { $admurl .= "?$ENV{'QUERY_STRING'}"; } elsif ( $ENV{'CONTENT_LENGTH'} ) { $admurl .= "?$Cgi::CONTENT"; } $params .= " -u "$admurl""; } $siteroot = $cgiVars{'siteroot'}; $prefix = "{{DS-ROOT}}";
$ENV{'PATH'} = '$prefix@ldapsdk_bindir@:$prefix/usr/lib:@ldapsdk_bindir@:/usr/lib'; $ENV{'LD_LIBRARY_PATH'} = '$prefix@nss_libdir@:$prefix/usr/lib:@nss_libdir@:/usr/lib'; $ENV{'SHLIB_PATH'} = '$prefix@nss_libdir@:$prefix/usr/lib:@nss_libdir@:/usr/lib';
# Save user-specified parameters as cookies in monreplication.properties. # Sync up with the property file so that monreplication2 is interval, and # monreplication3 the config file pathname. $propertyfile = "$siteroot/bin/admin/admin/bin/property/monreplication.properties"; $edit1 = "s#monreplication2=.*#monreplication2=$cgiVars{'refreshinterval'}#;"; $edit2 = "s#^monreplication3=.*#monreplication3=$cgiVars{'configfile'}#;"; system("perl -p -i.bak -e "$edit1" -e "$edit2" $propertyfile");
# Now the real work $replmon = "$siteroot/bin/slapd/admin/scripts/template-repl-monitor.pl"; system("perl -I$siteroot/lib/perl/arch -I$siteroot/lib/perl $replmon $params");
--- NEW FILE template-repl-monitor.pl.in --- #{{PERL-EXEC}} # BEGIN COPYRIGHT BLOCK # This Program is free software; you can redistribute it and/or modify it under # the terms of the GNU General Public License as published by the Free Software # Foundation; version 2 of the License. # # This Program is distributed in the hope that it will be useful, but WITHOUT # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS # FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. # # You should have received a copy of the GNU General Public License along with # this Program; if not, write to the Free Software Foundation, Inc., 59 Temple # Place, Suite 330, Boston, MA 02111-1307 USA. # # In addition, as a special exception, Red Hat, Inc. gives You the additional # right to link the code of this Program with code not covered under the GNU # General Public License ("Non-GPL Code") and to distribute linked combinations # including the two, subject to the limitations in this paragraph. Non-GPL Code # permitted under this exception must only link to the code of this Program # through those well defined interfaces identified in the file named EXCEPTION # found in the source code files (the "Approved Interfaces"). The files of # Non-GPL Code may instantiate templates or use macros or inline functions from # the Approved Interfaces without causing the resulting work to be covered by # the GNU General Public License. Only Red Hat, Inc. may make changes or # additions to the list of Approved Interfaces. You must obey the GNU General # Public License in all respects for all of the Program code and other code used # in conjunction with the Program except the Non-GPL Code covered by this # exception. If you modify this file, you may extend this exception to your # version of the file, but you are not obligated to do so. If you do not wish to # provide this exception without modification, you must delete this exception # statement from your version and license this file solely under the GPL without # exception. # # # Copyright (C) 2001 Sun Microsystems, Inc. Used by permission. # Copyright (C) 2005 Red Hat, Inc. # All rights reserved. # END COPYRIGHT BLOCK ############################################################################## # # FILE: repl-monitor.pl # # SYNOPSIS: # repl-monitor.pl -f configuration-file [-h host] [-p port] [-r] \ # [-u refresh-url] [-t refresh-interval] # # repl-monitor.pl -v # # DESCRIPTION: # Given an LDAP replication "supplier" server, crawl over all the ldap # servers via direct or indirect replication agreements. # For each master replica discovered, display the maxcsn of the master # and the replication status of all its lower level replicas. # All output is in HTML. # # OPTIONS: # # -f configuration-file # The configuration file contains the sections for the connection # parameters, the server alias, and the thresholds for different colors # when display the time lags between consumers and master. # If the Admin Server is running on Windows, the configuration-file # name may have format "D:/opt/replmon.conf". # # The connection parameter section consists of the section name # followed by one of more connection parameter entries: # # [connection] # host:port:binddn:bindpwd:bindcert # host:port=shadowport:binddn:bindpwd:bindcert # ... # # where host:port default (*:*) to that in a replication agreement, # binddn default (*) to "cn=Directory Manager", and bindcert is the # pathname of cert db if you want the script to connect to the server # via SSL. If bindcert is omitted, the connection will be simple # bind. # "port=shadowport" means to use shadowport instead of port if port # is specified in the replication agreement. This is useful when # for example, ssl port is specified in a replication agreement, # but you can't access the cert db from the machine where this # script is running. So you could let the script to map the ssl # port to a non-ssl port and use the simple bind. # # A server may have a dedicated or a share entry in the connection # section. The script will find out the most matched entry for a given # server. For example, if all the ldap servers except host1 share the # same binddn and bindpassword, the connection section then just need # two entries: # # [connection] # *:*:binddn:bindpassword: # host1:*:binddn:bindpassword: # # If a host:port is assigned an alias, then the alias instead of # host:port will be displayed in The output file. Each host:port # can have only one alias. But each alias may be used by more than # one host:port. # # [alias] # alias = host:port # ... # # CSN time lags between masters and consumers might be displayed in # different colors based on their range. The thresholds for different # colors may be specified in color section: # # [color] # lowmark (in minutes) = color # ... # If the color section or color entry is missing, the default color # set is: green for [0-5) minutes lag, yellow [5-60), and red 60 and more. # # -h host # Initial replication supplier's host. Default to the current host. # # -p port # Initial replication supplier's port. Default to 389. # # -r If specified, -r causes the routine to be entered without printing # HTML header information. This is suitable when making multiple calls # to this routine (e.g. when specifying multiple, different, "unrelated" # supplier servers) and expecting a single HTML output. # # -t refresh-interval # Specify the refresh interval in seconds. This option has to be # jointly used with option -u. # # -u refresh-url # The output HTML file may invoke a CGI program periodically. If # this CGI program in turn calls this script, the effect is that # the output HTML file would automatically refresh itself. This # is useful for continuing monitoring. See also option -t. # # -v Print out the version of this script # # DIAGNOSTICS: # There are several ways to invoke this script if you got error # "Can't locate Mozilla/LDAP/Conn.pm in @INC", or # "usage: Undefined variable": # # 1. Set the first line of the script to #!<DSHOME>/bin/slapd/admin/bin/perl # and run this script directly. # # 2. Run # <DSHOME>/bin/slapd/admin/bin/perl repl-monitor.pl # # 3. Set environment variable PERL5LIB to your Perl lib dirs where # Mozilla::LDAP module can be located. This should be under serverroot/lib/perl # e.g. PERL5LIB="serverroot/lib/perl/arch:serverroot/lib/perl" # # 4. Set LD_LIBRARY_PATH (or SHLIB_PATH) to point to the location of our # bundled shared libraries e.g. LD_LIBRARY_PATH="serverroot/lib" # # 5. Invoke the script as follows if <MYPERLDIR> (serverroot/lib/perl) contains # Mozilla/LDAP: # <MYPERLDIR>/bin/perl -I <MYPERLDIR>/arch -I <MYPERLDIR> repl-monitor.pl # ############################################################################# # enable the use of our bundled perldap with our bundled ldapsdk libraries # all of this nonsense can be omitted if the mozldapsdk and perldap are # installed in the operating system locations (e.g. /usr/lib /usr/lib/perl5) # this script is always invoked by repl-monitor-cgi.pl, which sets all of these # If using this script standalone, be sure to set the shared lib path and # the path to the perldap modules. $usage = "\nusage: $0 -f configuration-file [-h host] [-p port] [-r] [-u refresh-url] [-t refresh-interval]\n\nor : $0 -v\n";
use Getopt::Std; # parse command line arguments use Mozilla::LDAP::Conn; # LDAP module for Perl use Mozilla::LDAP::Utils qw(normalizeDN); # LULU, utilities. use Mozilla::LDAP::API qw(:api :ssl :apiv3 :constant); # Direct access to C API use Time::Local; # to convert GMT Z strings to localtime
# # Global variables # $product = "Directory Server Replication Monitor"; $version = "Version 1.0"; # # ldap servers given or discovered from the replication agreements: # @servers = (host:port=shadowport:binddn:password:cert_db) # # entries read from the connection section of the configuration file: # @allconnections = (host:port=shadowport:binddn:password:cert_db) # # aliases of ldap servers read from the configuration file: # %allaliases{$host:$port}= (alias) # # replicas discovered on all ldap servers # @allreplicas = (server#:replicaroot:replicatype:serverid:replicadn) # # ruvs retrieved from all replicas # @allruvs{replica#:masterid} = (rawcsn:decimalcsn;mon/day/year hh:mi:ss) # # agreements discovered on all ldap supplier servers: # @allagreements = (supplier_replica#:consumer#:conntype:schedule:status) # the array may take another format after the consumer replicas are located: # @allagreements = (supplier_replica#:consumer_replica#:conntype:schedule:status) #
#main { # turn off buffered I/O $| = 1;
# Check for legal options if (!getopts('h:p:f:ru:t:v')) { print $usage; exit -1; }
if ($opt_v) { print "$product - $version\n"; exit; }
$interval = $opt_t; $interval = 300 if ( !$interval || $interval <= 0 );
# Get current date/time $nowraw = localtime(); ($wday, $mm, $dd, $tt, $yy) = split(/ /, $nowraw); $now = "$wday $mm $dd $yy $tt";
# if no -r (Reenter and skip html header), print html header if (!$opt_r) { # print the HTML header &print_html_header; } else { # print separator for new replication set print "<hr width=90% size=3><br>\n"; }
exit -1 if &validateArgs < 0; exit if &read_cfg_file ($opt_f) < 0;
# Start with the given host and port # The index names in %ld are defined in Mozilla::LDAP::Utils::ldapArgs() &add_server ("$ld{host}:$ld{port}:$ld{bind}:$ld{pswd}:$ld{cert}");
$serveridx = 0; while ($serveridx <= $#servers) { if (&get_replicas ($serveridx) != 0 && $serveridx == 0) { my ($host, $port, $binddn) = split (/:/, $servers[0]); print("Login to $host:$port as "$binddn" failed\n"); exit; } $serveridx++; }
&find_consumer_replicas; &process_suppliers;
# All done! - well, for the current invokation only # print "</body></html>\n"; exit; }
sub validateArgs { my ($rc) = 0;
%ld = Mozilla::LDAP::Utils::ldapArgs();
if (!$opt_v && !$opt_f) { print "<p>Error: Missing configuration file.\n"; print "<p>If you need help on the configuration file, Please go back and click the Help button.\n"; #print $usage; # Don't show usage in CGI $rc = -1; } elsif (!$opt_h) { chop ($ld{"host"} = `hostname`); }
return $rc; }
sub read_cfg_file { my ($fn) = @_; unless (open(CFGFILEHANDLE, $fn)) { print "<p>Error: Can't open "$fn": $!.\n"; print "<p>If you need help on the configuration file, Please go back and click the Help button.\n"; return -1; } $section = 0; while (<CFGFILEHANDLE>) { next if (/^\s*#/ || /^\s*$/); chop ($_); if (m/^[(.*)]/) { $section = $1; } else { if ( $section =~ /conn/i ) { push (@allconnections, $_); } elsif ( $section =~ /alias/i ) { m/^\s*(\S.*)\s*=\s*(\S+)/; $allaliases {$2} = $1; } elsif ( $section =~ /color/i ) { m/^\s*(-?\d+)\s*=\s*(\S+)/; $allcolors {$1} = $2; } } } if ( ! keys (%allcolors) ) { $allcolors {0} = "#ccffcc"; #apple green $allcolors {5} = "#ffffcc"; #cream yellow $allcolors {60} = "#ffcccc"; #pale pink } @colorkeys = sort (keys (%allcolors)); close (CFGFILEHANDLE); return 0; }
sub get_replicas { my ($serveridx) = @_; my ($conn, $host, $port, $shadowport, $binddn, $bindpwd, $bindcert); my ($others); my ($replica, $replicadn); my ($ruv, $replicaroot, $replicatype, $serverid, $masterid, $maxcsn); my ($type, $flag, $i); my ($myridx, $ridx, $cidx);
# # Bind to the server # ($host, $port, $binddn, $bindpwd, $bindcert) = split (/:/, "$servers[$serveridx]", 5);
($port, $shadowport) = split (/=/, $port); $shadowport = $port if !$shadowport;
$conn = new Mozilla::LDAP::Conn ($host, $shadowport, "$binddn", $bindpwd, $bindcert);
return -1 if (!$conn);
# # Get all the replica on the server # $myridx = $#allreplicas + 1; $replica = $conn->search ("cn=mapping tree,cn=config", "sub", "(objectClass=nsDS5Replica)", 0, qw(nsDS5ReplicaRoot nsDS5ReplicaType nsDS5Flags nsDS5ReplicaId)); while ($replica) { $replicadn = $replica->getDN; $replicaroot = normalizeDN ($replica->{nsDS5ReplicaRoot}[0]); $type = $replica->{nsDS5ReplicaType}[0]; $flag = $replica->{nsDS5Flags}[0]; $serverid = $replica->{nsDS5ReplicaId}[0];
# flag = 0: change log is not created # type = 2: read only replica # type = 3: updatable replica $replicatype = $flag == 0 ? "consumer" : ($type == 2 ? "hub" : "master");
push (@allreplicas, "$serveridx:$replicaroot:$replicatype:$serverid:$replicadn");
$replica = $conn->nextEntry (); }
# # Get ruv for each replica # for ($ridx = $myridx; $ridx <= $#allreplicas; $ridx++) {
$replicaroot = $1 if ($allreplicas[$ridx] =~ /^\d+:([^:]*)/); # do a one level search with nsuniqueid in the filter - this will force the use of the # nsuniqueid index instead of the entry dn index, which seems to be unreliable in # heavily loaded servers $ruv = $conn->search($replicaroot, "one", "(&(nsuniqueid=ffffffff-ffffffff-ffffffff-ffffffff)(objectClass=nsTombstone))", 0, qw(nsds50ruv nsruvReplicaLastModified)); next if !$ruv; # this should be an error case . . .
for ($ruv->getValues('nsds50ruv')) { if (m/{replica\s+(\d+).+?}\s*\S+\s*(\S+)/i) { $masterid = $1; $maxcsn = &to_decimal_csn ($2); $allruvs {"$ridx:$masterid"} = "$2:$maxcsn"; } }
for ($ruv->getValues('nsruvReplicaLastModified')) { if (m/{replica\s+(\d+).+?}\s*(\S+)/i) { $masterid = $1; $lastmodifiedat = hex($2); my ($sec, $min, $hour, $mday, $mon, $year) = localtime ($lastmodifiedat); $mon++; $year += 1900; $hour = "0".$hour if ($hour < 10); $min = "0".$min if ($min < 10); $sec = "0".$sec if ($sec < 10); $allruvs {"$ridx:$masterid"} .= ";$mon/$mday/$year $hour:$min:$sec"; } } }
# # Get all agreements for each supplier replica # for ($ridx = $myridx; $ridx <= $#allreplicas; $ridx++) { $_ = $allreplicas[$ridx];
# Skip consumers next if m/:consumer:/i;
m/:([^:]*)$/; $replicadn = $1; my @attrlist = qw(cn nsds5BeginReplicaRefresh nsds5replicaUpdateInProgress nsds5ReplicaLastInitStatus nsds5ReplicaLastInitStart nsds5ReplicaLastInitEnd nsds5replicaReapActive nsds5replicaLastUpdateStart nsds5replicaLastUpdateEnd nsds5replicaChangesSentSinceStartup nsds5replicaLastUpdateStatus nsds5ReplicaHost nsds5ReplicaPort nsDS5ReplicaBindMethod nsds5ReplicaUpdateSchedule); $agreement = $conn->search("$replicadn", "sub", "(objectClass=nsDS5ReplicationAgreement)", 0, @attrlist); while ($agreement) {
my %agmt = (); # Push consumer to server stack if we have not already $host = ($agreement->getValues('nsDS5ReplicaHost'))[0]; $port = ($agreement->getValues('nsDS5ReplicaPort'))[0]; $cidx = &add_server ("$host:$port");
for (@attrlist) { $agmt{$_} = ($agreement->getValues($_))[0]; } if ($agmt{nsDS5ReplicaBindMethod} =~ /simple/i) { $agmt{nsDS5ReplicaBindMethod} = 'n'; } if (!$agmt{nsds5ReplicaUpdateSchedule} || ($agmt{nsds5ReplicaUpdateSchedule} eq '0000-2359 0123456') || ($agmt{nsds5ReplicaUpdateSchedule} eq '*') || ($agmt{nsds5ReplicaUpdateSchedule} eq '* *')) { $agmt{nsds5ReplicaUpdateSchedule} = 'always in sync'; }
$agmt{ridx} = $ridx; $agmt{cidx} = $cidx; push @allagreements, %agmt;
$agreement = $conn->nextEntry (); } }
$conn->close; }
# # Initially, the agreements have consumer host:port info instead of # replica info. This routine will find the consumer replica info # sub find_consumer_replicas { my ($m_ridx); # index of master's replica my ($s_ridx); # index of supplier's replica my ($c_ridx); # index of consumer's replica my ($c_sidx); # index of consumer server my ($remainder); # my ($s_replicaroot); # supplier replica root my ($c_replicaroot); # consumer replica root my ($j, $val);
# # Loop through every agreement defined on the current supplier replica # foreach (@allagreements) { $s_ridx = $_->{ridx}; $c_sidx = $_->{cidx}; $s_replicaroot = $1 if ($allreplicas[$s_ridx] =~ /^\d+:([^:]*)/); $c_replicaroot = "";
# $c_ridx will be assigned to -$c_sidx # if the condumer is not accessible # $c_sidx will not be zero since it's # not the first server. $c_ridx = -$c_sidx; # $c_sidx will not be zero
# Loop through consumer's replicas and find # the counter part for the current supplier # replica for ($j = 0; $j <= $#allreplicas; $j++) {
# Get a replica on consumer # I'm not sure what's going on here, but possibly could be made # much simpler with normalizeDN and/or ldap_explode_dn if ($allreplicas[$j] =~ /^$c_sidx:([^:]*)/) { $val = $1;
# We need to find out the consumer # replica that matches the supplier # replicaroot most. if ($s_replicaroot =~ /^.*$val$/i && length ($val) >= length ($c_replicaroot)) { $c_ridx = $j;
# Avoid case-sensitive comparison last if (length($s_replicaroot) == length($val)); $c_replicaroot = $val; } } } $_->{ridx} = $s_ridx; $_->{cidx} = $c_ridx; } }
sub process_suppliers { my ($ridx, $mid, $maxcsn);
$mid = "";
$last_sidx = -1; # global variable for print html page
for ($ridx = 0; $ridx <= $#allreplicas; $ridx++) {
# Skip consumers and hubs next if $allreplicas[$ridx] !~ /:master:(\d+):/i; $mid = $1;
# Skip replicas without agreements defined yet next if (! grep {$_->{ridx} == $ridx} @allagreements);
$maxcsn = &print_master_header ($ridx, $mid); if ( "$maxcsn" != "none" ) { &print_consumer_header (); &print_consumers ($ridx, $mid); } &print_supplier_end; }
if ($mid eq "") { print "<p>The server is not a master or it has no replication agreement\n"; } }
sub print_master_header { my ($ridx, $mid) = @_; my ($myruv) = $allruvs {"$ridx:$mid"}; my ($maxcsnval) = split ( /;/, "$myruv" ); my ($maxcsn) = &to_string_csn ($maxcsnval); my ($sidx, $replicaroot, $replicatype, $serverid) = split (/:/, $allreplicas[$ridx]);
# Print the master name if ( $last_sidx != $sidx ) { my ($ldapurl) = &get_ldap_url ($sidx, $sidx); &print_legend if ( $last_sidx < 0); print "<p><p><hr><p>\n"; print "\n<p><center class=page-subtitle><font color=#0099cc>\n"; print "Master:  $ldapurl</center>\n"; $last_sidx = $sidx; }
# Print the current replica info onthe master print "\n<p><table border=0 cellspacing=1 cellpadding=6 cols=10 width=100% class=bgColor9>\n";
print "\n<tr><td colspan=10><center>\n"; print "<font class=areatitle>Replica ID: </font>"; print "<font class=text28>$serverid</font>\n";
print "<font class=areatitle>Replica Root: </font>"; print "<font class=text28>$replicaroot</font>\n";
print "<font class=areatitle>Max CSN: </font>"; print "<font class=text28>$maxcsn</font>\n";
return $maxcsn; }
sub print_consumer_header { #Print the header of consumer print "\n<tr class=bgColor16>\n"; print "<th nowrap>Receiver</th>\n"; print "<th nowrap>Time Lag</th>\n"; print "<th nowrap>Max CSN</th>\n"; print "<th nowrap>Last Modify Time</th>\n"; print "<th nowrap>Supplier</th>\n"; print "<th nowrap>Sent/Skipped</th>\n"; print "<th nowrap>Update Status</th>\n"; print "<th nowrap>Update Started</th>\n"; print "<th nowrap>Update Ended</th>\n"; print "<th nowrap colspan=2>Schedule</th>\n"; print "<th nowrap>SSL?</th>\n"; print "</tr>\n"; }
sub print_consumers { my ($m_ridx, $mid) = @_; my ($ignore, $m_replicaroot) = split (/:/, $allreplicas[$m_ridx]); my (@consumers, @ouragreements, @myagreements); my ($s_ridx, $c_ridx, $conntype, $schedule, $status); my ($c_maxcsn_str, $lag, $markcolor); my ($c_replicaroot, $c_replicatype); my ($first_entry); my ($nrows); my ($found);
undef @ouragreements;
# Collect all the consumer replicas for the current master replica push (@consumers, $m_ridx); foreach (@consumers) { $s_ridx = $_; for (@allagreements) { next if ($_->{ridx} != $s_ridx); $c_ridx = $_->{cidx}; next if $c_ridx == $m_ridx; push @ouragreements, $_; $found = 0; foreach (@consumers) { if ($_ == $c_ridx) { $found = 1; last; } } push (@consumers, $c_ridx) if !$found; } }
# Print each consumer replica my ($myruv) = $allruvs {"$m_ridx:$mid"}; my ($m_maxcsn) = split ( /;/, "$myruv" ); foreach (@consumers) { $c_ridx = $_; next if $c_ridx == $m_ridx;
if ($c_ridx >= 0) { $myruv = $allruvs {"$c_ridx:$mid"}; ($c_maxcsn, $c_lastmodified) = split ( /;/, "$myruv" ); ($c_maxcsn_str, $lag, $markcolor) = &cacl_time_lag ($m_maxcsn, $c_maxcsn); $c_maxcsn_str =~ s/ /<br>/; ($c_sidx, $c_replicaroot, $c_replicatype) = split (/:/, $allreplicas[$c_ridx]); $c_replicaroot = "same as master" if $m_replicaroot eq $c_replicaroot; } else { # $c_ridx is actually -$c_sidx when c is not available $c_sidx = -$c_ridx; $c_maxcsn_str = "_"; $lag = "n/a"; $markcolor = red; $c_replicaroot = "_"; $c_replicatype = "_"; }
$nrows = 0; foreach (@ouragreements) { next if ($_->{cidx} != $c_ridx); $nrows++; }
$first_entry = 1; foreach (@ouragreements) { next if ($_->{cidx} != $c_ridx); $s_ridx = $_->{ridx}; $conntype = $_->{nsDS5ReplicaBindMethod}; $status = $_->{nsds5replicaLastUpdateStatus}; $schedule = $_->{nsds5ReplicaUpdateSchedule}; $s_sidx = $1 if $allreplicas [$s_ridx] =~ /^(\d+):/; $s_ldapurl = &get_ldap_url ($s_sidx, "n/a");
# Print out the consumer's replica and ruvs print "\n<tr class=bgColor13>\n"; if ($first_entry) { $first_entry = 0; $c_ldapurl = &get_ldap_url ($c_sidx, $conntype); print "<td rowspan=$nrows width=5% class=bgColor5>$c_ldapurl<BR>Type: $c_replicatype</td>\n"; print "<td rowspan=$nrows width=5% nowrap bgcolor=$markcolor><center>$lag</center></td>\n"; print "<td rowspan=$nrows width=15% nowrap>$c_maxcsn_str</td>\n"; print "<td rowspan=$nrows width=15% nowrap>$c_lastmodified</td>\n"; } print "<td width=5% nowrap><center>$s_ldapurl</center></td>\n"; my $changecount = $_->{nsds5replicaChangesSentSinceStartup}; if ( $changecount =~ /^$mid:(\d+)/(\d+) / || $changecount =~ / $mid:(\d+)/(\d+) / ) { $changecount = "$1 / $2"; } elsif ( $changecount =~ /^(\d+)$/ ) { $changecount = $changecount . " / " . "$_->{nsds5replicaChangesSkippedSinceStartup}"; } else { $changecount = "0 / 0"; } print "<td width=3% nowrap>$changecount</td>\n"; my $redfontstart = ""; my $redfontend = ""; if ($status =~ /error/i) { $redfontstart = "<font color='red'>"; $redfontend = "</font>"; } elsif ($status =~ /^(\d+) /) { if ( $1 != 0 ) { # warning $redfontstart = "<font color='#FF7777'>"; $redfontend = "</font>"; } } print "<td width=20% nowrap>$redfontstart$status$redfontend</td>\n"; print "<td nowrap>", &format_z_time($_->{nsds5replicaLastUpdateStart}), "</td>\n"; print "<td nowrap>", &format_z_time($_->{nsds5replicaLastUpdateEnd}), "</td>\n"; if ( $schedule =~ /always/i ) { print "<td colspan=2 width=10% nowrap>$schedule</td>\n"; } else { my ($ndays, @days); $schedule =~ /(\d\d)(\d\d)-(\d\d)(\d\d) (\d+)/; print "<td width=10% nowrap>$1:$2-$3:$4</td>\n"; $ndays = $5; $ndays =~ s/(\d)/$1,/g; @days = (Sun,Mon,Tue,Wed,Thu,Fri,Sat)[eval $ndays]; print "<td width=10% nowrap>@days</td>\n"; } print "<td width=3% nowrap class=bgColor5>$conntype</td>\n"; } } }
sub cacl_time_lag { my ($s_maxcsn, $c_maxcsn) = @_; my ($markcolor); my ($csn_str); my ($s_tm, $c_tm, $lag_tm, $lag_str, $hours, $minute);
$csn_str = &to_string_csn ($c_maxcsn);
if ($s_maxcsn && !$c_maxcsn) { $lag_str = "- ?:??:??"; $markcolor = &get_color (36000); # assume consumer has big latency } elsif (!$s_maxcsn && $c_maxcsn) { $lag_str = "+ ?:??:??"; $markcolor = &get_color (1); # consumer is ahead of supplier } elsif ($s_maxcsn le $c_maxcsn) { $lag_str = "0:00:00"; $markcolor = &get_color (0); } else { my ($rawcsn, $decimalcsn) = split (/:/, $s_maxcsn); ($s_tm) = split(/ /, $decimalcsn);
($rawcsn, $decimalcsn) = split (/:/, $c_maxcsn); ($c_tm) = split(/ /, $decimalcsn); if ($s_tm > $c_tm) { $lag_tm = $s_tm - $c_tm; $lag_str = "- "; $markcolor = &get_color ($lag_tm); } else { $lag_tm = $c_tm - $s_tm; $lag_str = "+ "; $markcolor = $allcolors{ $colorkeys[0] }; # no delay } $hours = int ($lag_tm / 3600); $lag_str .= "$hours:";
$lag_tm = $lag_tm % 3600; $minutes = int ($lag_tm / 60); $minutes = "0".$minutes if ($minutes < 10); $lag_str .= "$minutes:";
$lag_tm = $lag_tm % 60; $lag_tm = "0".$lag_tm if ($lag_tm < 10); $lag_str .= "$lag_tm"; } return ($csn_str, $lag_str, $markcolor); }
# # The subroutine would append a new entry to the end of # @servers if the host and port are new to @servers. # sub add_server { my ($host, $port, $binddn, $bindpwd, $bindcert) = split (/:/, "@_"); my ($shadowport) = $port; my ($domainpattern) = '.[^:]+'; my ($i);
# Remove the domain name from the host name my ($hostnode) = $host; $hostnode = $1 if $host =~ /^(\w+)./;
# new host:port if ($binddn eq "" || $bindpwd eq "" && $bindcert eq "") { # # Look up connection parameter in the order of # host:port # host:* # *:port # *:* # my (@myconfig, $h, $p, $d, $w, $c); (@myconfig = grep (/^$hostnode($domainpattern)*:$port\D/i, @allconnections)) || (@myconfig = grep (/^$hostnode($domainpattern)*:*:/i, @allconnections)) || (@myconfig = grep (/^*:$port\D/, @allconnections)) || (@myconfig = grep (/^*:*\D/, @allconnections)); if ($#myconfig >= 0) { ($h, $p, $d, $w, $c) = split (/:/, $myconfig[0]); ($p, $shadowport) = split (/=/, $p); $p = "" if $p eq "*"; $c = "" if $c eq "*"; } if ($binddn eq "" || $binddn eq "*") { if ($d eq "" || $d eq "*") { $binddn = "cn=Directory Manager"; } else { $binddn = $d; } } $bindpwd = $w if ($bindpwd eq "" || $bindpwd eq "*"); $bindcert = $c if ($bindcert eq "" || $bindcert eq "*"); }
for ($i = 0; $i <= $#servers; $i++) { return $i if ($servers[$i] =~ /$hostnode($domainpattern)*:\d*=$shadowport\D/i); }
push (@servers, "$host:$port=$shadowport:$binddn:$bindpwd:$bindcert"); return $i; }
sub get_ldap_url { my ($sidx, $conntype) = @_; my ($host, $port) = split(/:/, $servers[$sidx]); my ($shadowport); ($port, $shadowport) = split (/=/, $port); my ($protocol, $ldapurl);
if ($port eq 636 && $conntype eq "0" || $conntype =~ /SSL/i) { $protocol = ldaps; } else { $protocol = ldap; } my ($instance) = $allaliases { "$host:$port" }; $instance = "$host:$port" if !$instance; if ($conntype eq "n/a") { $ldapurl = $instance; } else { $ldapurl = "<a href="$protocol://$host:$port/">$instance</a>"; } return $ldapurl; }
sub to_decimal_csn { my ($maxcsn) = @_; if (!$maxcsn || $maxcsn eq "") { return "none"; }
my ($tm, $seq, $masterid, $subseq) = unpack("a8 a4 a4 a4", $maxcsn);
$tm = hex($tm); $seq = hex($seq); $masterid = hex($masterid); $subseq = hex($subseq);
return "$tm $seq $masterid $subseq"; }
sub to_string_csn { my ($rawcsn, $decimalcsn) = split(/:/, "@_"); if (!$rawcsn || $rawcsn eq "") { return "none"; } my ($tm, $seq, $masterid, $subseq) = split(/ /, $decimalcsn); my ($sec, $min, $hour, $mday, $mon, $year) = localtime($tm); $mon++; $year += 1900; foreach ($sec, $min, $hour, $mday, $mon) { $_ = "0".$_ if ($_ < 10); } my ($csnstr) = "$mon/$mday/$year $hour:$min:$sec"; $csnstr .= " $seq $subseq" if ( $seq != 0 || $subseq != 0 ); return "$rawcsn ($csnstr)"; }
sub get_color { my ($lag_minute) = @_; $lag_minute /= 60; my ($color) = $allcolors { $colorkeys[0] }; foreach (@colorkeys) { last if ($lag_minute < $_); $color = $allcolors {$_}; } return $color; }
# subroutine to remove escaped encoding
sub unescape { #my ($_) = @_; tr/+/ /; s/%(..)/pack("c",hex($1))/ge; $_; }
sub print_html_header { # print the HTML header
print "Content-type: text/html\n\n"; print "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 3.2//EN\"><html>\n"; print "<head><title>Replication Status</title>\n"; # print "<link type=text/css rel=stylesheet href="master-style.css">\n"; print "<style text/css>\n"; print "Body, p, table, td, ul, li {color: #000000; font-family: Arial, Helvetica, sans-serif; font-size: 12px;}\n"; print "A {color:blue; text-decoration: none;}\n"; print "BODY {font-family: arial, helvetica, sans-serif}\n"; print "P {font-family: arial, helvetica, sans-serif}\n"; print "TH {font-weight: bold; font-family: arial, helvetica, sans-serif}\n"; print "TD {font-family: arial, helvetica, sans-serif}\n"; print ".bgColor1 {background-color: #003366;}\n"; print ".bgColor4 {background-color: #cccccc;}\n"; print ".bgColor5 {background-color: #999999;}\n"; print ".bgColor9 {background-color: #336699;}\n"; print ".bgColor13 {background-color: #ffffff;}\n"; print ".bgColor16 {background-color: #6699cc;}\n"; print ".text8 {color: #0099cc; font-size: 11px; font-weight: bold;}\n"; print ".text28 {color: #ffcc33; font-size: 12px; font-weight: bold;}\n"; print ".areatitle {font-weight: bold; color: #ffffff; font-family: arial, helvetica, sans-serif}\n"; print ".page-title {font-weight: bold; font-size: larger; font-family: arial, helvetica, sans-serif}\n"; print ".page-subtitle {font-weight: bold; font-family: arial, helvetica, sans-serif}\n";
print "</style></head>\n<body class=bgColor4>\n";
if ($opt_u) { print "<meta http-equiv=refresh content=$interval; URL=$opt_u>\n"; }
print "<table border=0 cellspacing=0 cellpadding=10 width=100% class=bgColor1>\n"; print "<tr><td><font class=text8>$now</font></td>\n"; print "<td align=center class=page-title><font color=#0099CC>"; print "Directory Server Replication Status</font>\n";
if ($opt_u) { print "<br><font class=text8>(This page updates every $interval seconds)</font>\n"; }
print "</td><td align=right valign=center width=25%><font class=text8>$version"; print "</font></td></table>\n"; }
sub print_legend { my ($nlegends) = $#colorkeys + 1; print "\n<center><p><font class=page-subtitle color=#0099cc>Time Lag Legend:</font><p>\n"; print "<table cellpadding=6 cols=$nlegends width=40%>\n<tr>\n"; my ($i, $j); for ($i = 0; $i < $nlegends - 1; $i++) { $j = $colorkeys[$i]; print "\n<td bgcolor=$allcolors{$j}><center>within $colorkeys[$i+1] min</center></td>\n"; } $j = $colorkeys[$i]; print "\n<td bgcolor=$allcolors{$j}><center>over $colorkeys[$i] min</center></td>\n"; print "\n<td bgcolor=red><center>server n/a</center></td>\n"; print "</table></center>\n"; }
sub print_supplier_end { print "</table>\n"; }
# given a string in generalized time format, convert to ascii time sub format_z_time { my $zstr = shift; return "n/a" if (! $zstr); my ($year, $mon, $day, $hour, $min, $sec) = ($zstr =~ /(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})/); my $time = timegm($sec, $min, $hour, $day, ($mon-1), $year); ($sec, $min, $hour, $day, $mon, $year) = localtime($time); $mon++; $year += 1900; foreach ($sec, $min, $hour, $day, $mon) { $_ = "0".$_ if ($_ < 10); }
return "$mon/$day/$year $hour:$min:$sec"; }
--- NEW FILE template-verify-db.pl.in --- #{{PERL-EXEC}} # # BEGIN COPYRIGHT BLOCK # This Program is free software; you can redistribute it and/or modify it under # the terms of the GNU General Public License as published by the Free Software # Foundation; version 2 of the License. # # This Program is distributed in the hope that it will be useful, but WITHOUT # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS # FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. # # You should have received a copy of the GNU General Public License along with # this Program; if not, write to the Free Software Foundation, Inc., 59 Temple # Place, Suite 330, Boston, MA 02111-1307 USA. # # In addition, as a special exception, Red Hat, Inc. gives You the additional # right to link the code of this Program with code not covered under the GNU # General Public License ("Non-GPL Code") and to distribute linked combinations # including the two, subject to the limitations in this paragraph. Non-GPL Code # permitted under this exception must only link to the code of this Program # through those well defined interfaces identified in the file named EXCEPTION # found in the source code files (the "Approved Interfaces"). The files of # Non-GPL Code may instantiate templates or use macros or inline functions from # the Approved Interfaces without causing the resulting work to be covered by # the GNU General Public License. Only Red Hat, Inc. may make changes or # additions to the list of Approved Interfaces. You must obey the GNU General # Public License in all respects for all of the Program code and other code used # in conjunction with the Program except the Non-GPL Code covered by this # exception. If you modify this file, you may extend this exception to your # version of the file, but you are not obligated to do so. If you do not wish to # provide this exception without modification, you must delete this exception # statement from your version and license this file solely under the GPL without # exception. # # # Copyright (C) 2005 Red Hat, Inc. # All rights reserved. # END COPYRIGHT BLOCK #
sub getDbDir { (my $here) = @_; my @dbdirs = ();
opendir(DIR, $here) or die "can't opendir $here : $!"; while (defined($dir = readdir(DIR))) { my $thisdir; if ("$here" eq ".") { $thisdir = $dir; } else { $thisdir = $here . "{{SEP}}" . $dir; } if (-d $thisdir) { if (!($thisdir =~ /./)) { opendir(SUBDIR, "$thisdir") or die "can't opendir $thisdir : $!"; while (defined($file = readdir(SUBDIR))) { if ($file eq "DBVERSION") { $#dbdirs++; $dbdirs[$#dbdirs] = $thisdir; } } closedir(SUBDIR); } } } closedir(DIR);
return @dbdirs; }
sub getLastLogfile { (my $here) = @_; my $logfile = "";
opendir(DIR, $here) or die "can't opendir $here : $!"; while (defined($file = readdir(DIR))) { if ($file =~ /log./) { $logfile = $file; } } closedir(DIR);
return $logfile; }
$isWin = -d '\'; if ($isWin) { $NULL = "nul"; } else { $NULL = "/dev/null"; }
print("*****************************************************************\n"); print("verify-db: This tool should only be run if recovery start fails\n" . "and the server is down. If you run this tool while the server is\n" . "running, you may get false reports of corrupted files or other\n" . "false errors.\n"); print("*****************************************************************\n");
# get dirs having DBVERSION my $dbdirs = getDbDir("."); my $brand_ds = {{DS-BRAND}}; my $prefix = "{{DS-ROOT}}";
$ENV{'PATH'} = '$prefix@db_bindir@:$prefix/usr/lib:@db_bindir@:/usr/lib'; $ENV{'LD_LIBRARY_PATH'} = '@db_libdir@:/usr/lib'; $ENV{'SHLIB_PATH'} = '@db_libdir@:/usr/lib';
for (my $i = 0; $i < @$dbdirs; $i++) { # run db_printlog -h <dbdir> for each <dbdir> print "Verify log files in $$dbdirs[$i] ... "; open(PRINTLOG, "db_printlog -h $$dbdirs[$i] 2>&1 1> $NULL |"); sleep 1; my $haserr = 0; while ($l = <PRINTLOG>) { if ("$l" ne "") { if ($haserr == 0) { print "\n"; } print "LOG ERROR: $l"; $haserr++; } } close(PRINTLOG); if ($haserr == 0 && $? == 0) { print "Good\n"; } else { my $logfile = getLastLogfile($$dbdirs[$i]); print "Log file(s) in $$dbdirs[$i] could be corrupted.\n"; print "Please delete a log file $$logfile, and try restarting the server.\n"; } }
for (my $i = 0; $i < @$dbdirs; $i++) { # changelog opendir(DB, $$dbdirs[$i]) or die "can't opendir $$dbdirs[$i] : $!"; while (defined($db = readdir(DB))) { if ($db =~ /.db/) { my $thisdb = $$dbdirs[$i] . "{{SEP}}" . $db; print "Verify $thisdb ... "; open(DBVERIFY, "db_verify $thisdb 2>&1 1> $NULL |"); sleep 1; my $haserr = 0; while ($l = <DBVERIFY>) { if ($haserr == 0) { print "\n"; } if ("$l" ne "") { $haserr++; print "DB ERROR: $l"; } } close(DBVERIFY); if ($haserr == 0 && $? == 0) { print "Good\n"; } else { print "changelog file $db in $$dbdirs[$i] is corrupted.\n"; print "Please restore your backup and recover the database.\n"; } } } closedir(DB);
# backend: get instance dirs under <dbdir> my $instdirs = getDbDir($$dbdirs[$i]);
for (my $j = 0; $j < @$instdirs; $j++) { opendir(DIR, $$instdirs[$j]) or die "can't opendir $here : $!"; while (defined($db = readdir(DIR))) { if ($db =~ /.db/) { my $thisdb = $$instdirs[$j] . "{{SEP}}" . $db; print "Verify $thisdb ... "; open(DBVERIFY, "db_verify $thisdb 2>&1 1> $NULL |"); sleep 1; my $haserr = 0; while ($l = <DBVERIFY>) { if ($haserr == 0) { print "\n"; } if ("$l" ne "") { $haserr++; print "DB ERROR: $l"; } } close(DBVERIFY); if ($haserr == 0 && $? == 0) { print "Good\n"; } else { if ("$db" =~ /id2entry.db/) { print "Primary db file $db in $$instdirs[$j] is corrupted.\n"; print "Please restore your backup and recover the database.\n"; } else { print "Secondary index file $db in $$instdirs[$j] is corrupted.\n"; print "Please run db2index(.pl) for reindexing.\n"; } } } } closedir(DIR); } }
Index: template-cl-dump.pl =================================================================== RCS file: /cvs/dirsec/ldapserver/ldap/admin/src/scripts/template-cl-dump.pl,v retrieving revision 1.8 retrieving revision 1.9 diff -u -r1.8 -r1.9 --- template-cl-dump.pl 25 Oct 2006 00:04:42 -0000 1.8 +++ template-cl-dump.pl 25 Oct 2006 20:36:46 -0000 1.9 @@ -99,6 +99,8 @@ # enable the use of our bundled perldap with our bundled ldapsdk libraries # all of this nonsense can be omitted if the mozldapsdk and perldap are # installed in the operating system locations (e.g. /usr/lib /usr/lib/perl5) +$prefix = "{{DS-ROOT}}"; + $ENV{'LD_LIBRARY_PATH'} = '$prefix/usr/lib/dirsec:$prefix/usr/lib:/usr/lib/dirsec:/usr/lib'; $ENV{'SHLIB_PATH'} = '$prefix/usr/lib/dirsec:$prefix/usr/lib:/usr/lib/dirsec:/usr/lib';
Index: template-ns-newpwpolicy.pl =================================================================== RCS file: /cvs/dirsec/ldapserver/ldap/admin/src/scripts/template-ns-newpwpolicy.pl,v retrieving revision 1.6 retrieving revision 1.7 diff -u -r1.6 -r1.7 --- template-ns-newpwpolicy.pl 25 Oct 2006 00:04:42 -0000 1.6 +++ template-ns-newpwpolicy.pl 25 Oct 2006 20:36:46 -0000 1.7 @@ -42,6 +42,8 @@ # enable the use of our bundled perldap with our bundled ldapsdk libraries # all of this nonsense can be omitted if the mozldapsdk and perldap are # installed in the operating system locations (e.g. /usr/lib /usr/lib/perl5) +$prefix = "{{DS-ROOT}}"; + $ENV{'PATH'} = '$prefix/usr/lib/mozldap6:$prefix/usr/lib:/usr/lib/mozldap6:/usr/lib'; $ENV{'LD_LIBRARY_PATH'} = '$prefix/usr/lib/dirsec:$prefix/usr/lib:/usr/lib/dirsec:/usr/lib'; $ENV{'SHLIB_PATH'} = '$prefix/usr/lib/dirsec:$prefix/usr/lib:/usr/lib/dirsec:/usr/lib'; @@ -64,12 +66,6 @@ $opt_h = "{{SERVER-NAME}}"; $opt_v = 0;
-$ENV{'PATH'} = '$prefix{{SEP}}usr{{SEP}}lib:{{SEP}}usr{{SEP}}lib{{SEP}}mozldap'; -$ENV{'LD_LIBRARY_PATH'} .= ":"; -$ENV{'LD_LIBRARY_PATH'} .= "$prefix{{SEP}}usr{{SEP}}lib:{{SEP}}usr{{SEP}}lib{{SEP}}mozldap"; -$ENV{'SHLIB_PATH'} .= ":"; -$ENV{'SHLIB_PATH'} .= "$prefix{{SEP}}usr{{SEP}}lib:{{SEP}}usr{{SEP}}lib{{SEP}}mozldap"; - # Variables $ldapsearch="ldapsearch -1"; $ldapmodify="ldapmodify";
Index: template-repl-monitor-cgi.pl =================================================================== RCS file: /cvs/dirsec/ldapserver/ldap/admin/src/scripts/template-repl-monitor-cgi.pl,v retrieving revision 1.6 retrieving revision 1.7 diff -u -r1.6 -r1.7 --- template-repl-monitor-cgi.pl 25 Oct 2006 00:04:42 -0000 1.6 +++ template-repl-monitor-cgi.pl 25 Oct 2006 20:36:46 -0000 1.7 @@ -56,6 +56,8 @@ $params .= " -u "$admurl""; } $siteroot = $cgiVars{'siteroot'}; +$prefix = "{{DS-ROOT}}"; + $ENV{'PATH'} = '$prefix/usr/lib/mozldap6:$prefix/usr/lib:/usr/lib/mozldap6:/usr/lib'; $ENV{'LD_LIBRARY_PATH'} = '$prefix/usr/lib/dirsec:$prefix/usr/lib:/usr/lib/dirsec:/usr/lib'; $ENV{'SHLIB_PATH'} = '$prefix/usr/lib/dirsec:$prefix/usr/lib:/usr/lib/dirsec:/usr/lib';
Index: template-verify-db.pl =================================================================== RCS file: /cvs/dirsec/ldapserver/ldap/admin/src/scripts/template-verify-db.pl,v retrieving revision 1.6 retrieving revision 1.7 diff -u -r1.6 -r1.7 --- template-verify-db.pl 25 Oct 2006 00:04:42 -0000 1.6 +++ template-verify-db.pl 25 Oct 2006 20:36:46 -0000 1.7 @@ -112,6 +112,8 @@ # get dirs having DBVERSION my $dbdirs = getDbDir("."); my $brand_ds = {{DS-BRAND}}; +my $prefix = "{{DS-ROOT}}"; + $ENV{'PATH'} = '$prefix/usr/bin:$prefix/usr/lib:/usr/bin:/usr/lib'; $ENV{'LD_LIBRARY_PATH'} = ':/usr/lib'; $ENV{'SHLIB_PATH'} = ':/usr/lib';
389-commits@lists.fedoraproject.org