#!/usr/bin/env perl # # 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 # # makemccvlvindexes sub usage_and_exit { print "makemccvlvindexes usage\n"; print "\n"; print "This script analyses an LDAP directory in order to create VLV indices which\n"; print "could be configured to improve the performance of one-level searches.\n"; print "This is principally to be used to tune the directory browsing feature\n"; print "of the Mission Control Console.\n"; print "\n"; print "An LDAP client can only take advantage of these indices if it is itself\n"; print "VLV enabled. See the following specification for full details.\n"; print "\n"; print "ftp://ftp.ietf.org/internet-drafts/draft-ietf-ldapext-ldapv3-vlv-00.txt\n"; print "\n"; print "Command Line Arguments\n"; print "-? - help\n"; print "-D rootdn - Provide a root DN. Default= '$rootdn'\n"; print "-w password - Provide a password for the root DN.\n"; print "-h host - Provide a host name. Default= '$host'\n"; print "-p port - Provide a port. Default= '$port'\n"; print "-t threshold - Provide a container subordinate threshold. Default= $threshold\n"; print "-f filter - Provide a search filter. Default= '$vlvfilter'\n"; print "-s sort - Provide a sort specification. Default='$vlvsort'\n"; print "-n - Do the work, but don't create the indices\n"; exit; } # Initialise some things $vlvfilter= "(objectclass=*)"; $vlvsort= "sn givenname cn ou o"; $rootdn= "cn= Directory Manager"; $host= "localhost"; $port= "389"; $threshold= 1000; $really_do_it= "1"; # 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 "-h") { $host= shift @ARGV; } elsif($arg eq "-p") { $port= shift @ARGV; } elsif($arg eq "-t") { $threshold= shift @ARGV; } elsif($arg eq "-f") { $vlvfilter= shift @ARGV; } elsif($arg eq "-s") { $vlvsort= shift @ARGV; } elsif($arg eq "-n") { $really_do_it= "0"; } else { print "$arg: Unknown command line argument.\n"; } } $ldapsearch= "ldapsearch -h $host -p $port"; $ldapmodify= "ldapmodify -h $host -p $port -D \"$rootdn\" -w $rootpw"; if( $vlvfilter eq "" || $vlvsort eq "" || $rootdn eq "" || $host eq "" || $port eq "" || $threshold eq "") { print "Error: Need command line information..\n"; usage_and_exit(); } if( $rootpw eq "" ) { print "Warning: No root DN password provided. Won't be able to add VLV Search and Index entries.\n"; } # Tell the user what we're up to. print "Searching all naming contexts on '$host:$port' for containers with more than $threshold subordinate entries\n"; # Read the naming contexts from the root dse @namingcontexts= `$ldapsearch -s base -b \"\" \"objectclass=*\" namingcontexts`; # Get rid of the first line 'dn:' shift @namingcontexts; # Foreach naming context... foreach $nc (@namingcontexts) { # Extract the base from the naming context @base= split ' ', $nc; shift @base; # Find all the containers print "Searching naming context '@base' for containers.\n"; @containers= `$ldapsearch -s subtree -b \"@base\" \"numsubordinates=*\" numsubordinates`; chop @containers; # Foreach container while(@containers) { # $dn_line= shift @containers; $count_line= shift @containers; shift @containers; # Extract the count, and check it against the threshold @count_array= split ' ', $count_line; $count= @count_array[1]; $dn= substr($dn_line,4); print "Found container '$dn' with $count subordinates. "; if($count > $threshold) { # We've found a container that should be indexed. # Extract the DN and RDN of the container $comma_position= (index $dn, ','); if($comma_position== -1) { $rdn= $dn } else { $rdn= substr($dn, 0, $comma_position); } # Tell the user what we're up to. print "Adding VLV Search and Index entries.\n"; # Build the vlv search and index entries to be added. $vlvsearch_name= "MCC $rdn"; @vlvsearch= ( "dn: cn=$vlvsearch_name, cn=config, cn=ldbm\n", "objectclass: top\n", "objectclass: vlvSearch\n", "cn: $vlvsearch_name\n", "vlvbase: $dn\n", "vlvfilter: $vlvfilter\n", "vlvscope: 1\n\n" ); $vlvindex_name= "SN $vlvsearch_name"; @vlvindex= ( "dn: cn=$vlvindex_name, cn=$vlvsearch_name, cn=config, cn=ldbm\n", "objectclass: top\n", "objectclass: vlvIndex\n", "cn: $vlvindex_name\n", "vlvsort: $vlvsort\n\n" ); @vlvnames = ( @vlvnames, "\"" . $vlvindex_name . "\""); if($really_do_it eq "1") { open(FD,"| $ldapmodify -a -c"); print FD @vlvsearch; print FD @vlvindex; close(FD); } } else { print "Too small.\n"; } } } # Dump a script to actually create the indexes if($really_do_it eq "1" && $#vlvnames > 0) { print "\n"; print "$#vlvnames VLV indices have been declared. Execute the following commands to build the index files.\n"; print "\n"; print "\\stop\n"; print "slapd db2index -f -V @vlvnames\n"; print "\\start\n"; }