ENV-Variablen in Perl setzen

ENV-Variablen in Perl setzen

am 22.02.2006 21:17:29 von Marten Lehmann

Hi,

ich möchte am liebsten ein komplettes rc-File laden, bevor ich ein
Perl-Script ausführe. Leider ist

.. my-rc; ./script.pl

nicht möglich, da ich dem Script nichts voranstellen kann. Das Programm,
welches das Script aufruft kann leider nur das Script selbst
entgegennehmen. Das Problem dabei ist, dass das Programm vor dem Script
ein setuid() ausführt und dabei geht die env-Variable LD_LIBRARY_PATH
verloren. Diese Variable brauche ich aber für einen Datenbanktreiber.
Ich habe schon versucht ein

$ENV{'LD_LIBRARY_PATH'} = "....." direkt nach der shebang-Zeile und vor
dem "use DBD;". Leider bringt das nichts, der Datenbankfehler kommt
immer noch. Wie kann ich innerhalb eines Perl-Scripts ENV-Variablen
setzen? LD_LIBRARY_PATH scheint ja von Perl schon vor dem "use DBD;"
ausgewertet zu werden. Die shebang-Zeile kann man ja nicht einfach
verändern.

Ich habe übrigens keinen Zugriff auf /etc/ld.so.conf, es muß also über
diese Variable laufen.

Tschüß
Marten

Re: ENV-Variablen in Perl setzen

am 22.02.2006 21:33:10 von Ch Lamprecht

Marten Lehmann schrieb:
> Hi,
>
> ich möchte am liebsten ein komplettes rc-File laden, bevor ich ein
> Perl-Script ausführe. Leider ist
>
> .. my-rc; ./script.pl
>
> nicht möglich, da ich dem Script nichts voranstellen kann. Das Programm,
> welches das Script aufruft kann leider nur das Script selbst
> entgegennehmen. Das Problem dabei ist, dass das Programm vor dem Script
> ein setuid() ausführt und dabei geht die env-Variable LD_LIBRARY_PATH
> verloren. Diese Variable brauche ich aber für einen Datenbanktreiber.
> Ich habe schon versucht ein
>

Hi,
hast du mal das probiert:
BEGIN{
> $ENV{'LD_LIBRARY_PATH'} = "....."
}


direkt nach der shebang-Zeile und vor
> dem "use DBD;". Leider bringt das nichts, der Datenbankfehler kommt
> immer noch. Wie kann ich innerhalb eines Perl-Scripts ENV-Variablen
> setzen? LD_LIBRARY_PATH scheint ja von Perl schon vor dem "use DBD;"
> ausgewertet zu werden. Die shebang-Zeile kann man ja nicht einfach
> verändern.
>
> Ich habe übrigens keinen Zugriff auf /etc/ld.so.conf, es muß also über
> diese Variable laufen.
>
> Tschüß
> Marten

HTH Christoph
--

perl -e "print scalar reverse q/ed.enilno@ergn.l.hc/"

Re: ENV-Variablen in Perl setzen

am 22.02.2006 22:18:28 von Marten Lehmann

Hallo,

> hast du mal das probiert:
> BEGIN{
>
>> $ENV{'LD_LIBRARY_PATH'} = "....."
>
> }

bisher nicht, jetzt aber schon und es funktioniert trotzdem nicht. Ich
vermute mal, dass Perl diese spezielle Variable gar nicht selber
auswertet sondern das dlopen() überläßt. Gibt es irgendeine Möglichkeit
in der shebang-Zeile vor dem Interpreter Variablen zu setzen?

Tschüß
Marten

Re: ENV-Variablen in Perl setzen

am 22.02.2006 22:58:46 von Guido Ostkamp

Marten Lehmann wrote:
> Das Programm, welches das Script aufruft kann leider nur das Script
> selbst entgegennehmen. Das Problem dabei ist, dass das Programm vor
> dem Script ein setuid() ausführt und dabei geht die env-Variable
> LD_LIBRARY_PATH verloren.

