fauxxami
Anmeldungsdatum: 7. Januar 2012
Beiträge: 493
|
Hallo zusammen, ich bastele gerade an einem Shellscript, das Samba-Passwörter ändern soll. Ich glaube, fast am Ziel zu sein, aber eben leider nur fast. Die Zeile | echo -e 'hahaha!\nhahaha!' | sudo smbpasswd -s fritz
|
setzt das Passwort für den Benutzer "fritz" erwartungsgemäß; der Benutzer "www-data" darf "smbpasswd" mittels "sudo" aufrufen. Diese Zeile soll nun zu guter Letzt in ein PHP-Script eingebaut werden. Dazu möchte ich den o.g. Befehl zunächst mal in einen String packen: | $befehl = "echo -e 'hahaha!\nhahaha!' | sudo smbpasswd -s fritz";
|
funktioniert aber leider nicht, was vermutlich von den einfachen Anführungszeichen rund um das neue Passwort verursacht wird. Die aber brauche ich unbedingt für den Fall wie oben, dass das Passwort ein Sonderzeichen enthält. Dann habe ich die Variante | $befehl = "echo -e \'hahaha!\nhahaha!\' | sudo smbpasswd -s fritz";
|
probiert, aber die scheint es auch nicht zu sein. Kann mir freundliche Weise jemand sagen, wie ich das korrekt verpacke? Danke und Gruß, Jürgen
|
rklm
Projektleitung
Anmeldungsdatum: 16. Oktober 2011
Beiträge: 13174
|
fauxxami schrieb:
Kann mir freundliche Weise jemand sagen, wie ich das korrekt verpacke?
Disclaimer: Ich habe praktisch keine Erfahrung mit PHP. ☺ Ich habe mal eben in die PHP Doku zum Thema "externe Prozesse" geschaut und es scheint da keine Funktion zu geben, der man die Kommandozeile als Array übergibt (anstatt eines Strings). Das hätte die Sache deutlich einfacher gemacht. Du wirst wohl oder übel Deinen String so zusammen bauen müssen, dass er sicher ist. Vermutlich musst Du auf jeden Fall die Backslashes escapen: | $befehl = "echo -e 'hahaha!\\nhahaha!' | sudo smbpasswd -s fritz";
|
Wenn Du dann noch Passwörter hinein montieren willst, brauchst Du vermutlich escapeshellarg(). Vielleicht so: | $new_pwd = "hahaha!";
$new_pwd_esc = escapeshellarg(new_pwd);
$befehl = "echo -e " . $new_pwd_esc . "\\n" . $new_pwd_esc . " | sudo smbpasswd -s fritz";
|
Ciao robert
|
fauxxami
(Themenstarter)
Anmeldungsdatum: 7. Januar 2012
Beiträge: 493
|
Hi! Danke für deine Antwort:
Du wirst wohl oder übel Deinen String so zusammen bauen müssen, dass er sicher ist. Vermutlich musst Du auf jeden Fall die Backslashes escapen:
Ja, und genau das ist mein Problem: die Backslashes und die einfachen/doppelten Anführungszeichen. Ich blicke da nicht wirklich durch.
Wenn Du dann noch Passwörter hinein montieren willst, brauchst Du vermutlich escapeshellarg().
Das schaue ich mir mal an. Vielen Dank und Gruß, Jürgen
|
fauxxami
(Themenstarter)
Anmeldungsdatum: 7. Januar 2012
Beiträge: 493
|
Guten Morgen! Ich habe jetzt mal mit drei Varianten herumprobiert: diese PHP-Zeilen | $befehl = "echo -e 'hahaha!\\nhahaha!' | sudo smbpasswd -s fritz";
echo "<p>" . $befehl . "</p>";
echo "<p>" . escapeshellarg($befehl) . "</p>";
echo "<p>" . escapeshellcmd($befehl) . "</p>";
|
erzeugen im Browser folgenden Ausgaben: echo -e 'hahaha!\nhahaha!' | sudo smbpasswd -s fritz
'echo -e '\''hahaha!\nhahaha!'\'' | sudo smbpasswd -s fritz'
echo -e 'hahaha!\\nhahaha!' \| sudo smbpasswd -s fritz Die erste Ausgabe ist genau die, die ich auch bei manueller Ausführung an der Konsole eingeben würde. Darf ich also davon ausgehen, dass das auch die Variante ist, die in mein Script gehört? Also mit maskiertem Backslash und einfachen Anführungszeichen als Bestandteil des PHP-Strings? Die zusätzlichen Maskierungen, die escapeshellarg bzw. escapeshellcmd hinzufügen, erscheinen mir unnötig bzw. sogar vielleicht störend zu sein. Wie seht ihr das? Viele Grüße, Jürgen
|
rklm
Projektleitung
Anmeldungsdatum: 16. Oktober 2011
Beiträge: 13174
|
fauxxami schrieb:
Die erste Ausgabe ist genau die, die ich auch bei manueller Ausführung an der Konsole eingeben würde. Darf ich also davon ausgehen, dass das auch die Variante ist, die in mein Script gehört?
Probier es doch einfach aus. Du musst ja nicht smbpasswd nehmen, sondern kannst z.B. od -t x1c stattdessen einsetzen. Dann packst Du die Ausgabe in einen <pre> Block und kannst Dir in Ruhe das Hexdump anschauen. Daran kannst Du dann erkennen, ob genau das gesendet wurde, was Du erwartet hast. M.E. müsste so etwas dabei herauskommen: $ echo -e 'hahaha!\nhahaha!' | od -t x1c
0000000 68 61 68 61 68 61 21 0a 68 61 68 61 68 61 21 0a
h a h a h a ! \n h a h a h a ! \n
0000020 Also mit maskiertem Backslash und einfachen Anführungszeichen als Bestandteil des PHP-Strings? Die zusätzlichen Maskierungen, die escapeshellarg bzw. escapeshellcmd hinzufügen, erscheinen mir unnötig bzw. sogar vielleicht störend zu sein. Wie seht ihr das?
Ich denke escapeshellarg solltest Du nur auf ein einzelnes Argument anwenden, so wie ich es vorher gezeigt habe. escapeshellcmd ist hier wohl nicht angebracht (siehe Doku). Ciao robert
|
fauxxami
(Themenstarter)
Anmeldungsdatum: 7. Januar 2012
Beiträge: 493
|
Danke nochmal für die ausführliche Hilfe - meine erste Variante funktioniert. Prima! Grüße von Jürgen
|
rklm
Projektleitung
Anmeldungsdatum: 16. Oktober 2011
Beiträge: 13174
|
fauxxami schrieb: Danke nochmal für die ausführliche Hilfe - meine erste Variante funktioniert. Prima!
Bitte! Wenn mann bedenkt, dass ich nicht PHP programmiere, hat das ja super geklappt. 😬
|
fauxxami
(Themenstarter)
Anmeldungsdatum: 7. Januar 2012
Beiträge: 493
|
Guten Morgen!
Bitte! Wenn mann bedenkt, dass ich nicht PHP programmiere, hat das ja super geklappt. 😬
Um der Wahrheit die Ehre zu geben (und weil es vielleicht andere hier auch noch interessiert, wie es geht): ich hatte zu früh losgejubelt, weil die ge-echo-te Ausgabe genau das zeigte, was ich sehen wollte. Aber als ich das dann im Zusammenhang mit smbpasswd auch einsetzen wollte, klappte es immer noch nicht. Es hat mich sehr lange gekostet, es nun doch noch hinzukriegen: ich habe smbpasswd den Parameter -D10 (höchstes Debug-Level) mitgegeben und dann meinen Befehl mit system() abgesetzt. Die Ausgabe zeigte, dass smbpasswd permanent der Meinung war, dass die beiden Passwörter nicht übereinstimmten. Dann bin auf die Idee gekommen, dem echo-Befehl den Parameter -e zu klauen ("enable interpretation of backslash escapes"), und dann ging es mit dieser Anweisung: | $befehl = "echo -n '" . $pw . "\n" . $pw . "' | sudo smbpasswd -s fritz";
system($befehl, $retvalue);
|
Uff, das hat mich wirklich Stunden gekostet. Trotzdem noch mal vielen Dank für deine Hilfe; die Idee mit der Ausgabe dessen, was da gesendet wird, war Gold wert.
|
rklm
Projektleitung
Anmeldungsdatum: 16. Oktober 2011
Beiträge: 13174
|
fauxxami schrieb:
Dann bin auf die Idee gekommen, dem echo-Befehl den Parameter -e zu klauen ("enable interpretation of backslash escapes"), und dann ging es mit dieser Anweisung:
Genau deshalb hatte ich ja in meinem Beispiel zwei Backslashes. Vielleicht brauchst Du an der Stelle vier Backslashes (also "\\\\n"): die erste "Ebene" von Escaping macht PHP, so dass danach "\\n" übrig ist, was dann die Shell zu "\n" macht, das dann wiederum von echo korrekt interpretiert werden kann. Allerdings hast Du das ja in einem einfach gequoteten String und da wird in der Shell aus "\\n" "\\n". Hm...
Uff, das hat mich wirklich Stunden gekostet. Trotzdem noch mal vielen Dank für deine Hilfe; die Idee mit der Ausgabe dessen, was da gesendet wird, war Gold wert.
Fein!
|