我们在混合 RH5/RH6 环境中有一些服务器需要对两个 LDAP 服务之一进行身份验证。这在 SSSD 中实现并且运行良好。来自任一域的用户都可以成功登录,并且当用户名重叠时,正确的域优先。
问题在于我们有一个通过 pam_exec 运行的脚本,它只需要为两个域中的一个运行。
在更高版本的 PAM 中(例如 RH6 提供的版本),我可以利用[domains=X]
如下语法:
account [default=bad success=done user_unknown=ignore] pam_sss.so domains=domain_without_login_script
account [default=bad success=ok user_unknown=ignore] pam_sss.so domains=domain_with_login_script
(我不知道这是否会起作用,因为我没有测试过,因为在 RH5 系统上我无法使用该功能。对于第一个域,堆栈中的任何后续模块都会被忽略;不确定如果需要的话如何解决这个问题。)
无论如何,RH5 没有 pam_sss 这样的标志,而且,我看不到 PAM 或登录环境中包含此信息的任何内容。例如,如果我可以有类似以下内容的内容,那就太好了:
#!/usr/bin/perl -w
# do not process users from X domain
exit(0) if $ENV{'SSSD_Domain'} eq "domain_without_login_script";
到目前为止,我想到的唯一解决方案都是笨拙的。即使用户名重叠,每个域的 UID 也会不同,因此,既然选择了正确的帐户,我可以检查 UID:
#!/usr/bin/perl -w
# get authenticating user from environment
use Env qw(PAM_USER);
# do not process users from X domain
my $uid = getpwnam($PAM_USER);
my $domainXuid = getpwnam("$PAM_USER\@domain_without_login_script");
exit(0) if ($uid == $domainXuid); # i.e. authenticated domain is X domain
我觉得这似乎有点俗气。有人知道更好的方法吗?
答案1
这是一个非常好的问题。
一种方法是使用完全限定名称 (username@domain),该名称不会遍历所有域,但始终会命中一个特定域。这样,您可以通过调用以下内容在应用程序中编写逻辑:
for d in domain_list:
if getpwnam(username + "@" + d):
do_stuff()
另一个包括 sssd 将 sssd 域放入环境中。这已通过上游票据进行跟踪https://fedorahosted.org/sssd/ticket/2476但该方案尚未实施。