LD_LIBRARY_PATH geht nicht verloren, wenn ein Programm das setuid()
selbst macht, sondern nur, wenn ein Programm mit setuid-Bit und Owner
root im Filesystem steht und gestartet wird.

Du mußt vorher den ursprünglichen Inhalt von LD_LIBRARY_PATH in eine
andere Environmentvariable gerettet haben, ein kleines Programm mit
setuid-Bit starten, was den Inhalt wieder zurückkopiert und per
setuid(0) voll auf root umschaltet, und anschließend Dein Skript
ausführt.

Also etwa:

/tmp/x.c:
--- snip --- snap ---
#include
#include

int
main(void)
{
char *x, buf[1024];

if (x = getenv("ORIG_LD_LIBRARY_PATH")) {
snprintf(buf, sizeof(buf), "LD_LIBRARY_PATH=%s", x);
putenv(buf);
}
setuid(0);
execl("/tmp/xyz.pl", "xyz.pl", 0);
}
--- snip --- snap ---

und

/tmp/xyz.pl:
--- snip --- snap ---
#!/usr/bin/perl

use strict;
use warnings;

print "LD_LIBRARY_PATH=" . $ENV{'LD_LIBRARY_PATH'} . "\n";
--- snip --- snap ---

und dann etwa

$ export LD_LIBRARY_PATH=something
$ export ORIG_LD_LIBRARY_PATH=$LD_LIBRARY_PATH
$ make x
$ su - root
# chown root x
# chmod u+s x
# exit
$ ls -l /tmp/x
-rwsr-xr-x 1 root root 7518 Feb 22 22:44 /tmp/x
$ /tmp/x
LD_LIBRARY_PATH=something

HTH,

Guido

Re: ENV-Variablen in Perl setzen

am 22.02.2006 23:19:52 von Frank Seitz

Marten Lehmann wrote:

> bisher nicht, jetzt aber schon und es funktioniert trotzdem nicht. Ich
> vermute mal, dass Perl diese spezielle Variable gar nicht selber
> auswertet sondern das dlopen() überläßt. Gibt es irgendeine Möglichkeit
> in der shebang-Zeile vor dem Interpreter Variablen zu setzen?

Ja, LD_LIBRARY_PATH im laufenden Programm zu setzen (auch in einem
BEGIN-Block) ist zu spät. Und auf der Shebang-Zeile kannst Du
auch nichts machen. Aber Du müsstest Dein Programm durch
einen Shell-Wrapper ersetzen können, der die Variable
setzt und Dein (umbenanntes) Programm ruft.

Grüße
Frank
--
Dipl.-Inform. Frank Seitz; http://www.fseitz.de/
Tel: 04103/180301; Fax: -02; Industriestr. 31, 22880 Wedel

Re: ENV-Variablen in Perl setzen

am 23.02.2006 15:33:58 von Ingo Menger

Frank Seitz schrieb:

> Marten Lehmann wrote:
>
> > bisher nicht, jetzt aber schon und es funktioniert trotzdem nicht. Ich
> > vermute mal, dass Perl diese spezielle Variable gar nicht selber
> > auswertet sondern das dlopen() überläßt. Gibt es irgendeine Mög=
lichkeit
> > in der shebang-Zeile vor dem Interpreter Variablen zu setzen?
>
> Ja, LD_LIBRARY_PATH im laufenden Programm zu setzen (auch in einem
> BEGIN-Block) ist zu spät. Und auf der Shebang-Zeile kannst Du
> auch nichts machen. Aber Du müsstest Dein Programm durch
> einen Shell-Wrapper ersetzen können, der die Variable
> setzt und Dein (umbenanntes) Programm ruft.

Ginge sowas wie:
BEGIN { unless (defined $ENV{LD_LIBRARY_PATH}) {
$ENV{LD_LIBRARY_PATH} =3D ...;
exec(@ARGV);
}}

