在 RHEL 7 上删除 LDAP 用户后如何进行清理?

在 RHEL 7 上删除 LDAP 用户后如何进行清理?

我们有一个小型网络,使用 389 Directory Server for LDAP。我们创建 LDAP 用户,这些用户登录到网络中的各种计算机,然后有时我们会删除这些用户。但是,删除 LDAP 用户后,工件仍保留在用户访问的每个系统上。我什至不知道留下的所有内容,但我已经确定了以下内容:主目录、sssd 缓存条目和 AccountsService 缓存条目。除了文件系统上的残留之外,这还会导致已删除的用户显示在 gdm 登录屏幕上,并且如果使用与已删除用户相同的 uid 或用户名创建新的 LDAP 用户,则会导致问题(显示错误的名称或无法创建)主目录和 gdm 返回登录屏幕)。删除 LDAP 用户后如何清理每个本地系统?

这就是我到目前为止所拥有的:杀死所有进程,删除它们的主目录sss_cache -E,,,,systemctl restart sssdsystemctl restart accounts-daemon我还缺少什么或者有更好的方法吗?

即使您有完整的清理过程或脚本,您是否会在每个系统上手动运行它?有没有一种好方法可以自动清理 LDAP 删除?我尝试制作带有删除后回调的 389 Directory Server Post-Operation 插件,但无法让 389 Directory Server 加载该插件。当我尝试使用 ldapmodify 添加插件时,失败:ldap_add: Server is unwilling to perform (53) additional info: Invalid plugin path myplugin.so - failed to open library。我第一次看到这个错误时,发现 systemd 日志条目显示 SELinux 正在阻止执行,但在采取建议的操作后,我现在在 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 中。

相关内容