#! /bin/sh #==================================================================== # Start/stop script for OpenLDAP 2.2.x and 2.3.x # (http://www.openldap.org). # Use BerkeleyDB utilities and save data in LDIF format. # # chkconfig: 345 85 15 # description: OpenLDAP # # Copyright (C) 2008 Jonathan CLARKE # Copyright (C) 2007 Olivier LI-KIANG-CHEONG # Copyright (C) 2007 Thomas CHEMINEAU # Copyright (C) 2005 Sebastien BAHLOUL # Copyright (C) 2005 Raphael OUAZANA # Copyright (C) 2005 Clement OUDOT # Copyright (C) 2005 LINAGORA # # 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; either version 2 # of the License, or (at your option) any later version. # # 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. # # GPL License: http://www.gnu.org/licenses/gpl.txt # #==================================================================== # More contributions on http://www.linagora.org #==================================================================== #==================================================================== # Changelog #==================================================================== # Version 0.6.5 (07/2008): # - renamed $UID and $GID to $MYUID and $MYGID to enable bash compatibility # since $UID is read-only in bash # - do not run "mkdir $BACKUP_PATH" through $SU command, it is unlikely to # have permission to do that # - corrected bug in check for slurpd activation in slapd.conf (-ne instead # of -eq) # - do not save "slapcat" output through $SU command for backup, # the SLAPD_USER generally does not have write permission for that # Author: Jonathan CLARKE (LINAGORA) # # Version 0.6.4 (03/2008): # - changed default PS command to "ps -efww" to avoid truncating # output, and put it in global variable $PS_COMMAND # Author: Jonathan CLARKE (LINAGORA) # # Version 0.6.3 (01/2008): # - add SLAPD_CONF_DIR global parameter, so that the directory could be run # through a configuration directory unless the traditional slapd.conf file # - replace all ps commands by standard ps commands, for UNIX compatitiblity # (tested under Linux and Solaris), same with id command (add $MYUID and $MYGID) # - some correctives measures, so that special characters are escaped in # $SLAPD_SERVICES global parameter # - only check if SLURPD_BIN is executable if the config file specifies slurpd # replication # Authors: Thomas CHEMINEAU (LINAGORA) # Jonathan CLARKE (LINAGORA) # # Version 0.6 (08/2007) # - Check the pidfile directory exists with correct permissions # - Change the "su command" # Author: Olivier LI-KIANG-CHEONG # # Version 0.5 (05/2007): # - function to get values of parameters in config file. # - do backup and restore operations for all databases declared # in config file (combined with awk and low level of regexp in grep). # - some correctives measures # Author: Thomas CHEMINEAU (LINAGORA) # # Version 0.4 (10/2005): # - change init level # Author: Raphael OUAZANA (LINAGORA) # # Version 0.3 (10/2005): # - check port before killing process, cause several instances can # be running. # - If a user is configured, do a su before launching slurpd # Author: Clement OUDOT (LINAGORA) # # Version 0.2 (09/2005): # - Add chkconfig comments for RedHat # - If a user is configured, do a su before launching utilities # Author: Clement OUDOT (LINAGORA) # # Version 0.1 (08/2005): # - First version with all scripts done by LINAGORA # Author: Clement OUDOT (LINAGORA) #==================================================================== #==================================================================== # Default parameters (if /etc/default/{script_name} is not present) #==================================================================== # IP and port to listen (use wildcard * in IP to listen on all interfaces) IP="*" PORT="389" SSLPORT="636" # OpenLDAP directory and files SLAPD_PATH="/usr/local/" SLAPD_PID_FILE="$SLAPD_PATH/var/run/slapd.pid" SLAPD_CONF="$SLAPD_PATH/etc/openldap/slapd.conf" SLAPD_CONF_DIR="" SLAPD_SERVICES="ldap://$IP:$PORT ldaps://$IP:$SSLPORT" SLAPD_PARAMS="" SLAPD_BIN="$SLAPD_PATH/libexec/slapd" SLAPD_USER="" SLAPD_GROUP="" DATA_PATH="$SLAPD_PATH/var/openldap-data" SLAPCAT_BIN="$SLAPD_PATH/sbin/slapcat" SLAPINDEX_BIN="$SLAPD_PATH/sbin/slapindex" SLAPTEST_BIN="$SLAPD_PATH/sbin/slaptest" SLURPD_PID_FILE="$SLAPD_PATH/var/run/slurpd.pid" SLURPD_PARAMS="" SLURPD_BIN="$SLAPD_PATH/libexec/slurpd" # BerkeleyDB directory and files BDB_PATH="/usr/bin/" DB_ARCHIVE_BIN="$BDB_PATH/bin/db_archive" DB_RECOVER_BIN="$BDB_PATH/bin/db_recover" RECOVER_AT_STARTUP="1" # 0 for OpenLDAP 2.3.x # Backup BACKUP_AT_SHUTDOWN="1" BACKUP_PATH="/tmp/openldap" BACKUP_FILE="$BACKUP_PATH/data_`date +%Y%m%d%H%M%S`.ldif" BACKUP_SUFFIX="`date +%Y%m%d%H%M%S`.ldif" # Other TIMEOUT="60" # Max time to stop process FD_LIMIT="2048" # Max file descriptor # Script specific PROG_NAME=`basename $0 | sed 's/^[KS][0-9][0-9]//'` # For nice messages OS=`uname -s` # To adapt message printing MYUID=`id -u` # For UNIX compatibility => modify this command MYGID=`id -g` # For UNIX compatibility => modify this command PS_COMMAND="ps -efww" # This ensures full width for ps output but doesn't work on Solaris - use "ps -ef" # Return functions' value RETVAL="" #==================================================================== # Message function #==================================================================== message() { # $1: syslog level # $2: message if [ $OS = "Linux" ] then logger -p "local4.$1" -s -t $PROG_NAME -i "$2" else # Try without option -s logger -p "local4.$1" -t $PROG_NAME -i "$2" echo "$PROG_NAME: $2" fi } #==================================================================== # Specific functions #==================================================================== get_confvalues() { # $1: parameter in slapd.conf # $RETVAL : list of values list=`grep "^$1[[:space:]]" $SLAPD_CONF | grep -v '^#' | awk '{ print $2;}' | sed -e 's/"//g'` if [ "$list" ]; then RETVAL="$list" else RETVAL="" fi } #==================================================================== # Load specific parameters #==================================================================== if [ -f /etc/default/$PROG_NAME ] then . /etc/default/$PROG_NAME message "info" "[INFO] using /etc/default/$PROG_NAME for configuration" else message "info" "[INFO] using built-in configuration - this may cause some problems" fi #==================================================================== # Initiate 'su' command #==================================================================== if [ "$SLAPD_USER" -a $MYUID -eq 0 ] then SU="su -s /bin/bash - $SLAPD_USER -c " fi #==================================================================== # Initial checks #==================================================================== # Make sure the pidfile directory exists with correct permissions piddir=`dirname "$SLAPD_PID_FILE"` if [ ! -d "$piddir" ]; then mkdir -p "$piddir" [ -z "$SLAPD_USER" ] || chown -R "$SLAPD_USER" "$piddir" [ -z "$SLAPD_GROUP" ] || chgrp -R "$SLAPD_GROUP" "$piddir" fi # Rights to execute binaries for i in "$SLAPD_BIN" "$SLAPCAT_BIN" "$SLAPINDEX_BIN" "$SLAPTEST_BIN" "$DB_ARCHIVE_BIN" "$DB_RECOVER_BIN" do if [ ! -x $i ] then message "alert" "[ALERT] can't execute $i" exit 1 fi done # Rights to read files for i in "$SLAPD_CONF" do if [ ! -r $i ] then message "alert" "[ALERT] can't read $i" exit 1 fi done # Activate slurpd? ACTIVATE_SLURPD=`grep "^replica" $SLAPD_CONF | wc -l` # Right to execute slurpd, if used if [ $ACTIVATE_SLURPD -ne 0 -a ! -x "$SLURPD_BIN" ] then message "alert" "[ALERT] can't not execute $SLURPD_BIN" exit 1 fi # Is there a configuration directory ? if [ "$SLAPD_CONF_DIR" -a ! -w "$SLAPD_CONF_DIR" ] then message "alert" "[ALERT] can't write to configuration directory $SLAPD_CONF_DIR" exit 1 fi # Are you root (for port < 1024)? if [ $PORT -lt 1024 -a $MYUID -ne 0 ] then message "alert" "[ALERT] only root can launch OpenLDAP on port $PORT" exit 1 fi #==================================================================== # Functions #==================================================================== start_slapd() { # Check if db_recover is required if [ $RECOVER_AT_STARTUP -eq 1 ] then db_recover else message "info" "[INFO] no db_recover done" fi # Start message message "info" "Launching OpenLDAP..." # File descriptor limit, only for root if [ $MYUID -eq 0 ] then ulimit -n $FD_LIMIT if [ $? -eq 0 ] then message "info" "[OK] file descriptor limit set to $FD_LIMIT" else message "warning" "[WARNING] Fail to set file descriptor limit to $FD_LIMIT, going to next step" fi else message "info" "[INFO] file descriptor limit not modified (require root privileges)" fi # Parameters if [ "$SLAPD_CONF_DIR" ] then SLAPD_PARAMS="$SLAPD_PARAMS -F $SLAPD_CONF_DIR" elif [ "$SLAPD_CONF" ] then SLAPD_PARAMS="$SLAPD_PARAMS -f $SLAPD_CONF" fi if [ "$SLAPD_USER" -a $MYUID -eq 0 ] then SLAPD_PARAMS="$SLAPD_PARAMS -u $SLAPD_USER" fi if [ "$SLAPD_GROUP" -a $MYGID -eq 0 ] then SLAPD_PARAMS="$SLAPD_PARAMS -g $SLAPD_GROUP" fi # It's time to start slapd $SLAPD_BIN -h "$SLAPD_SERVICES" $SLAPD_PARAMS sleep 1 # Presence of PID file if [ ! -r $SLAPD_PID_FILE ] then message "alert" "[ALERT] no PID file for slapd" exit 1 fi # Is slapd launched? PID=`cat $SLAPD_PID_FILE` if [ ! -e /proc/$PID ] then message "alert" "[ALERT] slapd not running" exit 1 else message "info" "[OK] OpenLDAP started on port $PORT and $SSLPORT" fi } start_slurpd() { # Start message message "info" "Launching OpenLDAP replication..." if [ $ACTIVATE_SLURPD -eq 0 ] then message "info" "[INFO] no replica found in configuration, aborting lauching slurpd" return 1 fi # Parameters if [ "$SLAPD_CONF_DIR" ] then SLAPD_PARAMS="$SLAPD_PARAMS -F $SLAPD_CONF_DIR" elif [ "$SLAPD_CONF" ] then SLAPD_PARAMS="$SLAPD_PARAMS -f $SLAPD_CONF" fi # It's time to start slurpd if [ -z "$SU" ] then $SLURPD_BIN $SLURPD_PARAMS else $SU "$SLURPD_BIN $SLURPD_PARAMS" fi sleep 1 # Presence of PID file if [ ! -r $SLURPD_PID_FILE ] then message "alert" "[ALERT] no PID file for slurpd" exit 1 fi # Is slurpd launched? PID=`cat $SLURPD_PID_FILE` if [ ! -e /proc/$PID ] then message "alert" "[ALERT] slurpd not running" exit 1 else message "info" "[OK] OpenLDAP replication started" fi } stop_slapd() { # Stop message message "info" "Halting OpenLDAP..." # Presence of PID file if [ ! -r $SLAPD_PID_FILE ] then message "info" "[INFO] can't read PID file, to stop slapd try: $0 forcestop" return 1 else PID=`cat $SLAPD_PID_FILE` kill -INT $PID # Waiting loop i=0 while [ -e /proc/$PID ] do if [ $i -eq $TIMEOUT ] then # Timeout message "alert" "[ALERT] slapd still running (PID $PID), try: $0 forcestop" exit 1 fi i=`expr $i + 1` sleep 1 done message "info" "[OK] OpenLDAP stopped after $i seconds" fi # Backup if necessary if [ $BACKUP_AT_SHUTDOWN -eq 1 ] then backup else message "info" "[INFO] no data backup done" fi } stop_slurpd() { # Stop message message "info" "Halting OpenLDAP replication..." # Desctivate slurpd? DESACTIVATE_SLURPD=`cat $SLAPD_CONF | grep "^replica" | wc -l` if [ $DESACTIVATE_SLURPD -eq 0 ] then message "info" "[INFO] no replica found in configuration, aborting stopping slurpd" return 1 fi # Presence of PID file if [ ! -r $SLURPD_PID_FILE ] then message "warning" "[WARNING] can't read PID file, to stop slurpd try: $0 forcestop" else PID=`cat $SLURPD_PID_FILE` kill -INT $PID # Waiting loop i=0 while [ -e /proc/$PID ] do if [ $i -eq $TIMEOUT ] then # Timeout, need to kill message "alert" "[ALERT] slurpd still running (PID $PID), try: $0 forcestop" return 1 fi i=`expr $i + 1` sleep 1 done message "info" "[OK] OpenLDAP replication stopped after $i seconds" fi } forcestop() { # Stop message message "info" "Killing OpenLDAP with force..." # Presence of PID file if [ ! -r $SLAPD_PID_FILE ] then # Escape special characters into $SLAPD_SERVICES slapd_services="`echo "$SLAPD_SERVICES" | sed 's/\*/\\\*/g'`" # Check if any slapd process are running if [ `$PS_COMMAND | grep $SLAPD_BIN | grep "$slapd_services" | grep -v grep | wc -l` -eq 0 ] then message "info" "[INFO] Found no slapd process running with $SLAPD_SERVICES" else # Try a killall /usr/bin/killall -KILL $SLAPD_BIN if [ $? -eq 0 ] then message "info" "[OK] all slapd process killed with force" else message "alert" "[ALERT] Unable to kill slapd with force" exit 1 fi fi else PID=`cat $SLAPD_PID_FILE` kill -KILL $PID if [ $? -eq 0 ] then message "info" "[OK] slapd process killed with force (PID $PID)" else message "alert" "[ALERT] Unable to kill slapd with force (PID $PID)" exit 1 fi fi # Stop message message "info" "Killing OpenLDAP replication with force..." # Presence of PID file if [ ! -r $SLURPD_PID_FILE ] then # Check if any slapd process are running if [ `$PS_COMMAND | grep $SLURPD_BIN | grep -v grep | wc -l` -eq 0 ] then message "info" "[INFO] Found no slurpd process running" else # Try a killall /usr/bin/killall -KILL $SLURPD_BIN if [ $? -eq 0 ] then message "info" "[OK] slurpd process killed with force" else message "alert" "[ALERT] Unable to kill slurpd with force" exit 1 fi fi else PID=`cat $SLURPD_PID_FILE` kill -KILL $PID if [ $? -eq 0 ] then message "info" "[OK] slurpd process killed with force (PID $PID)" else message "alert" "[ALERT] Unable to kill slurpd with force (PID $PID)" exit 1 fi fi } slapd_status() { # Return 0 if slapd is running, 1 if slapd is stopped, 2 if we can't say if [ ! -r $SLAPD_PID_FILE ] then # Escape special characters into $SLAPD_SERVICES slapd_services="`echo "$SLAPD_SERVICES" | sed 's/\*/\\\*/g'`" # Check if any slapd process are running if [ `$PS_COMMAND | grep $SLAPD_BIN | grep "$slapd_services" | grep -v grep | wc -l` -eq 0 ] then return 1 else return 2 fi else PID=`cat $SLAPD_PID_FILE` fi if [ ! -e /proc/$PID ] then return 1 else return 0 fi } configtest() { # Start message message "info" "Launching OpenLDAP configuration test..." # slapd must be stopped slapd_status if [ $? -ne 1 ] then message "alert" "[ALERT] slapd is running or was not correctly shut down, aborting configuration test" exit 1 else # slaptest if [ -z "$SU" ] then $SLAPTEST_BIN -f "$SLAPD_CONF" -u > /dev/null 2>&1 else $SU "$SLAPTEST_BIN -f \"$SLAPD_CONF\" -u > /dev/null 2>&1" fi if [ $? -eq 0 ] then message "info" "[OK] OpenLDAP configuration test successful" else message "alert" "[ALERT] OpenLDAP configuration test failed" exit 1 fi fi } db_recover() { # Start message message "info" "Launching OpenLDAP database recovery..." # slapd must be stopped slapd_status if [ $? -ne 1 ] then message "alert" "[ALERT] slapd is running or was not correctly shut down, aborting database recovery" exit 1 fi # Do backup for all databases, # except if DATA_PATH is 'auto' dbdirs="$DATA_PATH" if [ "$DATA_PATH" = "auto" ] then get_confvalues "directory" dbdirs=$RETVAL if [ -z "$dbdirs" ] then message "alert" "[ALERT] No database directories found" exit 1 fi fi for dbdir in $dbdirs do # db_recover if [ -z "$SU" ] then $DB_RECOVER_BIN -h "$dbdir" else $SU "$DB_RECOVER_BIN -h \"$dbdir\"" fi if [ $? -eq 0 ] then message "info" "[OK] OpenLDAP $dbdir database recovery successful" else message "alert" "[ALERT] OpenLDAP $dbdir database recovery failed" exit 1 fi done } reindex() { # Start message message "info" "Launching OpenLDAP database reindexing..." # slapd must be stopped slapd_status if [ $? -ne 1 ] then message "alert" "[ALERT] slapd is running or was not correctly shut down, aborting reindexing" exit 1 else # slapindex if [ -z "$SU" ] then $SLAPINDEX_BIN -f "$SLAPD_CONF" else $SU "$SLAPINDEX_BIN -f \"$SLAPD_CONF\"" fi if [ $? -eq 0 ] then message "info" "[OK] OpenLDAP database reindexing successful" else message "alert" "[ALERT] OpenLDAP database reindexing failed" exit 1 fi fi } removelogs() { # Start message message "info" "Launching OpenLDAP database logs archiving..." # slapd must be stopped slapd_status if [ $? -ne 1 ] then message "alert" "[ALERT] slapd is running or was not correctly shut down, aborting archiving" exit 1 fi # Do backup for all databases, # except if DATA_PATH is 'auto' dbdirs="$DATA_PATH" if [ "$DATA_PATH" = "auto" ] then get_confvalues "directory" dbdirs=$RETVAL if [ -z "$dbdirs" ] then message "alert" "[ALERT] No database directories found" exit 1 fi fi for dbdir in $dbdirs do # db_archive if [ -z "$SU" ] then $DB_ARCHIVE_BIN -h "$dbdir" -d else $SU "$DB_ARCHIVE_BIN -h \"$dbdir\" -d" fi if [ $? -eq 0 ] then message "info" "[OK] OpenLDAP $dbdir database logs archiving successful" else message "alert" "[ALERT] OpenLDAP $dbdir database logs archiving failed" exit 1 fi done } backup() { # Start message message "info" "Launching OpenLDAP database backup..." # Backup directory mkdir -p "$BACKUP_PATH" # Do backup for all databases, # except if DATA_PATH is 'auto' dbdirs="$DATA_PATH" dbsufs="" if [ "$DATA_PATH" = "auto" ] then get_confvalues "directory" dbdirs=$RETVAL get_confvalues "suffix" dbsufs=$RETVAL if [ -z "$dbdirs" -o -z "$dbsufs" ] then message "alert" "[ALERT] No database directories found" exit 1 fi fi i=1 for dbdir in $dbdirs do # Table is not allowed, so we use awk suf=`echo $dbsufs | awk -v j="$i" 'BEGIN{OFS=" "} {print $j}'` dir=`basename $dbdir` file="$BACKUP_PATH/$dir-$BACKUP_SUFFIX" base="-b $suf" if [ -z $suf ] then base="" fi # slapcat if [ -z "$SU" ] then $SLAPCAT_BIN $base -f "$SLAPD_CONF" -l "$file" else $SU "$SLAPCAT_BIN $base -f \"$SLAPD_CONF\"" > "$file" fi # alert if [ $? -eq 0 ] then message "info" "[OK] data save in $file" else message "alert" "[ALERT] OpenLDAP database backup failed" exit 1 fi i=`expr $i + 1` done } #==================================================================== # Action switch #==================================================================== case $1 in start) configtest start_slurpd start_slapd ;; stop) stop_slapd stop_slurpd ;; forcestop) forcestop ;; restart) stop_slapd stop_slurpd configtest start_slurpd start_slapd ;; configtest) configtest ;; db_recover) db_recover ;; reindex) reindex ;; removelogs) removelogs ;; backup) backup ;; *) echo "Usage: $0 {start|stop|forcestop|restart|configtest|db_recover|reindex|removelogs|backup}" exit 1 ;; esac #==================================================================== # Exit #==================================================================== exit 0