Re: ENV-Variablen in Perl setzen

am 23.02.2006 15:55:47 von Christian Lackas

* Ingo Menger [2006-02-23]:

Hallo Ingo,

> exec(@ARGV);

exec $0, @ARGV;

der Programmname steht ja (im Gegensatz zu C) nicht in der
Parameterliste.

Gruß
Christian



--
Ich lege jetzt letzte Hand an den Rasenmäher...
http://www.lackas.net/ Perl Delphi Linux MP3 Searchengines Domainchecker

Re: ENV-Variablen in Perl setzen

am 23.02.2006 16:06:46 von Ingo Menger

Christian Lackas schrieb:

> * Ingo Menger [2006-02-23]:
>
> Hallo Ingo,
>
> > exec(@ARGV);
>
> exec $0, @ARGV;
>
> der Programmname steht ja (im Gegensatz zu C) nicht in der
> Parameterliste.

Upps. Ja richtig.
Aber dann müßte es gehen?

Re: ENV-Variablen in Perl setzen

am 23.02.2006 19:27:02 von Guido Ostkamp

Frank Seitz wrote:
> Aber Du müsstest Dein Programm durch einen Shell-Wrapper ersetzen
> können, der die Variable setzt und Dein (umbenanntes) Programm ruft.

Kann er nicht, denn bei Ablage von simplen Shell-Skripten mit
setuid-bit und Owner root wird dies aus Sicherheitsgründen ignoriert.

Kann man einfach probieren mit

#!/bin/bash
echo "UID = $UID"
echo "EUID = $EUID"

und bspw.

$ ls -l x.sh
-rwsr-xr-x 1 root users 95 Feb 23 19:24 x.sh
$ ./x.sh
UID = 500
EUID = 500

Gruß,

Guido

Re: ENV-Variablen in Perl setzen

am 23.02.2006 19:40:09 von Matthias Peick

Marten Lehmann skribis:

> $ENV{'LD_LIBRARY_PATH'} = "....." direkt nach der shebang-Zeile und vor
> dem "use DBD;". Leider bringt das nichts, der Datenbankfehler kommt
> immer noch. Wie kann ich innerhalb eines Perl-Scripts ENV-Variablen
> setzen? LD_LIBRARY_PATH scheint ja von Perl schon vor dem "use DBD;"

Wie du willst. Leider bringt es erst für Kindprozesse etwas, da
LD_LIBRARY_PATH beim Start des Perl-Interpreters ausgewertet wird. Für den
laufenden Prozess kann der Wert nicht mehr geändert werden.

Vermutlich wird es funktionieren, wenn du mit exec ein weiteres Programm
aufrufst, notfalls sich selber mit einem Schalter.

Re: ENV-Variablen in Perl setzen

am 23.02.2006 20:20:47 von Frank Seitz

Guido Ostkamp wrote:
> Frank Seitz wrote:
>
>>Aber Du müsstest Dein Programm durch einen Shell-Wrapper ersetzen
>>können, der die Variable setzt und Dein (umbenanntes) Programm ruft.
>
> Kann er nicht, denn bei Ablage von simplen Shell-Skripten mit
> setuid-bit und Owner root wird dies aus Sicherheitsgründen ignoriert.

Doch, kann er. Wenn ich es richtig verstanden habe, läuft
das rufenden Programm SUID, nicht das gerufene Skript.

Grüße
Frank
--
Dipl.-Inform. Frank Seitz; http://www.fseitz.de/
Tel: 04103/180301; Fax: -02; Industriestr. 31, 22880 Wedel

Re: ENV-Variablen in Perl setzen

am 23.02.2006 20:23:46 von Frank Seitz

Guido Ostkamp wrote:
> Frank Seitz wrote:
>
>>Aber Du müsstest Dein Programm durch einen Shell-Wrapper ersetzen
>>können, der die Variable setzt und Dein (umbenanntes) Programm ruft.
>
> Kann er nicht, denn bei Ablage von simplen Shell-Skripten mit
> setuid-bit und Owner root wird dies aus Sicherheitsgründen ignoriert.

