]> Frank Brehm's Git Trees - pixelpark/pp-admin-tools.git/commitdiff
Adding scripts/fix-memberof
authorFrank Brehm <frank@brehm-online.com>
Thu, 3 Nov 2022 13:52:15 +0000 (14:52 +0100)
committerFrank Brehm <frank@brehm-online.com>
Thu, 3 Nov 2022 13:52:15 +0000 (14:52 +0100)
scripts/fix-memberof [new file with mode: 0755]

diff --git a/scripts/fix-memberof b/scripts/fix-memberof
new file mode 100755 (executable)
index 0000000..10854da
--- /dev/null
@@ -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