在我们旧版本的代码中,我们通过Perl调用执行LDAP搜索,如下所示:
上面的代码将导致成功的LDAP搜索,并且该搜索的输出将在文件$lworkfile中。
不幸的是,我们最近在这台服务器上重新配置了openldap,以便在/etc/openldap/ldap.conf和/etc/ldap.conf中指定了“BASE DC =”。这个变化似乎意味着ldapsearch忽略了LDAP_BASEDN环境变量,因此我的ldapsearch失败了。
我尝试了几种不同的修复方法,但目前还没有成功:
(1) 我尝试回到使用"-b"参数进行ldapsearch,但转义shell元字符。我开始编写转义代码:
我使用方法(2)遇到的两个问题是:
a)使用带有参数数组的open或system无法让我将
# Pass the base DN in via the ldapsearch-specific environment variable
# (rather than as the "-b" paramater) to avoid problems of shell
# interpretation of special characters in the DN.
$ENV{LDAP_BASEDN} = $ldn;
$lcmd = "ldapsearch -x -T -1 -h $gLdapServer" .
<snip>
" > $lworkfile 2>&1";
system($lcmd);
if (($? != 0) || (! -e "$lworkfile"))
{
# Handle the error
}
上面的代码将导致成功的LDAP搜索,并且该搜索的输出将在文件$lworkfile中。
不幸的是,我们最近在这台服务器上重新配置了openldap,以便在/etc/openldap/ldap.conf和/etc/ldap.conf中指定了“BASE DC =”。这个变化似乎意味着ldapsearch忽略了LDAP_BASEDN环境变量,因此我的ldapsearch失败了。
我尝试了几种不同的修复方法,但目前还没有成功:
(1) 我尝试回到使用"-b"参数进行ldapsearch,但转义shell元字符。我开始编写转义代码:
my $ldn_escaped = $ldn;
$ldn_escaped =~ s/\/\\/g;
$ldn_escaped =~ s/`/\`/g;
$ldn_escaped =~ s/$/\$/g;
$ldn_escaped =~ s/"/\"/g;
由于我在Perl中没有正确转义那些正则表达式,所以出现了一些Perl错误(行号与带有反引号的正则表达式匹配)。
Backticks found where operator expected at /tmp/mycommand line 404, at end of line
同时我开始怀疑这种方法,并寻找更好的方法。
(2) 然后我看到了一些 Stackoverflow 的问题 (这里 和 这里),他们提出了更好的解决方案。
以下是代码:
print("Processing...");
# Pass the arguments to ldapsearch by invoking open() with an array.
# This ensures the shell does NOT interpret shell metacharacters.
my(@cmd_args) = ("-x", "-T", "-1", "-h", "$gLdapPool",
"-b", "$ldn",
<snip>
);
$lcmd = "ldapsearch";
open my $lldap_output, "-|", $lcmd, @cmd_args;
while (my $lline = <$lldap_output>)
{
# I can parse the contents of my file fine
}
$lldap_output->close;
我使用方法(2)遇到的两个问题是:
a)使用带有参数数组的open或system无法让我将
> $lworkfile 2>&1
传递给命令,因此我无法停止ldapsearch输出被发送到屏幕上,这使得我的输出看起来很丑:
b) 我无法确定如何选择传递给Processing...ldap_bind: Success (0) additional info: Success
open
的文件句柄的位置(即路径和文件名),也就是我不知道$lldap_output
在哪里。我可以移动/重命名它,还是检查它以找出它在哪里(或者它实际上没有保存到磁盘)?基于问题(2)的问题,这使我想回到方法(1),但我不太确定如何操作。