Doch, kann er. Das rufende Programm läuft SUID,
nicht das gerufene Skript.

Grüße
Frank
--
Dipl.-Inform. Frank Seitz; http://www.fseitz.de/
Tel: 04103/180301; Fax: -02; Industriestr. 31, 22880 Wedel

Re: ENV-Variablen in Perl setzen

am 24.02.2006 00:08:01 von Guido Ostkamp

Frank Seitz wrote:
> Doch, kann er. Das rufende Programm läuft SUID,
> nicht das gerufene Skript.

Du hast es offenbar nicht verstanden. Zuerst braucht er mal ein SUID
Programm, daß den LD_LIBRARY_PATH neu setzt und anschließend sein
Wunschprogramm aufruft - das Wunschprogramm ist ein Perl Skript.

Und das SUID-Programm, welches LD_LIBRARY_PATH neu aufsetzt - was Du
oben als Shell-Wrapper bezeichnet hast - kann nunmal nicht als Shell
Skript realisiert werden.

Die korrekte Vorgehensweise via C-Wrapper habe ich bereits ausführlich
anderswo in diesem Thread beschrieben, siehe nebenan.

Gruß,

Guido

Re: ENV-Variablen in Perl setzen

am 24.02.2006 08:58:06 von Frank Seitz

Guido Ostkamp wrote:
> Frank Seitz wrote:
>
>>Doch, kann er. Das rufende Programm läuft SUID,
>>nicht das gerufene Skript.
>
> Du hast es offenbar nicht verstanden. Zuerst braucht er mal ein SUID
> Programm, daß den LD_LIBRARY_PATH neu setzt und anschließend sein
> Wunschprogramm aufruft - das Wunschprogramm ist ein Perl Skript.

Ich glaube, die Verständnisprobleme liegen eher auf Deiner Seite.
Das SUID-Programm existiert bereits und kann vom OP nicht
modifiziert werden. Dieses ruft sein Perl Skript.

> Und das SUID-Programm, welches LD_LIBRARY_PATH neu aufsetzt - was Du
> oben als Shell-Wrapper bezeichnet hast - kann nunmal nicht als Shell
> Skript realisiert werden.

Mein Vorschlag war, ein Skript durch ein Skript zu ersetzen.
Allein daran hättest Du merken können, dass Dein Einwand (SUID-Bit wirkt
bei Skripten nicht), deplaziert ist. Elegant fand ich den
Vorschlag von Ingo Menger, das durch einen Selbstaufruf zu machen.

> Die korrekte Vorgehensweise via C-Wrapper habe ich bereits ausführlich
> anderswo in diesem Thread beschrieben, siehe nebenan.

Deinen Vorschlag fand ich auch interessant. Er passte nur nicht
zu dem Problem des OP (wie ich es verstanden habe).

Grüße
Frank
--
Dipl.-Inform. Frank Seitz; http://www.fseitz.de/
Tel: 04103/180301; Fax: -02; Industriestr. 31, 22880 Wedel

Re: ENV-Variablen in Perl setzen

am 24.02.2006 20:16:44 von Guido Ostkamp

Frank Seitz wrote:
> Ich glaube, die Verständnisprobleme liegen eher auf Deiner Seite.
> Das SUID-Programm existiert bereits und kann vom OP nicht
> modifiziert werden. Dieses ruft sein Perl Skript.

Ok, nehmen wir mal an, Deine Interpretation stimmt. Dann wird bereits
beim Start des SUID-Programms der LD_LIBRARY_PATH eliminiert. Das
heißt, das bereits vorher der Path in einer anderen Environment
Variable in Kopie abgelegt worden sein muß (ich gehe mal davon aus,
daß es sich um dynamischen Inhalt handelt), damit dieser überhaupt
vererbt wird und später genutzt werden kann.

