RHEL 7에서 LDAP 사용자를 삭제한 후 정리하는 방법은 무엇입니까?

RHEL 7에서 LDAP 사용자를 삭제한 후 정리하는 방법은 무엇입니까?

우리는 LDAP용 389 Directory Server를 사용하는 소규모 네트워크를 보유하고 있습니다. 우리는 LDAP 사용자를 생성하고, 이러한 사용자는 네트워크의 다양한 컴퓨터에 로그인한 다음 때로는 이러한 사용자를 삭제합니다. 그러나 LDAP 사용자를 삭제한 후에도 사용자가 액세스하는 모든 시스템에 아티팩트가 남아 있습니다. 남은 모든 것을 알지도 못하지만 홈 디렉토리, sssd 캐시 항목 및 AccountsService 캐시 항목은 식별했습니다. 파일 시스템의 남은 부분 외에도 삭제된 사용자가 gdm 로그인 화면에 표시되고 삭제된 사용자와 동일한 uid 또는 사용자 이름으로 새 LDAP 사용자가 생성되면 문제가 발생합니다(오류 표시). 이름을 지정하거나 생성할 수 없음) 홈 디렉터리를 입력하고 gdm은 로그인 화면으로 돌아갑니다. LDAP 사용자를 삭제한 후 각 로컬 시스템을 정리하는 방법은 무엇입니까?

이것이 내가 지금까지 가지고 있는 것입니다: 모든 프로세스를 종료하고 해당 홈 디렉토리를 삭제합니다 sss_cache -E,,, systemctl restart sssd. systemctl restart accounts-daemon내가 놓친 것이 있거나 더 좋은 방법이 있습니까?

완전한 정리 프로세스나 스크립트가 있더라도 모든 시스템에서 수동으로 실행합니까? LDAP 삭제를 자동으로 정리하는 좋은 방법이 있습니까? 삭제 후 콜백을 사용하여 389 Directory Server 사후 작업 플러그인을 만들려고 했지만 389 Directory Server에서 플러그인을 로드할 수 없습니다. ldapmodify를 사용하여 플러그인을 추가하려고 하면 실패합니다 ldap_add: Server is unwilling to perform (53) additional info: Invalid plugin path myplugin.so - failed to open library. 이 오류를 처음 봤을 때 SELinux가 실행을 차단하고 있음을 보여주는 systemd 로그 항목을 찾았지만 권장 조치를 취한 후에는 systemd 또는 dirsrv 로그에 유용한 내용이 표시되지 않으므로 실패 이유를 알 수 없습니다. .

답변1

내 솔루션은 사용자가 삭제될 때 스크립트를 수동으로 실행하고, 삭제 시 호스트 연결이 끊길 경우를 대비해 cron 작업이 각 호스트에서 정기적으로 스크립트를 실행하도록 하는 것이었습니다. 내 스크립트:

#!/bin/bash

purge() { # usage: purge <USER_NAME> <USER_ID>
    local USER_NAME=$1
    local USER_ID=$2
    if loginctl | awk '{print $2}' | grep -q $USER_ID
    then
        loginctl kill-user $USER_ID
    fi
    /usr/sbin/sss_cache -u $USER_NAME
    rm -rf /home/$USER_NAME
    rm -f /var/lib/AccountsService/users/$USER_NAME
    USERS_PURGED=true
    {
        sleep 10
        if loginctl | awk '{print $2}' | grep -q $USER_ID
        then
            loginctl terminate-user $USER_ID
        fi
        pkill -u $USER_ID
        echo "Purged user $USER_NAME" | systemd-cat -t ldap-cleanup
    } &
}

# Require root
if [ "$UID" != 0 ]
then
    >&2 echo "Please run this script as root."
    exit 1
fi

# Get LDAP users
LDAP_RESULT=$(ldapsearch -x -LLL uid=* uid uidNumber)
if [[ $? != 0 ]]
then
    >&2 echo "LDAP query failed"
    exit 1
fi

declare -A LDAP_USERS
LDAP_USER_NAMES=($(echo "$LDAP_RESULT" | sed -n 's/uid: //p'))
LDAP_UIDS=($(echo "$LDAP_RESULT" | sed -n 's/uidNumber: //p'))
if [[ ${#LDAP_USER_NAMES[@]} != ${#LDAP_UIDS[@]} ]]
then
    # This shouldn't happen
    >&2 echo "LDAP user name and UID arrays are different lengths!"
    exit 1
fi

for i in ${!LDAP_USER_NAMES[@]}
do
    LDAP_USERS["${LDAP_USER_NAMES[$i]}"]="${LDAP_UIDS[$i]}"
done

# Check local users against LDAP users
HOME_DIRS=$(ls -n /home | tail -n +2 )
LOCAL_USER_NAMES=($(echo "$HOME_DIRS" | awk '{print $9}'))
LOCAL_UIDS=($(echo "$HOME_DIRS" | awk '{print $3}'))
for i in ${!LOCAL_USER_NAMES[@]}
do
    USER_NAME=${LOCAL_USER_NAMES[$i]}
    USER_ID=${LOCAL_UIDS[$i]}
    if [[ ! ${LDAP_USERS[$USER_NAME]+x} ]]
    then
        if ! grep -q "^${USER_NAME}:" /etc/passwd
        then
            # Defunct LDAP user (user not in /etc/passwd nor LDAP)
            purge $USER_NAME $USER_ID
        fi
    elif [[ $USER_ID != ${LDAP_USERS[$USER_NAME]} ]]
    then
        if ! grep -q "^${USER_NAME}:" /etc/passwd
        then
            # Recreated LDAP user (different UID)
            purge $USER_NAME $USER_ID
        else
            >&2 echo "User ${USER_NAME} has a different UID in LDAP: local UID: $USER_ID, LDAP: ${LDAP_USERS[$USER_NAME]}"
        fi
    fi
done

if [ "$USERS_PURGED" = true ]
then
    # This should clean up the gdm user selection screen
    systemctl restart sssd
    systemctl restart accounts-daemon
fi

나는 그것이 훌륭하다고 말하는 것이 아니지만 그것은 내 필요에 충분합니다. 모든 사용자의 홈 디렉토리가 /home에 있다고 가정합니다.

관련 정보