Article
by Gary Childers
Contents:
- Introduction
- Managing Identity Manager
- Solution Requirements
- Proposed Solution
- Dependencies
- Caveat Implementor
- Script Usage
- Usage Examples
- Using Symlinks and Aliases
- Failing Drivers to Alternate Servers
- Scripts
- Summary
Introduction
Virtually all organizations rely on some type of Directory Services as the basis of their network security system -- whether Novell's eDirectory, Microsoft's Active Directory, LDAP directories, etc. In fact, a growing number of organizations have multiple directories or user databases, which are proprietary to their particular applications -- different directories with the same user accounts, each with their own attributes and passwords that have to be managed.
Enter Novell Identity Manager. Identity Manager (IDM) is a tremendously powerful and flexible product to synchronize user accounts between a great number of different systems and directories, including Novell’s eDirectory, Microsoft’s Active Directory, LDAP directories, Linux/Unix servers, Lotus Notes, and many others.
Managing Identity Manager
Once you have the IDM product up and running, you’re always looking for ways to simplify and automate various maintenance tasks. This is particularly true when you have implemented IDM on the Linux platform, since Linux administrators tend to rely heavily upon using scripts to automate the day-to-day management tasks that are required. This ability to automate complex tasks with scripts is one of the strengths of the Linux operating system.
So let's paint the scenario: administrators of Novell Identity Management (IDM) wish to be able to conveniently manage the IDM drivers running on Linux servers as part of the day-to-day administration of the Identity Management system. Novell provides iManager for Web-based remote administration, and also the dxcmd utility for local server console administration of IDM drivers.
The standard method for starting, stopping and checking the state of IDM drivers is to launch iManager on a workstation, login to a particular server, then select Identity Manager | Identity Manager Overview in the navigation pane, then select the desired Driver Set, and then finally select the particular IDM driver and click on the driver control button to Start, Stop, or Get Current Status for that driver.
This process can be slow or limiting, especially if you are at the Linux server console, and just want to quickly start, stop, or view the current state of your drivers. The dxcmd command-line utility can be used at the server console, but the interactive interface is a bit clunky. The real power in dxcmd is the ability for it to accept command parameters, and thus be included in scripting logic to perform the tasks which we want to do.
Solution Requirements
Let's flesh out the requirements which we want our scripts to accomplish: IDM administrators wish to be able to use easy-to-remember console commands to manage the state of the IDM drivers, and also be able to script these same commands for use with automated processes, such as data backups. Thus the IDM administrators wish to have Linux scripts which will accomplish the following tasks:
- display the status of IDM drivers
- display the servers associated with an IDM driverset
- start IDM drivers on a particular server
- stop IDM drivers on a particular server
- modify the startup option of an IDM driver
- failover an IDM driver to an alternate server
Proposed Solution
To accomplish these objectives, I have developed a Linux bash script (named idmutil.sh) for use on Linux servers which have Novell Identity Manager installed. This script can be copied to at least one IDM server in the environment. A secondary script (named idmfailover.sh) uses the first script to perform the more complex driver failover operation.
The environment-specific variables, such as the eDirectory version, the LDAP search base, and the service account name and password, are contained in a configuration script (named idmutil.conf), which is called by the primary script to set all the necessary parameters that are particular to the eDirectory environment in which the scripts are implemented. This configuration script needs to be modified for every different environment.
Dependencies
The service account used in these scripts (in my implementation, IDMservice) should be created to allow IDM management with the least required privileges, for security reasons. The service account needs only to be made trustee of the DriverSet object in eDirectory, with compare, read and write attribute rights to the object.
By default, the eDirectory and Identity Management applications are installed and configured on Linux to run as the root user. These scripts are therefore designed to also run as the root user to manage the IDM drivers. In order to allow non-root users to use these scripts, include command aliases in the server’s ‘sudoers’ file, and run the scripts using sudo.
For more on being able to manage eDirectory as a non-root user, see the AppNote: Non-Root eDirectory Management. This goes into detail about using sudo to allow non-root users to run the specific commands and utilities on the Linux servers required to manage eDirectory.
Caveat Implementor
As with any proposed solution, I must not omit this standard "disclaimer": Please note: command scripting (in general), whether in NetWare, Windows, or Linux can do wonders to automate and schedule repetitive tasks, but we must always be very careful. The wonderful thing about scripted tasks is that they perform commands exactly as we tell them to do, quickly and repeatedly. The terrible thing about scripted tasks is also that they perform commands exactly as we tell them to do (not particularly as we think that we are telling them to do), quickly and repeatedly.
Well-written scripts can do a world of good. Poorly-written (or poorly implemented) scripts can put you into a world of hurt. So always, always (and should I say "always"?) test your scripts (repeatedly) in a test lab (non-production) environment, and then carefully test them again in very limited fashion in a "pilot" environment, before full-scale production use. This is especially true for any script which you have "borrowed" from another environment.
Script Usage
So with that said, now to the script itself. The general syntax of the idmutil.sh script is:
idmutil.sh [ <action> ] [<driverCN>] [<host>] [<option>]
The script file itself is 'idmutil.sh', which in my implementations I have placed in the /opt/novell/eDirectory/scripts directory (create this directory) on the Linux servers which have both eDirectory and IDM installed.
I have incorporated some error messages into the script logic to assist the user with the proper syntax. For example, if the script command were entered with no parameters, it would yield these results:
sles-idm1:~ # idmutil Usage: idmutil.sh [ <action> ] [ <driverCN> | all ] [ <host> ] [ <option> ] Error: invalid action Valid Actions: start | stop | status | list | listhosts | getstate
So this tells us the valid options for the first script parameter: start, stop, status, list, listhosts and getstate ('getstate' is actually the same as 'status'). This first ('action') parameter is always required.
Depending upon the action specified, there are some parameters that have default values. For example, the "list" action always defaults to "all" drivers, since it is assumed that you wish to list all drivers in the IDM driverset associated with the server. Similarly, if no "host" parameter is specified, it is assumed that the command will run against the local host or server.
Usage Examples
Here are a few examples of the script usage to accomplish common tasks:
- To list all drivers in the driverset on the local server:
sles-idm1:~ # idmutil list all sles-idm1 Listing drivers on sles-idm1 for DriverSet.MAIN ... EDIR2-EDIR1 eDir2AD-RL Library BusLogic
Note: as we just mentioned, the same results occur if we run "idmutil list" or "idmutil list all", because of the default values which are used if none are specified. - To display the status of a single IDM driver:
sles-idm1:~ # idmutil status edir1-edir2 sles-idm1 Getting Status of drivers on sles-idm1 for DriverSet.MAIN ... edir1-edir2 : (2) Running : (2) Auto on sles-idm1
Note: if a hostname is not specified, the local host is assumed. - To display the status of all IDM drivers on another host:
sles-idm1:~ # idmutil status all sles-idm2 Getting Status of drivers on sles-idm2 for DriverSet.MAIN ... EDIR2-EDIR1 : (2) Running : (2) Auto on sles-idm2 eDir2AD-RL : (2) Running : (2) Auto on sles-idm2 Library : (0) Stopped : (0) Disabled on sles-idm2 BusLogic : (0) Stopped : (0) Disabled on sles-idm2
Note: when "all" is used for the driverCN, the script will list information for all drivers - To display the servers associated with an IDM driverset:
sles-idm1:~ # idmutil listhosts Listing Hosts for DriverSet.MAIN on sles-idm1 ... sles-idm1 sles-idm3
Note: the "listhosts" option does not take any further parameters. - To start an IDM driver on the local server:
sles-idm1:~ # idmutil start edir1-edir2 Starting drivers on sles-idm1 for DriverSet.MAIN ... edir1-edir2 : (0) Stopped : (2) Auto on sles-idm1 *Starting Driver edir1-edir2 on sles-idm1. Please wait ... edir1-edir2 : (2) Running : (2) Auto on sles-idm1
Note: again, if a hostname is not specified, the local host is assumed. However, a driver CN is always required for ‘start’ and ‘stop’ operations. - To start an IDM driver on a remote server:
sles-idm1:~ # idmutil start edir2-edir1 sles-idm2 Starting drivers on sles-idm2 for DriverSet.MAIN ... edir2-edir1 : (0) Stopped : (2) Auto on sles-idm2 *Starting Driver edir2-edir1 on sles-idm2. Please wait ... edir2-edir1 : (2) Running : (2) Auto on sles-idm2
- To stop an IDM driver on the local server:
sles-idm1:~ # idmutil stop edir1-edir2 Stopping drivers on sles-idm1 for DriverSet.MAIN ... edir1-edir2 : (2) Running : (2) Auto on sles-idm1 *Stopping Driver edir1-edir2 on sles-idm1. Please wait ... edir1-edir2 : (0) Stopped : (2) Auto on sles-idm1
- To stop all IDM drivers on the local server:
sles-idm1:~ # idmutil stop all Stopping drivers on sles-idm1 for DriverSet.MAIN ... EDIR1-EDIR2 : (2) Running : (2) Auto on sles-idm1 *Stopping Driver EDIR1-EDIR2 on sles-idm1. Please wait ... EDIR1-EDIR2 : (0) Stopped : (2) Auto on sles-idm1 BusLogic1 : (2) Running : (2) Auto on sles-idm1 *Stopping Driver BusLogic1 on sles-idm1. Please wait ... BusLogic1 : (0) Stopped : (2) Auto on sles-idm1 BusLogic2 : (2) Running : (2) Auto on sles-idm1 *Stopping Driver BusLogic2 on sles-idm1. Please wait ... BusLogic2 : (0) Stopped : (2) Auto on sles-idm1
Note: The same action can be performed on a remote server, by adding the hostname. - To start all IDM drivers on a remote server:
sles-idm2:~ # idmutil start all sles-idm1 Starting drivers on sles-idm1 for DriverSet.MAIN ... EDIR1-EDIR2 : (0) Stopped : (2) Auto on sles-idm1 *Starting Driver EDIR1-EDIR2 on sles-idm1. Please wait ... EDIR1-EDIR2 : (2) Running : (2) Auto on sles-idm1 BusLogic1 : (0) Stopped : (2) Auto on sles-idm1 *Starting Driver BusLogic1 on sles-idm1. Please wait ... BusLogic1 : (2) Running : (2) Auto on sles-idm1 BusLogic2 : (0) Stopped : (2) Auto on sles-idm1 *Starting Driver BusLogic2 on sles-idm1. Please wait ... BusLogic2 : (2) Running : (2) Auto on sles-idm1
Note: the IDM servers upon which the idmutil.sh script is run do not need to be in the same eDirectory trees, since the dxcmd utility, which it executes, is not tree-specific. - To modify the startup option of an IDM driver on a remote server:
sles-idm2:~ # idmutil setstartoption edir1-edir2 sles-idm1 disabled Setting Start Option of drivers on sles-idm1 for DriverSet.MAIN ... edir1-edir2 : (2) Running : (2) Auto on sles-idm1
Note: by design, this command did not execute, since the driver is currently running. To disable the driver, we need to first stop the driver, as in:sles-idm2:~ # idmutil stop edir1-edir2 sles-idm1 Stopping drivers on sles-idm1 for DriverSet.MAIN ... edir1-edir2 : (2) Running : (2) Auto on sles-idm1 *Stopping Driver edir1-edir2 on sles-idm1. Please wait ... edir1-edir2 : (0) Stopped : (2) Auto on sles-idm1 sles-idm2:~ # idmutil setstartoption edir1-edir2 sles-idm1 disabled Setting Start Option of drivers on sles-idm1 for DriverSet.MAIN ... edir1-edir2 : (0) Stopped : (2) Auto on sles-idm1 *Setting Start Option of Driver edir1-edir2 on sles-idm1. Please wait ... edir1-edir2 : (0) Stopped : (0) Disabled on sles-idm1
Note also that the only time the <option> parameter is used, is in conjunction with the "setstartoption" action parameter.
Using Symlinks and Aliases
No doubt you may have noticed that in all my examples I have run the command: "idmutil", rather than the true name of the script, with the full path specified, as: "/opt/novell/eDirectory/scripts/idmutil.sh". This is because I first created a symbolic link to the script file in /usr/bin (which by default is in the user's path in most implementations of Linux). To create the symlink for the script, we merely have to execute this command:
ln -sf /opt/novell/eDirectory/scripts/idmutil.sh /usr/bin/idmutil
Remember, one of the requirements for this solution was to give IDM administrators easy-to-remember console commands to manage the state of the IDM drivers. Thus, to assist them with a simpler command syntax, I have also created a few aliases which merely call the idmutil.sh script with some pre-supplied parameters.
In Linux, we use aliases all the time. For example, we use "ll" as a shortcut for "ls -l" to list directory contents, an alias which saves us a mere three keystrokes. Similarly, we can use aliases to make our script syntax a bit easier to remember and execute.
For example, if an administrator wants to view the IDM driver status on the server by merely typing "idmstatus", then I create an alias "idmstatus", by executing this:
alias idmstatus='idmutil status'
Thus executing "idmstatus all" will really execute "idmutil status all", since the alias will be expanded out before the command execution, as in:
sles-idm1:~ # idmstatus Getting Status of drivers on sles-idm1 for DriverSet.MAIN ... EDIR1-EDIR2 : (2) Running : (2) Auto on sles-idm1 BusLogic1 : (2) Running : (2) Auto on sles-idm1 BusLogic2 : (2) Running : (2) Auto on sles-idm1 sles-idm1:~ # idmutil status all sles-idm1 Getting Status of drivers on sles-idm1 for DriverSet.MAIN ... EDIR1-EDIR2 : (2) Running : (2) Auto on sles-idm1 BusLogic1 : (2) Running : (2) Auto on sles-idm1 BusLogic2 : (2) Running : (2) Auto on sles-idm1
Similarly, we can have an alias for listing, starting and stopping drivers by executing:
alias idmlist='idmutil list' alias idmstart='idmutil start' alias idmstop='idmutil stop'
An example of using these aliases to stop and start all IDM drivers on a server is:
sles-idm1:~ # idmstop all Stopping drivers on sles-idm1 for DriverSet.MAIN ... EDIR1-EDIR2 : (2) Running : (2) Auto on sles-idm1 *Stopping Driver EDIR1-EDIR2 on sles-idm1. Please wait ... EDIR1-EDIR2 : (0) Stopped : (2) Auto on sles-idm1 BusLogic1 : (2) Running : (2) Auto on sles-idm1 *Stopping Driver BusLogic1 on sles-idm1. Please wait ... BusLogic1 : (0) Stopped : (2) Auto on sles-idm1 BusLogic2 : (2) Running : (2) Auto on sles-idm1 *Stopping Driver BusLogic2 on sles-idm1. Please wait ... BusLogic2 : (0) Stopped : (2) Auto on sles-idm1 sles-idm1:~ # idmstart all Starting drivers on sles-idm1 for DriverSet.MAIN ... EDIR1-EDIR2 : (0) Stopped : (2) Auto on sles-idm1 *Starting Driver EDIR1-EDIR2 on sles-idm1. Please wait ... EDIR1-EDIR2 : (2) Running : (2) Auto on sles-idm1 BusLogic1 : (0) Stopped : (2) Auto on sles-idm1 *Starting Driver BusLogic1 on sles-idm1. Please wait ... BusLogic1 : (2) Running : (2) Auto on sles-idm1 BusLogic2 : (0) Stopped : (2) Auto on sles-idm1 *Starting Driver BusLogic2 on sles-idm1. Please wait ... BusLogic2 : (2) Running : (2) Auto on sles-idm1
Failing Drivers to Alternate Servers
Remember also that one of the requirements for this solution was to automate the fail-over of an IDM driver to an alternate server. Obviously, this first requires that we have already installed a secondary IDM server in the same eDirectory tree with the our primary IDM server, and extended the driverset to that server.
But then to accomplish the task of quickly failing over a driver or drivers to the second IDM server, another secondary script (idmfailover.sh) is utilized. The idmfailover.sh script is used to call the idmutil.sh script four times: first to stop the driver on the first server, to disable the driver on the first server, to enable the driver on the second server, and finally to start the driver on the second server.
The syntax for using the idmfailover.sh script is:
idmfailover <driverCN> <server1> <server2>
Here is an example:
VMSLES-1:~ # idmstatus Getting Status of drivers on VMSLES-1 for DriverSet.MAIN ... BusLogic1 : (2) Running : (2) Auto on VMSLES-1 ACME-IDP2M : (2) Running : (2) Auto on VMSLES-1 VMSLES-1:~ # idmstatus all vmsles-3 Getting Status of drivers on vmsles-3 for DriverSet.MAIN ... BusLogic1 : (0) Stopped : (0) Disabled on vmsles-3 ACME-IDP2M : (0) Stopped : (0) Disabled on vmsles-3 VMSLES-1:~ # idmfailover buslogic1 vmsles-1 vmsles-3 Stopping drivers on vmsles-1 for DriverSet.MAIN ... buslogic1 : (2) Running : (2) Auto on vmsles-1 *Stopping Driver buslogic1 on vmsles-1. Please wait ... buslogic1 : (0) Stopped : (2) Auto on vmsles-1 Setting Start Option of drivers on vmsles-1 for DriverSet.MAIN ... buslogic1 : (0) Stopped : (2) Auto on vmsles-1 *Setting Start Option of Driver buslogic1 on vmsles-1. Please wait ... buslogic1 : (0) Stopped : (0) Disabled on vmsles-1 Setting Start Option of drivers on vmsles-3 for DriverSet.MAIN ... buslogic1 : (0) Stopped : (0) Disabled on vmsles-3 *Setting Start Option of Driver buslogic1 on vmsles-3. Please wait ... buslogic1 : (0) Stopped : (2) Auto on vmsles-3 Starting drivers on vmsles-3 for DriverSet.MAIN ... buslogic1 : (0) Stopped : (2) Auto on vmsles-3 *Starting Driver buslogic1 on vmsles-3. Please wait ... buslogic1 : (2) Running : (2) Auto on vmsles-3 VMSLES-1:~ # idmstatus all vmsles-3 Getting Status of drivers on vmsles-3 for DriverSet.MAIN ... BusLogic1 : (2) Running : (2) Auto on vmsles-3 ACME-IDP2M : (0) Stopped : (0) Disabled on vmsles-3 VMSLES-1:~ # idmstatus Getting Status of drivers on VMSLES-1 for DriverSet.MAIN ... BusLogic1 : (0) Stopped : (0) Disabled on VMSLES-1 ACME-IDP2M : (2) Running : (2) Auto on VMSLES-1
This example shows that the 'BusLogic1' driver was running on the vmsles-1 server, and we failed it over to the vmsles-3 server by executing: "idmfailover buslogic1 vmsles-1 vmsles-3", and then verified that it is now running on the vmsles-3 server.
And once again, you may notice that we utilized a symbolic link to reference the script. To create the symlink for the idmfailover.sh script, we merely have to execute this command:
ln -sf /opt/novell/eDirectory/scripts/idmfailover.sh /usr/bin/idmfailover
The automatic fail-over of IDM drivers may be required if administrators want to perform an operation such as a scheduled data backup of the server, or any other maintenance which would require stopping the drivers and starting them on an alternate server.
Scripts
And now for the actual scripts themselves. Below is the text of the scripts developed to accomplish the required tasks outlined above:
The main script, idmutil.sh:
#!/bin/bash
# idmutil.sh
# Script to start, stop, and list status of IDM drivers using dxcmd
# Author: Gary Childers, 02/09/2009 Version 1.3.1
# Usage: idmutil [ <action> ] [<driverCN>] [<host>] [<option>]
#----------------------------------------------------------------------------#
## Set initial required variables
SCRIPT=idmutil.sh
CONFFILE=ndsenvironment.conf
SCRIPTDIR=/opt/novell/eDirectory/scripts
## Set IDM server environment-specific variables from a separate config file
if [ -f $SCRIPTDIR/$CONFFILE ]; then
. $SCRIPTDIR/$CONFFILE
else
echo "Configuration file $SCRIPTDIR/$CONFFILE missing!"
exit 1
fi
## Required script variables
THISHOST=`/bin/hostname`
ACTION=$1
if [ "$ACTION" = "status" ]; then ACTION="getstate"; fi
DRVRCN=$2
if [ "$DRVRCN" = "" ]; then DRVRCN="all"; fi
DXMLHOST=$3
if [ "$DXMLHOST" = "" ]; then DXMLHOST="$THISHOST" ; fi
SETSTARTUP=$4
if [ "$ACTION" = "setstartoption" ]; then OPTOPTION=$SYNCOPTION; fi
ACTIONLIST="list listhosts start stop getstate getstartoption setstartoption"
OPTIONLIST="disabled manual auto"
DRVRSET=`echo $DRVRSETDN | sed s/"cn="//g | sed s/",ou="/"."/g |sed s/",o="/"."/g`
DELAY=3
## Set the location of utilities according to eDirectory version
if [ -f /usr/bin/dxcmd ]; then UTILDIR=/usr/bin; fi
if [ -f /opt/novell/eDirectory/bin/dxcmd ]; then UTILDIR=/opt/novell/eDirectory/bin; fi
if [ "$UTILDIR" = "" ]; then
echo "Error: dxcmd utility not found"
exit 1
fi
DXUTIL="$UTILDIR/dxcmd"
LDAPUTIL="$UTILDIR/ldapsearch"
## Set Error Messages
ERROR0="You must run this script as root."
ERROR1="invalid action"
ERROR4="invalid startup option"
USAGE="Usage: $SCRIPT [ <action> ] [<driverCN>] [<host>] [<option>]"
USAGE1="Valid Actions: start | stop | status | list | listhosts | getstate"
USAGE4="Valid Options: disabled | manual | auto"
## Notify root user dependency
if [ $(whoami) != "root" ]; then
echo $ERROR0
exit 1
fi
#----------------------------------------------------------------------------#
## Define functions
function LCASE()
{
## Function to translate strings to lowercase
echo $1 | tr [:upper:] [:lower:]
}
function TESTLIST()
{
## Function to validate a parameter against a list
## Returns 1 if LOCALLIST contains LOCALOPTION, returns 0 otherwise
LOCALOPTION=$1
LOCALLIST=$2
for LISTITEM in $LOCALLIST; do
if [ "$(LCASE $LOCALOPTION)" = "$(LCASE $LISTITEM)" ]; then return 1; fi
done
return 0
}
function ECHOERROR()
{
echo "$1 : $2"
echo "$3"
exit 1
}
function GETSTATE()
{
## Get the current state for the specified driver
STATE=`$DXUTIL -s -host $DXMLHOST -user $IDMUSER -password $IDMPWD -getstate $DRVR.$DRVRSET`
case $STATE in
"0" ) STATEDESC="Stopped" ;;
"1" ) STATEDESC="Starting" ;;
"2" ) STATEDESC="Running" ;;
"3" ) STATEDESC="Stopping" ;;
"-601" ) STATEDESC="No Such Entry" ;;
* ) STATEDESC="ERROR" ;;
esac
## Get the current startup option for the specified driver
STARTOPT=`$DXUTIL -s -host $DXMLHOST -user $IDMUSER -password $IDMPWD -getstartoption $DRVR.$DRVRSET`
case $STARTOPT in
"0" ) STARTDESC="Disabled" ;;
"1" ) STARTDESC="Manual" ;;
"2" ) STARTDESC="Auto" ;;
"-601" ) STARTDESC="No Such Entry" ;;
* ) STARTDESC="ERROR" ;;
esac
## Echo the results returned from getting State and Startup Option
echo " $(printf %-24.24s "$DRVR") : ($STATE) $(printf %-12s "$STATEDESC") : ($STARTOPT) $(printf %-12s "$STARTDESC") on $DXMLHOST"
}
function TESTACTION()
{
## Test state and startup option
case $ACTION in
"start" ) if [ $STATE = 2 ] ; then return 1; fi ;
if [ $STARTOPT = 0 ] ; then return 1; fi ;;
"stop" ) if [ $STATE = 0 ] ; then return 1; fi ;;
"setstartoption" ) if [ $STATE = 2 ] ; then return 1; fi ;;
esac
if [ $STATE = "-601" ] ; then return 1; fi
return 0
}
function DOACTION()
{
## Perform the specified action for the specified drivers
echo " *$ACTDESC Driver $DRVR on $DXMLHOST. Please wait ..."
$DXUTIL -q -host $DXMLHOST -user $IDMUSER -password $IDMPWD -$ACTION $DRVR.$DRVRSET $SETSTARTUP $OPTOPTION
sleep $DELAY
}
#----------------------------------------------------------------------------#
## Validate the provided arguments
## validate the action parameter
TESTLIST $ACTION "$ACTIONLIST"
if [ $? = "0" ]; then ECHOERROR $ACTION "$ERROR1" "$USAGE1"; fi
## Set the description for the specified action
case $ACTION in
"list" ) ACTDESC="Listing"; DRVRCN="all" ;;
"listhosts" ) ACTDESC="Listing Hosts"; DRVRCN="all" ;;
"start" ) ACTDESC="Starting" ;;
"stop" ) ACTDESC="Stopping" ;;
"getstate" ) ACTDESC="Getting Status of" ;;
"getstartoption" ) ACTDESC="Getting Start Option of" ;;
"setstartoption" ) ACTDESC="Setting Start Option of" ;;
* ) ACTDESC="INVALID ACTION" ;;
esac
## Validate the host parameter
ERROR3a="Server $DXMLHOST: is not a valid IDM host"
USAGE3a="Valid Hosts: $HOSTLIST"
TESTLIST $DXMLHOST "$HOSTLIST"
if [ $? = "0" ]; then ECHOERROR $DXMLHOST "$ERROR3a" "$USAGE3a"; fi
## Validate the startoption parameter
if [ "$1" = "setstartoption" ]; then
TESTLIST $SETSTARTUP "$OPTIONLIST"
if [ $? = "0" ]; then ECHOERROR $SETSTARTUP "$ERROR4" "$USAGE4"; fi
fi
## Find Servers associated with the DriverSet using LDAP search
DXMLHOSTS=`$LDAPUTIL -h $DXMLHOST -p 389 -x -D $LDAPUSER -w $IDMPWD -s base -b $DRVRSETDN DirXML-ServerList | grep DirXML-ServerList: | cut -d" " -f2 | cut -d"=" -f2 | cut -d"," -f1`
## Find Drivers contained in the DriverSet using LDAP search
DXMLDRVRS=`$LDAPUTIL -h $DXMLHOST -p 389 -x -D $LDAPUSER -w $IDMPWD -s one -b $DRVRSETDN dn | grep dn: | cut -d" " -f2 | cut -d"=" -f2 | cut -d"," -f1`
## List Servers associated with the DriverSet
if [ $ACTION = "listhosts" ]; then
echo "$ACTDESC for $DRVRSET on $DXMLHOST ..."
for HOST in $DXMLHOSTS; do echo $HOST; done
exit 0
fi
## Validate if the IDM driverset is associated with the specified server
ERROR3b="Server $DXMLHOST is not associated with $DRVRSET"
USAGE3b="Valid Hosts: $DXMLHOSTS"
TESTLIST $DXMLHOST "$DXMLHOSTS"
if [ $? = "0" ]; then ECHOERROR $DXMLHOST "$ERROR3b" "$USAGE3b"; fi
## Validate if the driver is in the IDM driverset
ERROR2="is not a valid driver in $DRVRSET on $DXMLHOST"
USAGE2="Valid Drivers: $DXMLDRVRS"
if [ "$DRVRCN" != "all" ]; then
TESTLIST $DRVRCN "$DXMLDRVRS"
if [ $? = "0" ]; then ECHOERROR $DRVRCN "$ERROR2" "$USAGE2"; fi
fi
## Show status of the IDM drivers, and conditionally perform the action
if [ "$ACTION" = "list" -o "$DRVRCN" = "all" ]
then DRVRLIST=$DXMLDRVRS
else DRVRLIST=$DRVRCN
fi
echo "$ACTDESC drivers on $DXMLHOST for $DRVRSET ..."
for DRVR in $DRVRLIST; do
if [ "$ACTION" = "list" ]; then
echo $DRVR
else
GETSTATE {}
if [ "$ACTION" = "start" -o "$ACTION" = "stop" -o "$ACTION" = "setstartoption" ]; then
TESTACTION {}
if [ $? != 1 ]; then
DOACTION {}
GETSTATE {}
fi
fi
fi
done
exit 0
The configuration script, idmutil.conf :
#!/bin/bash # idmutil.conf # Set environment-specific variables for the idmutil.sh script ## Environment-specific variables LDAPUSER="cn=IDMservice,o=MAIN" IDMUSER="IDMservice.MAIN" IDMPWD="n0v3ll" DRVRSETDN="cn=DriverSet,o=MAIN" LDAPBASE="o=MAIN" SYNCOPTION=noresync HOSTLIST="vmsles-1 vmsles-2 vmsles-3 vmsles-4"
Obviously, these parameters are specific to the environment in which the scripts are to be deployed. The IDMservice account password is stored in clear text, which is why we setup an account with the least required privileges. The file should also be restricted to be readable only by the root user.
The script to failover IDM drivers to alternate servers, idmfailover.sh:
#!/bin/bash # idmfailover.sh # Script to failover IDM drivers to another server using idmutil script # Author: Gary Childers 2009-02-09 Version 1.2 # Usage: idmfailover <driverCN> <server1> <server2> ## Test the provided parameters USAGE="Usage: idmfailover <driverCN> <server1> <server2>" if [ "$1" = "" -o "$2" = "" -o "$3" = "" ]; then echo "invalid parameters" echo $USAGE exit 1 fi ## Set required variables IDMUTIL1=/opt/novell/eDirectory/scripts/idmutil.sh DRIVER=$1 SERVER1=$2 SERVER2=$3 ## Stop the driver on the first server $IDMUTIL1 stop $DRIVER $SERVER1 ## Set the start option to disabled on the first server $IDMUTIL1 setstartoption $DRIVER $SERVER1 disabled ## Set the start option to auto on the second server $IDMUTIL1 setstartoption $DRIVER $SERVER2 auto ## Start the driver on the second server $IDMUTIL1 start $DRIVER $SERVER2 exit 0
Summary
Just to recap this suggested solution for scripted management of IDM drivers on Linux:
- Deploy the scripts in /opt/novell/eDirectory/scripts (create the directory)
- Create a service account with appropriate eDirectory rights to the IDM DriverSet
- Modify the idmutil.conf file to accommodate the desired eDirectory environment
- Create symlinks and aliases to the script files for ease-of-use
This solution allows IDM administrators to more easily manage IDM drivers from the Linux console, and to more easily script IDM commands for automated processes, such as data backups. If you choose to adapt these scripts for your environment, be sure (I say again) to test them thoroughly before deployment on production servers. Happy scripting!
Disclaimer: As with everything else at Cool Solutions, this content is definitely not supported by Novell (so don't even think of calling Support if you try something and it blows up).
It was contributed by a community member and is published "as is." It seems to have worked for at least one person, and might work for you. But please be sure to test, test, test before you do anything drastic with it.
Related Articles
User Comments
Security required
Submitted by dgersic on 26 February 2009 - 9:39am.
Section 1.2 of the docs, "Securing Directory Access" might be good to review if you are on IDM 3.6 or newer. You can lock down the security required on your IDMservice account even further.
- Be the first to comment! To leave a comment you need to Login or Register
Great Solution, but I am getting an Error
Submitted by bwillhite on 13 March 2009 - 12:21pm.
I have a single server IDM test environment, SLES 10, IDM 3.6 eDir 8.8, when I run the idmutil script I receive an error stating 'Server idm-srv: is not a valid IDM host'.
I can run dxcmd and ldapsearch successfully and I have double-checked the idmutil.conf and it seems correct. I can also connect via LDAP on port 389.
What am I missing?
Thanks
- Be the first to comment! To leave a comment you need to Login or Register
Re: Getting an Error
Submitted by gchilders on 25 March 2009 - 4:11pm.
Hi, sorry for the delay in responding.
Looking at the script, I see where your error is coming from. I included a servername checking routine, to limit the number of servers to check:
## Validate the host parameter
ERROR3a="Server $DXMLHOST: is not a valid IDM host"
USAGE3a="Valid Hosts: $HOSTLIST"
TESTLIST $DXMLHOST "$HOSTLIST"
if [ $? = "0" ]; then ECHOERROR $DXMLHOST "$ERROR3a" "$USAGE3a"; fi
I did this because all of the eDirectory servers in the tree were not IDM servers.
But I can see that there is a line missing from the published idmutil.conf file:
HOSTLIST="vmsles-1 vmsles-2 vmsles-3 vmsles-4" ## example ##
The 'TESTLIST' function merely tests a supplied parameter against a list of values. If you add the HOSTLIST variable with valid IDM server names in your idmutil.conf file, that should eradicate the error.
- Be the first to comment! To leave a comment you need to Login or Register
Execellent
Submitted by ukrause on 14 March 2009 - 8:02am.
This give some very nice option for Admins to easily observe their environment. Execllent done. Thx.
- Be the first to comment! To leave a comment you need to Login or Register
- Be the first to comment! To leave a comment you need to Login or Register
IDM 3.5 and above
Submitted by mbristow on 19 April 2009 - 6:40pm.
FYI... I wasn't able to get these scripts to work with IDM 3.0.1, and it think it is due to the "-s" switch that gets used with DXCMD. DXCMD version 1.0 that comes with IDM 3.0.1 does not support "-s".
- Be the first to comment! To leave a comment you need to Login or Register


6