Ein nun aufgerufener Wrapper, der LD_LIBRARY_PATH wieder setzt,
erfüllt nur seinen Zweck, wenn er in der Lage ist die UID so zu
verändern, so daß sowohl EUID als auch UID 0 sind - andernfalls wird
bei dem nun folgenden Aufruf des Perl Skriptes der LD_LIBRARY_PATH
erneut weggeworfen. Zu diesem Aspekt habe ich bisher z.B. bei Ingo
nichts gesehen.

Als Shell Lösung kommt also hier die bash etc. nicht in Frage, weil
sie das nicht beherrscht, die zsh schafft es allerdings.

So etwas klappt also bei mir:

/tmp/x.c (anstelle des Original-SUID Programms):
--- snip --- snap ---
#include
#include

int
main(void)
{
execl("/usr/bin/zsh", "zsh", "/tmp/x.sh", 0);
}
--- snip --- snap ---


/tmp/x.sh:
--- snip --- snap ---
#!/usr/bin/zsh

echo "UID = $UID, EUID = $EUID"
UID=0
echo "UID = $UID, EUID = $EUID"
export LD_LIBRARY_PATH=$MY_LD_LIBRARY_PATH
exec /tmp/x.pl
--- snip --- snap ---


/tmp/x.pl:
--- snip --- snap ---
#!/usr/bin/perl

print "LD_LIBRARY_PATH=" . $ENV{'LD_LIBRARY_PATH'} . "\n";
print "UID = " . $< . ", EUID = " . $> . "\n";
--- snip --- snap ---

mit

-rwsr-xr-x 1 root root 7036 Feb 24 19:42 x
-rwxr-xr-x 1 root users 144 Feb 24 19:49 x.sh
-rwxr-xr-x 1 root users 123 Feb 24 19:49 x.pl

liefert

$ export MY_LD_LIBRARY_PATH=blubber
$ /tmp/x
UID = 500, EUID = 0
UID = 0, EUID = 0
LD_LIBRARY_PATH=blubber
UID = 0, EUID = 0

Gruß,

Guido

Re: ENV-Variablen in Perl setzen

am 24.02.2006 22:14:40 von Frank Seitz

Guido Ostkamp wrote:

> Ok, nehmen wir mal an, Deine Interpretation stimmt. Dann wird bereits
> beim Start des SUID-Programms der LD_LIBRARY_PATH eliminiert. Das
> heißt, das bereits vorher der Path in einer anderen Environment
> Variable in Kopie abgelegt worden sein muß (ich gehe mal davon aus,
> daß es sich um dynamischen Inhalt handelt), damit dieser überhaupt
> vererbt wird und später genutzt werden kann.

Es sei denn, man setzt die Variable im gerufenen Programm auf
einen festen Wert. Das scheint im vorliegenden Fall zu reichen.

> Ein nun aufgerufener Wrapper, der LD_LIBRARY_PATH wieder setzt,
> erfüllt nur seinen Zweck, wenn er in der Lage ist die UID so zu
> verändern, so daß sowohl EUID als auch UID 0 sind - andernfalls wird
> bei dem nun folgenden Aufruf des Perl Skriptes der LD_LIBRARY_PATH
> erneut weggeworfen.

EUID und UID müssen nicht 0 sein. Sie können beliebig,
müssen aber identisch sein. Zumindest ist es unter Linux so.

> Zu diesem Aspekt habe ich bisher z.B. bei Ingo
> nichts gesehen.

Folgende Zeile genügt, um die Bedingung zu erfüllen:

$< = $>;

Grüße
Frank
--
Dipl.-Inform. Frank Seitz; http://www.fseitz.de/
Tel: 04103/180301; Fax: -02; Industriestr. 31, 22880 Wedel

Re: ENV-Variablen in Perl setzen

am 25.02.2006 00:25:56 von Guido Ostkamp

Frank Seitz wrote:
> Es sei denn, man setzt die Variable im gerufenen Programm auf
> einen festen Wert. Das scheint im vorliegenden Fall zu reichen.

