--- /dev/null
+#!/bin/bash
+
+set -e
+set -u
+
+VERBOSE="n"
+DEBUG="n"
+QUIET='n'
+SIMULATE='n'
+YES="n"
+
+VERSION="1.1"
+
+# console colors:
+RED=""
+YELLOW=""
+GREEN=""
+# BLUE=""
+CYAN=""
+NORMAL=""
+
+BASENAME=$(basename "${0}")
+BASE_DIR=$( dirname "$0" )
+cd "${BASE_DIR}" || exit 99
+BASE_DIR=$( readlink -f . )
+
+declare -a INSTANCES=()
+INSTANCES+=( 'dpx-legacy' )
+INSTANCES+=( 'dpx-prd' )
+INSTANCES+=( 'dpx-dev' )
+INSTANCES+=( 'spk-prd' )
+INSTANCES+=( 'spk-dev' )
+
+declare -a USED_INSTANCES=()
+
+declare -A LDAP_URLS=()
+LDAP_URLS['dpx-legacy']="ldap://ldap-legacy.pixelpark.com"
+LDAP_URLS['dpx-prd']="ldaps://prd-ds.pixelpark.com"
+LDAP_URLS['dpx-dev']="ldaps://dev-ldap2.pixelpark.com"
+LDAP_URLS['spk-prd']="ldaps://live-ldap.spk.pixelpark.net"
+LDAP_URLS['spk-dev']="ldaps://stage-ldap.spk.pixelpark.net"
+
+declare -A BIND_DNS=()
+BIND_DNS['dpx-legacy']="cn=admin"
+BIND_DNS['dpx-prd']="cn=admin"
+BIND_DNS['dpx-dev']="cn=admin"
+BIND_DNS['spk-prd']="cn=admin"
+BIND_DNS['spk-dev']="cn=admin"
+
+declare -A BIND_PW_FILES=()
+BIND_PW_FILES['dpx-legacy']="${HOME}/.private/ldap-admin-wonl.txt"
+BIND_PW_FILES['dpx-prd']="${HOME}/.private/dirsrv-dpx-prd-admin-pwd-wonl.txt"
+BIND_PW_FILES['dpx-dev']="${HOME}/.private/dirsrv-dpx-dev-admin-pwd-wonl.txt"
+BIND_PW_FILES['spk-prd']="${HOME}/.private/dirsrv-mngr-spk-live.pwd-wonl.txt"
+BIND_PW_FILES['spk-dev']="${HOME}/.private/dirsrv-mngr-spk-stage.pwd-wonl.txt"
+
+declare -A SUFFIXES=()
+SUFFIXES['dpx-legacy']="o=isp"
+SUFFIXES['dpx-prd']="o=isp"
+SUFFIXES['dpx-dev']="o=isp"
+SUFFIXES['spk-prd']="dc=spk,dc=pixelpark,dc=net"
+SUFFIXES['spk-dev']="dc=spk,dc=pixelpark,dc=net"
+
+declare -a USERS=()
+
+LDIF_FILE=
+
+USER=
+INSTANCE=
+LDAP_URL=
+BIND_DN=
+BIND_PW_FILE=
+SUFFIX=
+USER_DN=
+USER_CN=
+USER_MAIL=
+USER_NAME=
+
+# none
+EMPTY_PASSWD="CWEQxQmmAOSuI"
+
+CURRENT_TS=$( date +'%s' )
+SHADOW_EXPIRE=$( echo "( ${CURRENT_TS} / 3600 / 24 ) - 100" | bc )
+
+NEW_LOGIN_SHELL="/bin/false"
+
+#-------------------------------------------------------------------
+detect_color() {
+
+ local safe_term="${TERM//[^[:alnum:]]/?}"
+ local match_lhs=""
+ local use_color="false"
+ local term=
+
+ if [[ -f ~/.dir_colors ]] ; then
+ match_lhs="${match_lhs}$( grep '^TERM ' ~/.dir_colors | sed -e 's/^TERM *//' -e 's/ .*//')"
+ fi
+ if [[ -f /etc/DIR_COLORS ]] ; then
+ match_lhs="${match_lhs}$( grep '^TERM ' /etc/DIR_COLORS | sed -e 's/^TERM *//' -e 's/ .*//')"
+ fi
+ if [[ -z ${match_lhs} ]] ; then
+ type -P dircolors >/dev/null && \
+ match_lhs=$(dircolors --print-database | grep '^TERM ' | sed -e 's/^TERM *//' -e 's/ .*//')
+ fi
+ for term in ${match_lhs} ; do
+ # shellcheck disable=SC2053
+ if [[ "${safe_term}" == ${term} || "${TERM}" == ${term} ]] ; then
+ use_color="true"
+ break
+ fi
+ done
+
+ # console colors:
+ if [ "${use_color}" = "true" ] ; then
+ RED="\\033[38;5;196m"
+ YELLOW="\\033[38;5;226m"
+ GREEN="\\033[38;5;46m"
+ # BLUE="\\033[38;5;27m"
+ CYAN="\\033[38;5;36m"
+ NORMAL="\\033[39m"
+ # HAS_COLORS="y"
+ else
+ RED=""
+ YELLOW=""
+ GREEN=""
+ # BLUE=""
+ CYAN=""
+ NORMAL=""
+ fi
+
+ local my_tty
+
+ my_tty=$(tty)
+ if [[ "${my_tty}" =~ 'not a tty' ]] ; then
+ my_tty='-'
+ fi
+
+}
+detect_color
+
+#------------------------------------------------------------------------------
+my_date() {
+ date +'%F %T.%N %:::z'
+}
+
+#------------------------------------------------------------------------------
+debug() {
+ if [[ "${VERBOSE}" != "y" ]] ; then
+ return 0
+ fi
+ echo -e " * [$(my_date)] [${BASENAME}:${CYAN}DEBUG${NORMAL}]: $*" >&2
+}
+
+#------------------------------------------------------------------------------
+info() {
+ if [[ "${QUIET}" == "y" ]] ; then
+ return 0
+ fi
+ if [[ "${VERBOSE}" == "y" ]] ; then
+ echo -e " ${GREEN}*${NORMAL} [$(my_date)] [${BASENAME}:${GREEN}INFO${NORMAL}] : $*"
+ else
+ echo -e " ${GREEN}*${NORMAL} $*"
+ fi
+}
+
+#------------------------------------------------------------------------------
+warn() {
+ if [[ "${VERBOSE}" == "y" ]] ; then
+ echo -e " ${YELLOW}*${NORMAL} [$(my_date)] [${BASENAME}:${YELLOW}WARN${NORMAL}] : $*" >&2
+ else
+ echo -e " ${YELLOW}*${NORMAL} [${BASENAME}:${YELLOW}WARN${NORMAL}] : $*" >&2
+ fi
+}
+
+#------------------------------------------------------------------------------
+error() {
+ if [[ "${VERBOSE}" == "y" ]] ; then
+ echo -e " ${RED}*${NORMAL} [$(my_date)] [${BASENAME}:${RED}ERROR${NORMAL}]: $*" >&2
+ else
+ echo -e " ${RED}*${NORMAL} [${BASENAME}:${RED}ERROR${NORMAL}]: $*" >&2
+ fi
+}
+
+#------------------------------------------------------------------------------
+description() {
+ cat <<-EOF
+
+ Disables a LDAP User by Setting its inetStatus to '${CYAN}disabled${NORMAL}',
+ setting the Login Shell to '${CYAN}/bin/false${NORMAL}', setting the password to a dummy value
+ and removing the appropriate entries in groups.
+
+ EOF
+
+}
+
+#------------------------------------------------------------------------------
+draw_line() {
+ if [[ "${QUIET}" == "y" ]] ; then
+ return 0
+ fi
+ echo "---------------------------------------------------"
+}
+
+#------------------------------------------------------------------------------
+empty_line() {
+ if [[ "${QUIET}" == "y" ]] ; then
+ return 0
+ fi
+ echo
+}
+
+#------------------------------------------------------------------------------
+usage() {
+
+ local inst_out=""
+ local inst=
+ local i=0
+
+ for inst in "${INSTANCES[@]}" ; do
+ i=$(( $i + 1 ))
+ if [[ "${i}" != "1" ]] ; then
+ if [[ "${i}" == "${#INSTANCES[*]}" ]] ; then
+ inst_out+=" and "
+ else
+ inst_out+=", "
+ fi
+ fi
+ inst_out+="'${CYAN}${inst}${NORMAL}'"
+ done
+
+ cat <<-EOF
+ Usage: ${BASENAME} [[-I|--instance INSTANCE] -I ...] [-s|--simulate] [-d|--debug] [[-v|--verbose] | [-q|--quiet]] [--nocolor] USER1 [USER2 ...]
+ ${BASENAME} [-h|--help]
+ ${BASENAME} [-V|--version]
+
+ The mandatory users to disable are the POSIX user names (in LDAP: 'uid'), e.g. '${CYAN}max.mustermann${NORMAL}'.
+
+ Options:
+ -I|--instance INSTANCE
+ The LDAP instance to use as the target of this script. If left empty, all instances are changed.
+ May be one or more of ${inst_out}.
+ -s|--simulate Simulation mode, nothing is really done.
+ -d|--debug Debug output (bash -x).
+ -v|--verbose Set verbosity on.
+ -q|--quiet Quiet execution. Mutually exclusive to --verbose.
+ --nocolor Don't use colors on display.
+ -h|--help Show this output and exit.
+ -V|--version Prints out version number of the script and exit.
+
+ EOF
+
+}
+
+#------------------------------------------------------------------------------
+get_options() {
+
+ local tmp=
+ local short_options="I:sydvqhV"
+ local long_options="inst:,instance:,simulate,yes,debug,verbose,quiet,help,version"
+ local py_version=
+ local py_found="n"
+ local ret=
+ local inst=
+
+ set +e
+ tmp=$( getopt -o "${short_options}" --long "${long_options}" -n "${BASENAME}" -- "$@" )
+ ret="$?"
+ if [[ "${ret}" != 0 ]] ; then
+ echo "" >&2
+ echo -e "$( usage )" >&2
+ exit 1
+ fi
+ set -e
+
+ # Note the quotes around `$TEMP': they are essential!
+ eval set -- "${tmp}"
+
+ while true ; do
+ case "$1" in
+ -I|--inst|--instance)
+ USED_INSTANCES+=("$2" )
+ shift
+ shift
+ ;;
+ -s|--simulate)
+ SIMULATE="y"
+ shift
+ ;;
+ -y|--yes)
+ YES="y"
+ shift
+ ;;
+ -d|--debug)
+ DEBUG="y"
+ shift
+ ;;
+ -v|--verbose)
+ VERBOSE="y"
+ shift
+ ;;
+ -q|--quiet)
+ QUIET="y"
+ RED=""
+ YELLOW=""
+ GREEN=""
+ # BLUE=""
+ CYAN=""
+ NORMAL=""
+ # HAS_COLORS="n"
+ shift
+ ;;
+ --nocolor)
+ RED=""
+ YELLOW=""
+ GREEN=""
+ # BLUE=""
+ CYAN=""
+ NORMAL=""
+ # HAS_COLORS="n"
+ shift
+ ;;
+ -h|--help)
+ echo -e "$( description )"
+ echo
+ echo -e "$( usage )"
+ exit 0
+ ;;
+ -V|--version)
+ echo "${BASENAME} version: ${VERSION}"
+ exit 0
+ ;;
+ --) shift
+ break
+ ;;
+ *) echo "Internal error!"
+ exit 1
+ ;;
+ esac
+ done
+
+ while [[ "$#" != "0" ]] ; do
+ USERS+=( "$1" )
+ shift
+ done
+
+ if [[ "${DEBUG}" = "y" ]] ; then
+ set -x
+ fi
+
+ if [[ "${VERBOSE}" == "y" && "${QUIET}" == "y" ]] ; then
+ error "Options '${RED}--verbose${NORMAL}' and '${RED}--quiet${NORMAL}' are mutually exclusive."
+ echo >&2
+ echo -e "$( usage )" >&2
+ exit 1
+ fi
+
+ if [[ "${#USED_INSTANCES[*]}" == 0 ]] ; then
+ for inst in "${INSTANCES[@]}" ; do
+ USED_INSTANCES+=( "${inst}" )
+ done
+ fi
+
+ local instances_ok='y'
+ for inst in "${USED_INSTANCES[@]}" ; do
+ if [[ ! -v "LDAP_URLS[${inst}]" ]] ; then
+ instances_ok='n'
+ error "Given instance '${RED}${inst}${NORMAL}' is invalid."
+ fi
+ done
+ if [[ "${instances_ok}" == "n" ]] ; then
+ echo >&2
+ echo -e "$( usage )" >&2
+ exit 1
+ fi
+
+ if [[ "${#USERS[*]}" == "0" ]] ; then
+ echo >&2
+ warn "No user to disable given."
+ echo >&2
+ echo -e "$( usage )" >&2
+ exit 1
+ fi
+
+ if [[ "${SIMULATE}" == "y" ]] ; then
+ echo
+ echo -e "${CYAN}---------------------------------------------${NORMAL}"
+ echo -e " ${YELLOW}Simulation mode${NORMAL}"
+ echo -e " ${CYAN}Nothing will be done in real.${NORMAL}"
+ echo -e "${CYAN}---------------------------------------------${NORMAL}"
+ sleep 0.5
+ fi
+
+}
+
+#------------------------------------------------------------------------------
+RM() {
+
+ if [[ "${VERBOSE}" == "y" ]] ; then
+ rm --verbose "$@"
+ else
+ rm "$@"
+ fi
+
+}
+
+#------------------------------------------------------------------------------
+cleanup_tmp_file() {
+ if [[ -n "${LDIF_FILE}" ]] ; then
+ if [[ -e "${LDIF_FILE}" ]] ; then
+ debug "Removing temporary file '${CYAN}${LDIF_FILE}${NORMAL}' ..."
+ RM --force --recursive "${LDIF_FILE}"
+ fi
+ fi
+}
+
+#------------------------------------------------------------------------------
+yes_or_no() {
+
+ local msg="$1"
+ local timeout="5"
+ if [[ "$#" -gt 1 ]] ; then
+ timeout="$2"
+ fi
+
+ if [[ "${YES}" == "y" ]] ; then
+ return 0
+ fi
+
+ local answer=
+ debug "Trying to get an answer with a timeout of ${timeout} seconds."
+ printf "${msg}"
+ if read -t "${timeout}" answer ; then
+ debug "Got an answer: '${answer}'"
+ else
+ echo
+ return 1
+ fi
+
+ local first_letter=$( echo "${answer}" | tr '[:upper:]' '[:lower:]' | sed -e 's/^\(.\).*/\1/' )
+ if [[ "${first_letter}" == 'y' || "${first_letter}" == 'j' ]] ; then
+ return 0
+ else
+ return 1
+ fi
+
+}
+
+#------------------------------------------------------------------------------
+get_user_dn() {
+
+ debug "Trying to detect the DN uf user '${CYAN}${USER}${NORMAL}' ..."
+
+ if [[ ! -f "${BIND_PW_FILE}" ]] ; then
+ error "Did not found password file '${RED}${BIND_PW_FILE}${NORMAL}' of Bind DN '${CYAN}${BIND_DN}${NORMAL}' of LDAP instance '${GREEN}${INSTANCE}${NORMAL}'."
+ empty_line
+ exit 5
+ fi
+
+ USER_DN=''
+ USER_CN=
+ USER_MAIL=
+ USER_NAME=
+ filter="(&(objectClass=*)(uid=${USER}))"
+ cmd="ldapsearch -x -LLL -o ldif-wrap=no -H '${LDAP_URL}' "
+ cmd+="-b \"${SUFFIX}\" -x -D \"${BIND_DN}\" -y \"${BIND_PW_FILE}\" "
+ cmd+="\"${filter}\" dn cn mail"
+ # cmd+="\"${filter}\" dn cn mail | grep '^dn:' | sed -e 's/^dn:[ ][ ]*//i' | head -n 1"
+ debug "Executing: ${cmd}"
+ local user_info=$( eval ${cmd} )
+
+ local count=$( echo "${user_info}" | grep '^dn:' | wc -l )
+ if [[ "${count}" == "0" ]] ; then
+ warn "Did not found DN of uid '${YELLOW}${USER}${NORMAL}'."
+ return 1
+ fi
+ if [[ "${count}" -gt 1 ]] ; then
+ warn "User Id '${YELLOW}${USER}${NORMAL}' is not unique."
+ return 1
+ fi
+
+ USER_DN=$( echo "${user_info}" | grep '^dn:' | sed -e 's/^dn:[ ][ ]*//i' )
+ USER_CN=$( echo "${user_info}" | grep '^cn:' )
+ if echo "${USER_CN}" | grep -q '^cn::' ; then
+ USER_CN=$( echo "${USER_CN}" | sed -e 's/^cn::[ ][ ]*//i' | base64 -d )
+ else
+ USER_CN=$( echo "${USER_CN}" | sed -e 's/^cn:[ ][ ]*//i' )
+ fi
+ USER_MAIL=$( echo "${user_info}" | grep '^mail:' | sed -e 's/^mail:[ ][ ]*//i' | head -n 1 )
+
+ USER_NAME="${USER_CN}"
+ if [[ -n "${USER_MAIL}" ]] ; then
+ USER_NAME+=" <${USER_MAIL}>"
+ fi
+
+ local question="Do you want to disable User '${CYAN}${USER_NAME}${NORMAL}' (${CYAN}${USER_DN}${NORMAL}) [${RED}y${NORMAL}|${YELLOW}N${NORMAL}] ? "
+ if yes_or_no "${question}" ; then
+ info "User '${CYAN}${USER_NAME}${NORMAL}' (${CYAN}${USER_DN}${NORMAL}) will be disabled."
+ return 0
+ fi
+ info "User '${CYAN}${USER_NAME}${NORMAL}' (${CYAN}${USER_DN}${NORMAL}) will be left untouched."
+ return 1
+
+}
+
+#------------------------------------------------------------------------------
+disabling_password() {
+
+ local old_pwd=
+ local cmd=
+ local value=
+ local locked_pwd_encoded=
+
+ info "Disabling password of '${CYAN}${USER_NAME}${NORMAL}'."
+
+ debug "Getting current hashed password of user '${CYAN}${USER}${NORMAL}' ..."
+
+ cmd="ldapsearch -x -LLL -o ldif-wrap=no -H '${LDAP_URL}' -s base "
+ cmd+="-b \"${USER_DN}\" -x -D \"${BIND_DN}\" -y \"${BIND_PW_FILE}\" userPassword "
+ cmd+="| grep -i '^userPassword:' | head -n 1"
+ debug "Executing: ${cmd}"
+ value=$( eval ${cmd} )
+
+ if [[ -n "${value}" ]] ; then
+ if echo "${value}" | grep -q -i "^userPassword::" ; then
+ old_pwd=$( printf "${value}" | sed -e 's/^userPassword::[ ][ ]*//i' | base64 -d )
+ else
+ old_pwd=$( printf "${value}" | sed -e 's/^userPassword:[ ][ ]*//i' )
+ fi
+ debug "Found old password hash '${CYAN}${USER}${NORMAL}': '${CYAN}${old_pwd}${NORMAL}'."
+ else
+ debug "User '${CYAN}${USER}${NORMAL}' has currently no password."
+ fi
+
+ local empty_pwd_encoded=$( echo "${EMPTY_PASSWD}" | base64 -w 0 )
+
+ if [[ -n "${old_pwd}" ]] ; then
+ locked_pwd_encoded=$( echo "${old_pwd}" | base64 -w 0 )
+ cat > "${LDIF_FILE}" <<-EOF
+ dn: ${USER_DN}
+ changetype: modify
+ add: carLicense
+ carLicense:: ${locked_pwd_encoded}
+ -
+ delete: userPassword
+ -
+ replace: shadowExpire
+ shadowExpire: ${SHADOW_EXPIRE}
+ EOF
+ else
+ cat > "${LDIF_FILE}" <<-EOF
+ dn: ${USER_DN}
+ changetype: modify
+ replace: shadowExpire
+ shadowExpire: ${SHADOW_EXPIRE}
+ EOF
+ fi
+ echo "-" >> "${LDIF_FILE}"
+ echo '' >> "${LDIF_FILE}"
+
+ if [[ "${VERBOSE}" == "y" ]] ; then
+ debug "Resulting LDIF:"
+ cat "${LDIF_FILE}"
+ fi
+
+ cmd="ldapmodify -H \"${LDAP_URL}\" -x -D \"${BIND_DN}\" -y \"${BIND_PW_FILE}\""
+ cmd+=" -f \"$( readlink -f "${LDIF_FILE}" )\""
+ debug "Executing: ${cmd}"
+ if [[ "${SIMULATE}" != "y" ]] ; then
+ eval $cmd
+ fi
+ debug "Done."
+
+}
+
+#------------------------------------------------------------------------------
+setting_user_status() {
+
+ info "Setting UserStatus of '${CYAN}${USER_NAME}${NORMAL}' to '${CYAN}disabled${NORMAL}' ..."
+
+ cat > "${LDIF_FILE}" <<-EOF
+ dn: ${USER_DN}
+ changetype: modify
+ replace: inetUserStatus
+ inetUserStatus: inactive
+ -
+ replace: mailUserStatus
+ mailUserStatus: inactive
+ -
+
+ EOF
+
+ if [[ "${VERBOSE}" == "y" ]] ; then
+ debug "Resulting LDIF:"
+ cat "${LDIF_FILE}"
+ fi
+
+ cmd="ldapmodify -H \"${LDAP_URL}\" -x -D \"${BIND_DN}\" -y \"${BIND_PW_FILE}\""
+ cmd+=" -f \"$( readlink -f "${LDIF_FILE}" )\""
+ debug "Executing: ${cmd}"
+ if [[ "${SIMULATE}" != "y" ]] ; then
+ eval $cmd
+ fi
+ debug "Done."
+
+}
+
+#------------------------------------------------------------------------------
+remove_uniq_member() {
+
+ local group_dn="$1"
+
+ info "Removing '${CYAN}${USER}${NORMAL}' from group '${CYAN}${group_dn}${NORMAL}' ..."
+
+ local cmd=
+
+ cat > "${LDIF_FILE}" <<-EOF
+ dn: ${group_dn}
+ changetype: modify
+ delete: uniqueMember
+ uniqueMember: ${USER_DN}
+ -
+
+ EOF
+
+ if [[ "${VERBOSE}" == "y" ]] ; then
+ debug "Resulting LDIF:"
+ cat "${LDIF_FILE}"
+ fi
+
+ cmd="ldapmodify -H \"${LDAP_URL}\" -x -D \"${BIND_DN}\" -y \"${BIND_PW_FILE}\""
+ cmd+=" -f \"$( readlink -f "${LDIF_FILE}" )\""
+ debug "Executing: ${cmd}"
+ if [[ "${SIMULATE}" != "y" ]] ; then
+ eval $cmd
+ fi
+ debug "Done."
+
+}
+
+#------------------------------------------------------------------------------
+remove_all_uniq_member() {
+
+ empty_line
+ info "Removing all entries of kind '${CYAN}uniqueMember=${BIND_DN}${NORMAL}' ..."
+
+ local group_dn=
+ local cmd=
+
+ local oifs="${IFS}"
+ IFS="
+"
+
+ cmd="ldapsearch -x -LLL -o ldif-wrap=no -H '${LDAP_URL}' -s sub "
+ cmd+="-b \"${SUFFIX}\" -x -D \"${BIND_DN}\" -y \"${BIND_PW_FILE}\" "
+ cmd+="\"(uniqueMember=${USER_DN})\" dn | "
+ cmd+="grep -i '^dn:' | sed -e 's/^dn: //i'"
+ debug "Executing: ${cmd}"
+ for group_dn in $( eval ${cmd} ) ; do
+ remove_uniq_member "${group_dn}"
+ done
+ IFS="${oifs}"
+
+}
+
+#------------------------------------------------------------------------------
+remove_member() {
+
+ local group_dn="$1"
+
+ info "Removing '${CYAN}${USER}${NORMAL}' from group '${CYAN}${group_dn}${NORMAL}' ..."
+
+ local cmd=
+
+ cat > "${LDIF_FILE}" <<-EOF
+ dn: ${group_dn}
+ changetype: modify
+ delete: member
+ member: ${USER_DN}
+ -
+
+ EOF
+
+ if [[ "${VERBOSE}" == "y" ]] ; then
+ debug "Resulting LDIF:"
+ cat "${LDIF_FILE}"
+ fi
+
+ cmd="ldapmodify -H \"${LDAP_URL}\" -x -D \"${BIND_DN}\" -y \"${BIND_PW_FILE}\""
+ cmd+=" -f \"$( readlink -f "${LDIF_FILE}" )\""
+ debug "Executing: ${cmd}"
+ if [[ "${SIMULATE}" != "y" ]] ; then
+ eval $cmd
+ fi
+ debug "Done."
+
+}
+
+#------------------------------------------------------------------------------
+remove_all_member() {
+
+ empty_line
+ info "Removing all entries of kind '${CYAN}member=${USER_DN}${NORMAL}' ..."
+
+ local group_dn=
+ local cmd=
+
+ local oifs="${IFS}"
+ IFS="
+"
+
+ cmd="ldapsearch -x -LLL -o ldif-wrap=no -H '${LDAP_URL}' -s sub "
+ cmd+="-b \"${SUFFIX}\" -x -D \"${BIND_DN}\" -y \"${BIND_PW_FILE}\" "
+ cmd+="\"(member=${USER_DN})\" dn | "
+ cmd+="grep -i '^dn:' | sed -e 's/^dn: //i'"
+ debug "Executing: ${cmd}"
+ for group_dn in $( eval ${cmd} ) ; do
+ remove_member "${group_dn}"
+ done
+ IFS="${oifs}"
+
+}
+
+#------------------------------------------------------------------------------
+remove_member_uid() {
+
+ local group_dn="$1"
+
+ info "Removing '${CYAN}${USER}${NORMAL}' from group '${CYAN}${group_dn}${NORMAL}' ..."
+
+ local cmd=
+
+ cat > "${LDIF_FILE}" <<-EOF
+ dn: ${group_dn}
+ changetype: modify
+ delete: memberUid
+ memberUid: ${USER}
+ -
+
+ EOF
+
+ if [[ "${VERBOSE}" == "y" ]] ; then
+ debug "Resulting LDIF:"
+ cat "${LDIF_FILE}"
+ fi
+
+ cmd="ldapmodify -H \"${LDAP_URL}\" -x -D \"${BIND_DN}\" -y \"${BIND_PW_FILE}\""
+ cmd+=" -f \"$( readlink -f "${LDIF_FILE}" )\""
+ debug "Executing: ${cmd}"
+ if [[ "${SIMULATE}" != "y" ]] ; then
+ eval $cmd
+ fi
+ debug "Done."
+
+}
+
+#------------------------------------------------------------------------------
+remove_all_member_uid() {
+
+ empty_line
+ info "Removing all entries of kind '${CYAN}memberUid=${USER}${NORMAL}' ..."
+
+ local group_dn=
+ local cmd=
+
+ local oifs="${IFS}"
+ IFS="
+"
+
+ cmd="ldapsearch -x -LLL -o ldif-wrap=no -H '${LDAP_URL}' -s sub "
+ cmd+="-b \"${SUFFIX}\" -x -D \"${BIND_DN}\" -y \"${BIND_PW_FILE}\" "
+ cmd+="\"(memberUid=${USER})\" dn | "
+ cmd+="grep -i '^dn:' | sed -e 's/^dn: //i'"
+ debug "Executing: ${cmd}"
+ for group_dn in $( eval ${cmd} ) ; do
+ remove_member_uid "${group_dn}"
+ done
+ IFS="${oifs}"
+
+}
+
+#------------------------------------------------------------------------------
+remove_sudo_user() {
+
+ local group_dn="$1"
+
+ info "Removing '${CYAN}${USER}${NORMAL}' from group '${CYAN}${group_dn}${NORMAL}' ..."
+
+ local cmd=
+
+ cat > "${LDIF_FILE}" <<-EOF
+ dn: ${group_dn}
+ changetype: modify
+ delete: sudoUser
+ sudoUser: ${USER}
+ -
+
+ EOF
+
+ if [[ "${VERBOSE}" == "y" ]] ; then
+ debug "Resulting LDIF:"
+ cat "${LDIF_FILE}"
+ fi
+
+ cmd="ldapmodify -H \"${LDAP_URL}\" -x -D \"${BIND_DN}\" -y \"${BIND_PW_FILE}\""
+ cmd+=" -f \"$( readlink -f "${LDIF_FILE}" )\""
+ debug "Executing: ${cmd}"
+ if [[ "${SIMULATE}" != "y" ]] ; then
+ eval $cmd
+ fi
+ debug "Done."
+
+}
+
+#------------------------------------------------------------------------------
+remove_all_sudo_users() {
+
+ empty_line
+ info "Removing all entries of kind '${CYAN}sudoUser=${USER}${NORMAL}' ..."
+
+ local group_dn=
+ local cmd=
+
+ local oifs="${IFS}"
+ IFS="
+"
+
+ cmd="ldapsearch -x -LLL -o ldif-wrap=no -H '${LDAP_URL}' -s sub "
+ cmd+="-b \"${SUFFIX}\" -x -D \"${BIND_DN}\" -y \"${BIND_PW_FILE}\" "
+ cmd+="\"(sudoUser=${USER})\" dn | "
+ cmd+="grep -i '^dn:' | sed -e 's/^dn: //i'"
+ debug "Executing: ${cmd}"
+ for group_dn in $( eval ${cmd} ) ; do
+ remove_sudo_user "${group_dn}"
+ done
+ IFS="${oifs}"
+
+}
+
+#------------------------------------------------------------------------------
+modify_login_shell() {
+
+ info "Setting Login Shell of '${CYAN}${USER_NAME}${NORMAL}' to '${CYAN}${NEW_LOGIN_SHELL}${NORMAL}' ..."
+
+ cat > "${LDIF_FILE}" <<-EOF
+ dn: ${USER_DN}
+ changetype: modify
+ replace: loginShell
+ loginShell: ${NEW_LOGIN_SHELL}
+ -
+
+ EOF
+
+ if [[ "${VERBOSE}" == "y" ]] ; then
+ debug "Resulting LDIF:"
+ cat "${LDIF_FILE}"
+ fi
+
+ cmd="ldapmodify -H \"${LDAP_URL}\" -x -D \"${BIND_DN}\" -y \"${BIND_PW_FILE}\""
+ cmd+=" -f \"$( readlink -f "${LDIF_FILE}" )\""
+ debug "Executing: ${cmd}"
+ if [[ "${SIMULATE}" != "y" ]] ; then
+ eval $cmd
+ fi
+ debug "Done."
+
+}
+
+#------------------------------------------------------------------------------
+perform_instance() {
+
+ empty_line
+ draw_line
+ info "Disabling user '${GREEN}${USER}${NORMAL}' in LDAP instance '${GREEN}${INSTANCE}${NORMAL}'."
+ empty_line
+ sleep 2
+
+ if get_user_dn ; then
+ :
+ else
+ return 0
+ fi
+
+ debug "Continue ..."
+ setting_user_status
+ disabling_password
+ modify_login_shell
+ remove_all_uniq_member
+ remove_all_member
+ remove_all_member_uid
+ remove_all_sudo_users
+
+}
+
+#------------------------------------------------
+main() {
+
+ get_options "$@"
+
+ debug "Creating temporary LDIF file ..."
+ LDIF_FILE=$( mktemp disable-user.XXXXXXXX.ldif )
+ debug "Temporary file is '${CYAN}${LDIF_FILE}${NORMAL}'."
+
+ trap cleanup_tmp_file INT TERM EXIT ABRT
+
+ for USER in "${USERS[@]}" ; do
+ for INSTANCE in "${USED_INSTANCES[@]}" ; do
+ LDAP_URL="${LDAP_URLS[${INSTANCE}]}"
+ BIND_DN="${BIND_DNS[${INSTANCE}]}"
+ BIND_PW_FILE="${BIND_PW_FILES[${INSTANCE}]}"
+ SUFFIX="${SUFFIXES[${INSTANCE}]}"
+ perform_instance
+ done
+ done
+
+ empty_line
+ info "Finished."
+
+}
+
+main "$@"
+
+# vim: et list