From e6d7ce8117c1efacc518c5317c35167d0f59253c Mon Sep 17 00:00:00 2001 From: Frank Brehm Date: Thu, 3 Nov 2022 14:52:15 +0100 Subject: [PATCH] Adding scripts/fix-memberof --- scripts/fix-memberof | 355 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 355 insertions(+) create mode 100755 scripts/fix-memberof diff --git a/scripts/fix-memberof b/scripts/fix-memberof new file mode 100755 index 0000000..10854da --- /dev/null +++ b/scripts/fix-memberof @@ -0,0 +1,355 @@ +#!/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 -- 2.39.5