|
うーん、むずかしい…。全然理解してないことがよくわかった。 すごく汚くて変な書き方ですがこんな感じ。 use Net::Telnet; $username='yourname'; $oldpasswd='secret1'; $newpasswd='secret2'; $t = new Net::Telnet (Timeout => 5, Prompt => '/\w*? /', Dump_Log => 'telnet-log'); $t->open("localhost"); $t->login($username, $oldpasswd); $t->prompt('/Old password:/'); $t->cmd("/usr/bin/passwd"); $t->print("$oldpasswd\n"); ($prematch,$match) = $t->waitfor('/[a-zA-Z ]+:/'); print "[$prematch] [$match]\n"; $t->print("$newpasswd\n"); ($prematch,$match) = $t->waitfor('/[a-zA-Z ]+:/'); print "[$prematch] [$match]\n"; $t->print("$newpasswd\n"); ($prematch,$match) = $t->waitfor('/[a-zA-Z ]+:/'); print "[$prematch] [$match]\n"; $t->close(); 適当に $match の結果に応じて、パスワードが違うやら、 新しいパスワードが短いやら出力すればいいのかな。 expect の方がすっきり書けるような気も。 |
|
やっぱ僕がやるとしたら pw コマンドの wrapper 作って、 それを root に suid するなぁ。passwd の挙動を 全て把握するのは厳しい。 |
|
結局、68userさんのおっしゃる通りpasswdの挙動を全て把握するのは 厳しいので、telnetされる側のServerにID,Passwordを変数として受け 取って、passwdファイルを直接編集するperlを置き、それをCGI(Perl) からtelnetして、rootで実行させるようにしました。 結局何故expectで動作しないのかは不明なままですが、要求を満たす 物は出来ました。 アドバイスありがとうございました。 |
|
私の場合、次のような感じのスクリプトで動きます。 一応、ログインしてコマンド実行程度なら、大丈夫のようです。 環境は perl 5.00503 + Expect-1.08 + FreeBSD 4.2-BETA です。 #!/usr/bin/perl use Expect; my $user = 'rose'; my $password = 'password'; my $prompt = 'host\{rose\}\d+\s'; my @cmdlist = ( 'ls -alF', 'ps -auxw', 'exit', ); my $telnet = Expect->spawn("telnet localhost"); $telnet->expect(30,"login: ") || die "NO login prompt"; print $telnet "$user\r"; $telnet->expect(30,"assword:") || die "NO password prompt"; print $telnet "$password\r"; my $match = $telnet->expect( 30, "closed by foreign host", "-re", $prompt ); die "refused by server\n" if $match == 1; die "NO shell prompt, ".$telnet->exp_error()."\n" unless $match; foreach $cmd ( @cmdlist ) { print $telnet "$cmd\r"; my $match = $telnet->expect( 30, "closed by foreign host", "-re", $prompt ); last if $match == 1; die "NO prompt after command\n" if $telnet->exp_error(); } $telnet->hard_close(); exit; |