In einer älteren Version unseres Codes haben wir von Perl aus eine LDAP-Suche wie folgt durchgeführt:
# 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
}
Der obige Code würde zu einer erfolgreichen LDAP-Suche führen, und die Ausgabe dieser Suche würde in der Datei $lworkfile
.
Leider haben wir openldap auf diesem Server kürzlich neu konfiguriert, so dass in /etc/openldap/ldap.conf und /etc/ldap.conf ein "BASE DC=" angegeben ist. Diese Änderung scheint zu bedeuten, dass ldapsearch die Umgebungsvariable LDAP_BASEDN ignoriert, so dass meine ldapsearch fehlschlägt.
Ich habe verschiedene Lösungen ausprobiert, aber bisher ohne Erfolg:
(1) Ich habe versucht, wieder das Argument "-b" für ldapsearch zu verwenden, aber die Shell-Metazeichen zu escapen. Ich habe angefangen, den Escaping-Code zu schreiben:
my $ldn_escaped = $ldn;
$ldn_escaped =~ s/\/\\/g;
$ldn_escaped =~ s/`/\`/g;
$ldn_escaped =~ s/$/\$/g;
$ldn_escaped =~ s/"/\"/g;
Das führte zu einigen Perl-Fehlern, weil ich diese Regexe in Perl nicht richtig escaped habe (die Zeilennummer stimmt mit der Regex mit den Backticks überein).
Backticks found where operator expected at /tmp/mycommand line 404, at end of line
Gleichzeitig begann ich an diesem Ansatz zu zweifeln und suchte nach einer besseren Lösung.
(2) Ich habe dann einige Stackoverflow-Fragen gesehen ( aquí y aquí ), die eine bessere Lösung vorschlug.
Hier ist der Code:
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;
Die beiden Probleme, die ich mit Ansatz (2) habe, sind:
a) Der Aufruf von open oder system mit einem Array von Argumenten erlaubt mir nicht die Übergabe von > $lworkfile 2>&1
an den Befehl angehängt, so dass ich nicht verhindern kann, dass die ldapsearch-Ausgabe an den Bildschirm gesendet wird, was meine Ausgabe hässlich aussehen lässt:
Processing...ldap_bind: Success (0) additional info: Success
b) Ich kann nicht herausfinden, wie ich den Speicherort (d.h. Pfad und Dateiname) für das Dateihandle auswählen kann, das an open
d.h. ich weiß nicht, wo $lldap_output
ist. Kann ich sie verschieben/umbenennen oder untersuchen, um herauszufinden, wo sie sich befindet (oder ist sie gar nicht auf der Festplatte gespeichert)?
Angesichts der Probleme mit (2) denke ich, dass ich zu Ansatz (1) zurückkehren sollte, aber ich bin mir nicht ganz sicher, wie