我确实针对 LDAP 设置了 PAM 身份验证。一切正常,但当我同时拥有同名但不同 UID 的本地用户和 ldap 用户时,我遇到了问题。
我正在 RH6 上工作,目前我的system-auth
配置password-auth
如下:
session required pam_mkhomedir.so skel=/etc/skel umask=0002
我的ssosers
用户存在于ldap
:
[root@localhost pam.d]# getent -s ldap passwd ssosers
ssosers:x:20100:1000:ssosers:/home/ssosers:/usr/bin/sh
以及/etc/passwd
:
[root@localhost pam.d]# cat /etc/passwd | grep ssosers
ssosers:x:50025:50025::/home/ssosers:/bin/bash
我ssosers
可以使用本地密码和 LDAP 密码登录。请考虑他们有不同的 UID。问题是,当我删除本地用户以强制对 ldap 进行身份验证时,下次ssosers
登录时会pam_mkhomedir.so
失败,因为该用户/home/ssosers
已经存在,并且由于缺乏权限,用户无法加入他的家:
Last login: Mon Feb 19 17:01:00 2018 from 10.212.148.18
Could not chdir to home directory /home/ssosers: Permission denied
-sh: /home/ssosers/.profile: Permission denied
-sh-4.1$
$PAM_USER
如果 pam_mkhomedir 失败,有没有办法更改主目录的权限?我希望他加入他的老家。
更新
我想出了一个简单的解决方案。基本上运行此脚本是为了通过 LDAP 查找用户,如果找到它,我会删除该用户并更新主文件夹的 UID,如果没有找到它,我会删除用户和主目录。
#!/bin/bash
getent -s ldap passwd $1 > /dev/null
if [ $? -eq 0 ]; then
userdel $1
chown -R $1 /home/$1
else
userdel -r $1
fi
但是,在积极的情况下,如何添加基于 OLD UID 的查找(查找具有 OLD uid 的其他文件)?当我执行userdel $1
本地 UID(旧的)时,已不再解决。这是ssosers
删除后 的用户主目录的权限:
drwx------ 3 50025 oinstall 1024 Feb 19 18:30 ssosers
这就是为什么我必须用 chown 更新家庭的许可,因为首先指向passwd
然后指向nsswitch
files
ldap
答案1
在删除用户之前,您应该将用户的旧 UID 存储在变量中。
例如,这是脚本的改进版本:
- 可以在命令行上使用多个用户名参数
- 正确引用所有变量
- 有两种不同的确定所有权的方法 - 仅选择 1。
- 有一些非常原始的错误检查。需要更多。尝试考虑所有可能出错的事情,然后想出一种方法来测试它们,并
error()
在必要时使用该函数来中止。如果您有一位了解您环境的同事,您可以向他展示您的代码并询问“我缺少什么?”、“还有什么可能出错吗?”这将非常有用。
在我认为它可以安全地在我的系统上使用之前,它仍然需要工作,但作为一个例子已经足够了。
#!/bin/bash
error() {
local ec="$1" ; shift # first arg is the exit code
# if there are any more args, they are the error message. print to stderr
[ -n "$*" ] && echo "$@" >&2
# exit with $ec if $ec is non-zero
[ "$ec" -ne 0 ] && exit "$ec"
}
for user in "$@" ; do
OLDUID=$(getent -s files passwd "$user" | cut -d : -f 3)
[ -z "$OLDUID" ] && error 1 "user '$user' is not local"
NEWUID=$(getent -s ldap passwd "$user" | cut -d : -f 3)
if [ -z "$NEWUID" ] ; then
# user exists locally but there is no corresponding LDAP user
# so delete the user and their home dir. This **definitely** needs
# more sanity checking to make sure you're not deleting root or some
# other important account. Maybe check that [ "$OLDUID" -ge 1000 ]
# (or 500 or whatever the lowest normal-user uid is on your system)
userdel -r "$user"
elif [ "$OLDUID" -ne "$NEWUID" ]; then
# both local and LDAP user exist. UIDs are different, so delete the local
# user and change ownership of their files to the the LDAP uid.
# Method 1:
#homedir=$(getent -s files passwd "$user" | cut -d : -f 6)
#userdel "$user"
#chown -R "$user" "$homedir"
#find /tmp /var/tmp -uid "$OLDUID" -exec chown "$NEWUID" {} +
# Method 2:
#userdel "$user"
#find / -uid "$OLDUID" -exec chown "$NEWUID" {} +
else
# both exist, delete local user. UIDs are equal, no need to chown anything.
userdel "$user"
fi
done
顺便说一句,由于此脚本处理多个用户名参数,您可能想要使用error 0 ...
而不是error 1 ...
仅将问题记录到 stderr 而不中止,但如果 OLDUID 或 NEWUID 为空,则需要跳到下一个用户名。
例如
OLDUID=$(getent -s files passwd "$user" | cut -d : -f3)
[ -z "$OLDUID" ] && error 0 "user '$user' is not local" && continue