hotti: use Shell qw(htpasswd)

hi,

s. Thema. Auf linux+co tut das einwandfrei, es geht so:

  
use Shell qw(htpasswd);  
htpasswd("-b $pwfile $user $password");  

und schwubs, ist für einen user das Passwort geändert. Das nun soll auch auf XP laufen und da haben wir das Problem: Das Programm "htpasswd" heißt hier "htpasswd.exe".

Was ich versucht habe:

htpasswd.exe ins /cgi-bin/ kopiert neben mein Script

1
use Shell qw(htpasswd.exe);
htpasswd("siehe oben");
=> $? wirft mir einen status 512 (no cigar)

2
use Shell qw(htpasswd.exe);
htpasswd.exe("siehe oben");

=> undefined subroutine main::exe blahh oder so ähnlich.

Weitere untaugliche Versuche folgten mit
use Shell qw(htpasswd) und einer Umbenennung der "htpasswd.exe" nach "htpasswd" und was weiß ich, was ich alles noch probiert habe, nix geht.

Hat jemand ne Idee?
Hotte

  1. Moin Moin!

    system("c:/path/to/htpasswd.exe","-b",$pwfile,$user,$password);

    Alexander

    --
    Today I will gladly share my knowledge and experience, for there are no sweeter words than "I told you so".
    1. Moin Moin!

      system("c:/path/to/htpasswd.exe","-b",$pwfile,$user,$password);

      Freilich, das geht. qx() geht auch ;-)

      use Shell qw(???);

      Evntl. werd ich mal testen:
      use Shell qw(htpasswd htpasswd.exe);

      und den Aufruf mit htpasswd("-b $file $user $pass");

      Viele Grüße,
      Hotte

      --
      Der Außenminister hat beschlossen, den Import von Elefanten zu verstärken. Damit der Zirkus in Deutschland weitergeht...
      1. Moin Moin!

        Moin Moin!

        system("c:/path/to/htpasswd.exe","-b",$pwfile,$user,$password);

        Freilich, das geht. qx() geht auch ;-)

        Der feine Unterschied zwischen qx(), ``, system $string und exec $string einerseits und system LIST und exec LIST andererseits ist der, dass die beiden Varianten mit LIST jedes Theater mit der notorisch problematischen Shell vermeiden, wärend die anderen Varianten (incl. use Shell) mit einer ziemlich primitiven Heuristik entscheiden, ob die Shell zum Parsen des Strings benötigt wird oder nicht:

        "If there is only one scalar argument or an array with one element in it, the argument is checked for shell metacharacters, and if there are any, the entire argument is passed to the system's command shell for parsing (this is /bin/sh -c on Unix platforms, but varies on other platforms). If there are no shell metacharacters in the argument, it is split into words and passed directly to execvp, which is more efficient."

        Das führt dazu, dass Du bei qx(), ``, system $string und exec $string die übergebenen Parameter quoten solltest (lies: "mußt"), während das bei system LIST und exec LIST nicht nötig ist.

        Das Quoting hängt natürlich von der Shell ab, die Perl aufruft. Unter Windows ist das entweder cmd.exe oder command.com, die sich in ihrem Verhalten schon unterscheiden. Wahlweise könnte jemand unter Win32 auch eine ganz andere Shell per $ENV{'PERL5SHELL'} gesetzt haben. Unter Unixen ist /bin/sh oft eine Bourne Shell, bei Linuxen sehr oft ein Symlink auf /bin/bash, manchmal aber auch auf /bin/ash oder /bin/dash. Perl für Cygwin nutzt das, was Cygwin als /bin/sh ins System mogelt, also in aller Regel auch eine Bash. Ich würde auch nicht darauf wetten, dass kein System eine C-Shell oder eine Korn-Shell als /bin/sh installiert hat. Mit anderen Worten: Das Verhalten von qx(), ``, system $string und exec $string ist EXTREM abhängig vom jeweiligen Betriebssystem und dessen Konfiguration. Selbst das Quoting ist unterschiedlich. Bourne und Bash interpolieren nicht, wenn man Single Quotes benutzt, die kritischen Zeichen kann man mit Backslashes escapen. C-Shell hab ich mir nie angesehen, Command.com und CMD.EXE sind deutlich anders, die Quoting-Regeln füllen einige Seiten und sind mehr standardisierte Fehler als sinnvolle Regeln.

        Um überhaupt sicher quoten zu können, müßtest Du also sehr intensiv zur Laufzeit nachforschen, mit welcher Shell Du Dich herumschlagen mußt.

        Bei den LIST-Varianten ist das Problem nicht existent, weil die Abhängigkeit von der Shell entfällt.

        use Shell qw(???);

        Evntl. werd ich mal testen:
        use Shell qw(htpasswd htpasswd.exe);

        htpasswd.exe ist kein güliger Name für eine Funktion in Perl. Das Shell-Modul kann keine Aliase vergeben, Du mußt Dich darauf verlassen, dass die jeweilige Shell das passende Programm findet.

        und den Aufruf mit htpasswd("-b $file $user $pass");

        Darf ich $user oder $pass bestimmen, z.B. per Web-Interface?

        Dann setze ich $user und/oder $pass auf "x ; /bin/rm -rf / ; /bin/true", wahlweise auf "x ; format c: /u ; rem", "x | format c: /u | rem ", "x && format c: /u && rem", "x > c:\boot.ini ; rem", "x > c:\ntldr ; rem" oder ähnliche Garstigkeiten.

        Alle diese Werte machen Dir ohne PASSENDES Quoting mit qx(), ``, system $string und exec $string richtig Ärger, während sie für system LIST und exec LIST (also: system('c:/apache/bin/htpasswd.exe','-b',$file,$user,$pass) bzw. system('/opt/apache/bin/htpasswd','-b',$file,$user,$pass)) überhaupt kein Problem sind.

        http://xkcd.com/327/

        Alexander

        --
        Today I will gladly share my knowledge and experience, for there are no sweeter words than "I told you so".