Ich kann aus dem OP nicht herauslesen, ob der OP hardcoded Pfade
nur als Notlösung oder als regulären Weg wählen wollte.

> EUID und UID müssen nicht 0 sein. Sie können beliebig,
> müssen aber identisch sein. Zumindest ist es unter Linux so.

Richtig. Ich gehe aber davon aus, daß 0 gewünscht ist, denn sonst
könnte man sich den ganzen Kram mit der SUID Applikation sparen und
das Perl Skript auch direkt aufrufen (außer man will eine
komplett andere UID als vor dem SUID Programmaufruf annehmen, was
wiederum erst geht, wenn man vorher root war ;-)).

Gruß,

Guido

Re: ENV-Variablen in Perl setzen

am 25.02.2006 07:41:07 von Frank Seitz

Guido Ostkamp wrote:
> Frank Seitz wrote:
>
>>Es sei denn, man setzt die Variable im gerufenen Programm auf
>>einen festen Wert. Das scheint im vorliegenden Fall zu reichen.
>
> Ich kann aus dem OP nicht herauslesen, ob der OP hardcoded Pfade
> nur als Notlösung oder als regulären Weg wählen wollte.

Ihm bleibt nichts anderes übrig, wenn er über
das SUID-Programm keine Kontrolle hat.

>>EUID und UID müssen nicht 0 sein. Sie können beliebig,
>>müssen aber identisch sein. Zumindest ist es unter Linux so.
>
> Richtig. Ich gehe aber davon aus, daß 0 gewünscht ist, denn sonst
> könnte man sich den ganzen Kram mit der SUID Applikation sparen und
> das Perl Skript auch direkt aufrufen (außer man will eine
> komplett andere UID als vor dem SUID Programmaufruf annehmen, was
> wiederum erst geht, wenn man vorher root war ;-)).

Oh, da verkennst Du die Möglichkeiten des SUID-Bit.
Per SUID-Bit können die Zugriffsrechte eines x-beliebigen
Benutzers auf ein Programm transferiert werden. Der, der das
Bit setzt, muss das Recht dazu haben (muss Owner oder root sein),
das ist alles. Im vorliegenden Fall wäre es sogar fatal,
dem Skript Root-Rechte zu transferieren, da jemand anders als root
es schreiben darf. Damit wäre er dann selber root.

Grüße
Frank
--
Dipl.-Inform. Frank Seitz; http://www.fseitz.de/
Tel: 04103/180301; Fax: -02; Industriestr. 31, 22880 Wedel

Re: ENV-Variablen in Perl setzen

am 25.02.2006 14:40:52 von Guido Ostkamp

Frank Seitz wrote:
> Ihm bleibt nichts anderes übrig, wenn er über das SUID-Programm
> keine Kontrolle hat.

Der OP hat aber bisher nicht gesagt, daß er über den Aufruf des SUID
Programms keine Kontrolle hat bzw. den Admin nicht mit einer
entsprechenden Environment-Änderung beauftragen kann. Ggf.
reicht der Weg, den ich ausgeführt habe aus, um mittels
MY_LD_LIBRARY_PATH Variable das hinzubekommen.

> Oh, da verkennst Du die Möglichkeiten des SUID-Bit. Per SUID-Bit
> können die Zugriffsrechte eines x-beliebigen Benutzers auf ein
> Programm transferiert werden.

Ok, da hast Du Recht, Irrtum meinerseits.

> Im vorliegenden Fall wäre es sogar fatal, dem Skript Root-Rechte zu
> transferieren, da jemand anders als root es schreiben darf.

Wenn der OP ein Perl-Skript entwerfen soll, heißt das noch nicht, daß
das Skript zum Ausführungszeitpunkt noch für Normalnutzer schreibbar
abgelegt ist. Ergo ist es auch nicht zwangsläufig fatal, dem Skript
Root-Rechte zu transferieren.

Gruß,

Guido