Скрипт для смены пароля FTP - PullRequest
1 голос
/ 25 июня 2010

У меня есть следующий скрипт для обновления одного из моих паролей FTP каждые 15 дней через cronjob и по электронной почте соответствующим людям после того, как была предпринята попытка.Случайно произойдет сбой, и поэтому я буду запускать его снова вручную, и он будет работать.Кажется, я не могу понять, в чем дело.

Скрипт подключается к локальной базе данных mysql, получает логин и пароль для учетной записи и затем меняет этот пароль на FTP.Все успешно вплоть до смены пароля.Опять же, это случайно, иногда это работает, иногда это не так.

Спасибо!

#!/usr/bin/perl -w
#

use DBI;
use Net::FTP;

our $dbh = DBI->connect('DBI:mysql:database:127.0.0.1','user','password') or die "Aargh $!\n";
$transquery=q{SELECT dest_login,dest_password FROM list where id=123};
$sth=$dbh->prepare($transquery);
$sth->execute();
while($co=$sth->fetchrow_hashref){
  $login=$co->{'dest_login'};
  $pass=$co->{'dest_password'};
}

$changeresult='FAIL';
$actionlog='';
$newstring='';
$upperchars='ABCDEFGHIJKLMNOPQRSTUVWXYZ';
$lowerchars='abcdefghijklmnopqrstuvwxyz';
$allowedchars='ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789@#$';
$l=length($upperchars);
  $newstring.=substr($upperchars,int(rand($l)),1);
  $newstring.=substr($lowerchars,int(rand($l)),1);
$l=length($allowedchars);
for ($i=0;$i<6;$i++){
  $newstring.=substr($allowedchars,int(rand($l)),1);
}
print "$newstring\n";
$actionlog .= "Setting Password for $login from $pass to $newstring\n";
$username=
eval{
    $ftp=Net::FTP->new('x.x.x.x',Timeout=>480,Debug=>1) or die "Error connecting FTP $!\n";
    $changepassword="$pass/$newstring/$newstring";
    $ftp->login($login,$changepassword) or die "Error changing password $!\n";
    #If we are here, time to update the password
    $changeresult='SUCCESS';
    $actionlog .= "Password successfully updated\n";
    $transquery=q{UPDATE list set dest_password=(?) where id=123};
    $sth=$dbh->prepare($transquery);
    $sth->execute($newstring);
  };

  if ($@) {
    $actionlog = $actionlog . "$@\n";
  };
if($actionlog ne ""){
  #print $actionlog;

  #my $send_to  = "To: someone\@example.com\n";
  my $send_to  = "To: databaseusers\@example.com\n";
  my $sendmail = "/usr/sbin/sendmail -t";

  open(SENDMAIL, "|$sendmail") or die "Cannot open $sendmail: $!";
  print SENDMAIL "Reply-to: databasepassword\@example.com\n";
  print SENDMAIL "Subject: Password Change Information [$changeresult]\n";
  print SENDMAIL $send_to;
  print SENDMAIL "Content-type: text/plain\n\n";
  print SENDMAIL $send_to;
  print SENDMAIL "Content-type: text/plain\n\n";
  print SENDMAIL $actionlog;
  close(SENDMAIL);
  $actionlog='';
}
else{
  #print "Nothing done this session\n";

1 Ответ

1 голос
/ 25 июня 2010

USUW может вам что-то сказать. (use strict; use warnings;)

Что-нибудь печатает?

В начале вы не выполняете большую проверку ошибок в части DBI, возможно, вы получаете ошибку соединения. В блоках AIX возникала проблема с получением клиентского порта, который система не была уверена в том, использовался он или нет. Когда это произойдет, он просто не сможет подключиться к базе данных.

Я наконец-то исправил эту проблему для наших скриптов, изучив $OS_ERROR (он же $!) для этого конкретного кода (Errno::EADDRINUSE), а затем подождал и повторил попытку с экспоненциальным спадом (подождите 2 секунды, затем 4, тогда 8 ...).

Если ваш сценарий «по какой-то причине умирает», то важно, чтобы сценарий сообщил вам эту причину. Я бы изучил тему сообщений об ошибках в различных модулях, которые вы используете.

Например, Net::FTP позволяет пропустить переключатель Debug => 1, и тогда вы увидите весь разговор.

И я знаю, что с DBI есть намного больше, где вы можете получать сообщения об ошибках.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...