--- /dev/null
+#!/bin/bash
+
+set -e
+set -u
+
+BASE_NAME="$( basename ${0} )"
+MY_REAL_NAME=$( readlink -f $0 )
+BIN_DIR=$( dirname "${MY_REAL_NAME}" )
+BASE_DIR=$( dirname "${BIN_DIR}" )
+LIB_DIR="${BASE_DIR}/lib"
+CONF_DIR="${BASE_DIR}/etc"
+
+TMP_LDIF_FILE=
+
+if [[ -f "${BIN_DIR}/functions.rc" ]] ; then
+ . "${BIN_DIR}/functions.rc"
+else
+ echo "Bash resource file '${BIN_DIR}/functions.rc' not found" >&2
+ exit 5
+fi
+
+declare -a DNS=()
+declare -a PEOPLE_OUS=()
+declare -a GROUPS_OUS=()
+
+detect_color
+
+DESCRIPTION=$( cat <<-EOF
+ Fix objectClasses of all necessary entries to enable the memberOf-Plugin
+ on all necessary LDAP-entries.
+
+ EOF
+)
+
+#------------------------------------------------------------------------------
+usage() {
+ cat <<-EOF
+ Usage: ${BASE_NAME} [Common Options] [LDAP Options]
+ ${BASE_NAME} [-h|--help]
+ ${BASE_NAME} [-V|--version]
+
+ LDAP Options:
+ EOF
+
+ echo "${LDAP_USAGE_MSG}"
+ empty_line
+ echo " Common Options:"
+ echo "${STD_USAGE_MSG}"
+
+}
+
+#------------------------------------------------------------------------------
+get_options() {
+
+ local tmp=
+ local base_dir=
+
+ set +e
+ tmp=$( getopt -o ${LDAP_STD_OPTS_SHORT}${STD_SHORT_OPTIONS} \
+ --long ${LDAP_STD_OPTS_LONG},${STD_LONG_OPTIONS} \
+ -n "${BASE_NAME}" -- "$@" )
+ if [[ $? != 0 ]] ; then
+ empty_line
+ usage >&2
+ exit 1
+ fi
+ set -e
+
+ # Note the quotes around `$TEMP': they are essential!
+ eval set -- "${tmp}"
+ eval_common_options "$@"
+ if [[ "${DEBUG}" == 'y' ]] ; then
+ declare -p REMAINING_OPTS
+ declare -p REMAINING_ARGS
+ fi
+
+# local -a rest_args_common=()
+# for tmp in "${REMAINING_ARGS[@]}" ; do
+# rest_args_common+=(${tmp})
+# done
+
+ eval_ldap_options "${REMAINING_OPTS[@]}" "${REMAINING_ARGS[@]}"
+
+ if [[ "${DEBUG}" == 'y' ]] ; then
+ declare -p REMAINING_OPTS
+ declare -p REMAINING_ARGS
+ fi
+
+ if [[ "${#REMAINING_OPTS[@]}" -gt 0 ]] ; then
+ error "Unknown options: ${REMAINING_OPTS[*]}"
+ empty_line
+ usage >&2
+ exit 2
+ fi
+
+ if [[ "${#REMAINING_ARGS[@]}" != "0" ]] ; then
+ error "Unknown arguments: ${REMAINING_ARGS[*]}."
+ empty_line
+ usage >&2
+ exit 2
+ fi
+
+}
+
+#------------------------------------------------------------------------------
+cleanup_tmp_file() {
+
+ if [[ -n "${TMP_LDIF_FILE}" ]] ; then
+ if [[ -f "${TMP_LDIF_FILE}" ]] ; then
+ echo "Removing temporary file '${TMP_LDIF_FILE}'."
+ RM_force "${TMP_LDIF_FILE}"
+ fi
+ fi
+
+}
+
+#------------------------------------------------------------------------------
+eval_people_ous() {
+
+ local dn=
+ local line=
+
+ local cmd="ldapsearch -LLL -o ldif-wrap=no "
+ cmd+="-H \"${LDAP_URL}\" -b \"${LDAP_BASE}\""
+ cmd+=" -x -D \"${LDAP_USR}\" -y \"${LDAP_PWD_FILE}\" "
+ cmd+="'(&(objectClass=organizationalUnit)(ou=*People))' dn | grep '^dn:'"
+
+ empty_line
+ info "Evaluating of all OUs for people ..." >&2
+ debug "Executing: ${cmd}"
+ empty_line
+
+ local oifs="${IFS}"
+ IFS="
+"
+
+ for line in $( eval ${cmd} ) ; do
+ if echo "${line}" | grep -q '^dn: ' ; then
+ dn=$( echo "${line}" | sed -e 's/^dn: *//' )
+ elif echo "${line}" | grep -q '^dn:: ' ; then
+ dn=$( echo "${line}" | sed -e 's/^dn:: *//' | base64 -d )
+ fi
+ PEOPLE_OUS+=("${dn}")
+ done
+
+ IFS="${oifs}"
+
+ if [[ "${VERBOSE}" == "y" ]] ; then
+ echo -e "${CYAN}Evaluated OUs for people:${NORMAL}" >&2
+ for dn in "${PEOPLE_OUS[@]}" ; do
+ echo -e " ${CYAN}*${NORMAL} ${dn}"
+ done
+ empty_line
+ fi
+
+}
+
+#------------------------------------------------------------------------------
+eval_groups_ous() {
+
+ local dn=
+ local line=
+
+ local cmd="ldapsearch -LLL -o ldif-wrap=no "
+ cmd+="-H \"${LDAP_URL}\" -b \"${LDAP_BASE}\""
+ cmd+=" -x -D \"${LDAP_USR}\" -y \"${LDAP_PWD_FILE}\" "
+ cmd+="'(&(objectClass=organizationalUnit)(ou=*Groups))' dn | grep '^dn:'"
+
+ empty_line
+ info "Evaluating of all OUs for groups ..." >&2
+ debug "Executing: ${cmd}"
+ empty_line
+
+ local oifs="${IFS}"
+ IFS="
+"
+
+ for line in $( eval ${cmd} ) ; do
+ if echo "${line}" | grep -q '^dn: ' ; then
+ dn=$( echo "${line}" | sed -e 's/^dn: *//' )
+ elif echo "${line}" | grep -q '^dn:: ' ; then
+ dn=$( echo "${line}" | sed -e 's/^dn:: *//' | base64 -d )
+ fi
+ GROUPS_OUS+=("${dn}")
+ done
+
+ IFS="${oifs}"
+
+ if [[ "${VERBOSE}" == "y" ]] ; then
+ echo -e "${CYAN}Evaluated OUs for groups:${NORMAL}" >&2
+ for dn in "${GROUPS_OUS[@]}" ; do
+ echo -e " ${CYAN}*${NORMAL} ${dn}"
+ done
+ empty_line
+ fi
+
+}
+
+#------------------------------------------------------------------------------
+fix_users() {
+
+ local people_dn=
+ local -a users_dns=()
+ local line=
+ local dn=
+ local cmd=
+
+ local oifs="${IFS}"
+ IFS="
+"
+
+ empty_line
+ info "Fixing objectClasses of users ..."
+ empty_line
+
+ for people_dn in "${PEOPLE_OUS[@]}" ; do
+
+ debug "Evaluating OU '${CYAN}${people_dn}${NORMAL}'."
+
+ cmd="ldapsearch -LLL -o ldif-wrap=no -H \"${LDAP_URL}\" -b \"${people_dn}\""
+ cmd+=" -x -D \"${LDAP_USR}\" -y \"${LDAP_PWD_FILE}\" "
+ cmd+="'(&(uid=*)(!(|(objectClass=extensibleObject)(objectClass=inetAdmin)(objectClass=inetUser)"
+ cmd+="(objectClass=nsManagedPerson)(objectClass=nsMemberOf))))' dn | grep '^dn:'"
+
+ # debug "Executing: ${cmd}"
+ for line in $( eval ${cmd} ) ; do
+ if echo "${line}" | grep -q '^dn: ' ; then
+ dn=$( echo "${line}" | sed -e 's/^dn: *//' )
+ elif echo "${line}" | grep -q '^dn:: ' ; then
+ dn=$( echo "${line}" | sed -e 's/^dn:: *//' | base64 -d )
+ fi
+ users_dns+=("${dn}")
+ done
+
+ done
+
+ info "Found ${CYAN}${#users_dns[*]} users${NORMAL} to fix."
+
+ IFS="${oifs}"
+
+ local i=0
+ for dn in "${users_dns[@]}" ; do
+ info "Fixing user '${CYAN}${dn}${NORMAL}' ..."
+ echo "dn: ${dn}" >"${TMP_LDIF_FILE}"
+ echo "changetype: modify" >>"${TMP_LDIF_FILE}"
+ echo "add: objectClass" >>"${TMP_LDIF_FILE}"
+ echo "objectClass: nsManagedPerson" >>"${TMP_LDIF_FILE}"
+ echo "-" >>"${TMP_LDIF_FILE}"
+ echo "" >>"${TMP_LDIF_FILE}"
+ if [[ "$i" -lt "2" && "${VERBOSE}" == "y" ]] ; then
+ cat "${TMP_LDIF_FILE}"
+ fi
+ cmd="ldapmodify -H \"${LDAP_URL}\" -D \"${LDAP_USR}\" -y \"${LDAP_PWD_FILE}\" "
+ cmd+="-f \"${TMP_LDIF_FILE}\""
+ debug "Executing: ${cmd}"
+ if [[ "${SIMULATE}" != "y" ]] ; then
+ eval ${cmd}
+ fi
+ i=$(( i + 1 ))
+ sleep 0.1
+ done
+
+}
+
+#------------------------------------------------------------------------------
+fix_groups() {
+
+ local group_dn=
+ local -a group_dns=()
+ local line=
+ local dn=
+ local cmd=
+
+ local oifs="${IFS}"
+ IFS="
+"
+
+ empty_line
+ info "Fixing objectClasses of groups ..."
+ empty_line
+
+ for group_dn in "${GROUPS_OUS[@]}" ; do
+
+ debug "Evaluating OU '${CYAN}${group_dn}${NORMAL}'."
+
+ cmd="ldapsearch -LLL -o ldif-wrap=no -H \"${LDAP_URL}\" -b \"${group_dn}\""
+ cmd+=" -x -D \"${LDAP_USR}\" -y \"${LDAP_PWD_FILE}\" "
+ cmd+="'(&(|(objectClass=groupOfNames)(objectClass=groupOfUniqueNames))"
+ cmd+="(!(|(objectClass=extensibleObject)(objectClass=inetAdmin)(objectClass=inetUser)"
+ cmd+="(objectClass=nsManagedPerson)(objectClass=nsMemberOf))))' dn | grep '^dn:'"
+
+ # debug "Executing: ${cmd}"
+ for line in $( eval ${cmd} ) ; do
+ if echo "${line}" | grep -q '^dn: ' ; then
+ dn=$( echo "${line}" | sed -e 's/^dn: *//' )
+ elif echo "${line}" | grep -q '^dn:: ' ; then
+ dn=$( echo "${line}" | sed -e 's/^dn:: *//' | base64 -d )
+ fi
+ group_dns+=("${dn}")
+ done
+
+ done
+
+ info "Found ${CYAN}${#group_dns[*]} groups${NORMAL} to fix."
+
+ IFS="${oifs}"
+
+ local i=0
+ for dn in "${group_dns[@]}" ; do
+ info "Fixing group '${CYAN}${dn}${NORMAL}' ..."
+ echo "dn: ${dn}" >"${TMP_LDIF_FILE}"
+ echo "changetype: modify" >>"${TMP_LDIF_FILE}"
+ echo "add: objectClass" >>"${TMP_LDIF_FILE}"
+ echo "objectClass: nsMemberOf" >>"${TMP_LDIF_FILE}"
+ echo "-" >>"${TMP_LDIF_FILE}"
+ echo "" >>"${TMP_LDIF_FILE}"
+ if [[ "$i" -lt "2" && "${VERBOSE}" == "y" ]] ; then
+ cat "${TMP_LDIF_FILE}"
+ fi
+ cmd="ldapmodify -H \"${LDAP_URL}\" -D \"${LDAP_USR}\" -y \"${LDAP_PWD_FILE}\" "
+ cmd+="-f \"${TMP_LDIF_FILE}\""
+ debug "Executing: ${cmd}"
+ if [[ "${SIMULATE}" != "y" ]] ; then
+ eval ${cmd}
+ fi
+ i=$(( i + 1 ))
+ sleep 0.1
+ done
+
+}
+
+#------------------------------------------------------------------------------
+main() {
+
+ get_options "$@"
+
+ eval_people_ous
+ eval_groups_ous
+
+ TMP_LDIF_FILE=$( mktemp -t "tmp-fix-memberof.XXXXXXXXXXXX.ldif" )
+ trap cleanup_tmp_file INT TERM EXIT ABRT
+
+ fix_users
+ fix_groups
+
+ empty_line
+ info "${CYAN}Finished${NORMAL}."
+
+}
+
+main "$@"
+
+exit 0
+
+# vim: et list