![在 RHEL 7 上删除 LDAP 用户后如何进行清理?](https://linux22.com/image/155652/%E5%9C%A8%20RHEL%207%20%E4%B8%8A%E5%88%A0%E9%99%A4%20LDAP%20%E7%94%A8%E6%88%B7%E5%90%8E%E5%A6%82%E4%BD%95%E8%BF%9B%E8%A1%8C%E6%B8%85%E7%90%86%EF%BC%9F.png)
我们有一个小型网络,使用 389 Directory Server for LDAP。我们创建 LDAP 用户,这些用户登录到网络中的各种计算机,然后有时我们会删除这些用户。但是,删除 LDAP 用户后,工件仍保留在用户访问的每个系统上。我什至不知道留下的所有内容,但我已经确定了以下内容:主目录、sssd 缓存条目和 AccountsService 缓存条目。除了文件系统上的残留之外,这还会导致已删除的用户显示在 gdm 登录屏幕上,并且如果使用与已删除用户相同的 uid 或用户名创建新的 LDAP 用户,则会导致问题(显示错误的名称或无法创建)主目录和 gdm 返回登录屏幕)。删除 LDAP 用户后如何清理每个本地系统?
这就是我到目前为止所拥有的:杀死所有进程,删除它们的主目录sss_cache -E
,,,,systemctl restart sssd
。systemctl 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 中。